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,305 @@
1
+ """Types for the backend artifact-storage API.
2
+
3
+ Port of `atomicmemory-sdk/src/storage/types.ts`. Python callers use
4
+ snake_case field names while Pydantic aliases accept the TypeScript
5
+ SDK's camelCase spellings at the public boundary.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any, Literal
11
+ from urllib.parse import urlparse
12
+
13
+ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
14
+
15
+ StorageArtifactStatus = Literal[
16
+ "stored",
17
+ "pending",
18
+ "available",
19
+ "unavailable",
20
+ "deleting",
21
+ "deleted",
22
+ "delete_failed",
23
+ "failed",
24
+ ]
25
+ StorageAddressingMode = Literal["location", "content", "provider_native"]
26
+ StorageConsistency = Literal["immediate", "eventual"]
27
+ StorageAvailabilityModel = Literal["immediate", "delayed", "scheduled", "best_effort"]
28
+ StorageDeleteSemantics = Literal["delete", "unpin", "tombstone", "provider_retained"]
29
+ StorageMode = Literal["pointer", "managed"]
30
+ ContentEncoding = Literal["identity", "aes_gcm"]
31
+ DeleteArtifactPolicy = Literal["artifact_only", "with_documents"]
32
+ ArtifactMetadata = dict[str, str | int | float | bool]
33
+ ManagedBody = bytes | bytearray | memoryview
34
+
35
+
36
+ class StorageClientConfig(BaseModel):
37
+ """Configuration for sync and async storage clients."""
38
+
39
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
40
+
41
+ api_url: str = Field(alias="apiUrl")
42
+ api_key: str = Field(alias="apiKey")
43
+ user_id: str = Field(alias="userId")
44
+ timeout_seconds: float = Field(default=30.0, alias="timeoutSeconds")
45
+
46
+ @field_validator("api_url")
47
+ @classmethod
48
+ def _validate_api_url(cls, value: str) -> str:
49
+ stripped = value.strip()
50
+ parsed = urlparse(stripped)
51
+ if parsed.scheme not in {"http", "https"} or not parsed.netloc:
52
+ raise ValueError("api_url must be an http(s) URL")
53
+ return stripped
54
+
55
+ @field_validator("api_key", "user_id")
56
+ @classmethod
57
+ def _validate_non_empty_secret(cls, value: str) -> str:
58
+ stripped = value.strip()
59
+ if stripped == "":
60
+ raise ValueError("value must not be empty")
61
+ return stripped
62
+
63
+ @field_validator("timeout_seconds")
64
+ @classmethod
65
+ def _validate_timeout(cls, value: float) -> float:
66
+ if value <= 0:
67
+ raise ValueError("timeout_seconds must be greater than zero")
68
+ return value
69
+
70
+ @model_validator(mode="after")
71
+ def _require_non_empty(self) -> StorageClientConfig:
72
+ if not self.api_url:
73
+ raise ValueError("api_url is required")
74
+ if not self.api_key:
75
+ raise ValueError("api_key is required")
76
+ if not self.user_id:
77
+ raise ValueError("user_id is required")
78
+ return self
79
+
80
+
81
+ class ArtifactRef(BaseModel):
82
+ """Stable reference to a storage artifact.
83
+
84
+ At least one identifier is required. v1 follow-up operations use
85
+ ``artifact_id`` as the canonical handle.
86
+ """
87
+
88
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
89
+
90
+ artifact_id: str | None = Field(default=None, alias="artifactId")
91
+ uri: str | None = None
92
+ content_hash: str | None = Field(default=None, alias="contentHash")
93
+
94
+ @model_validator(mode="after")
95
+ def _require_one_identifier(self) -> ArtifactRef:
96
+ if self.artifact_id is None and self.uri is None and self.content_hash is None:
97
+ raise ValueError("ArtifactRef requires artifact_id, uri, or content_hash")
98
+ return self
99
+
100
+
101
+ class StorageLifecycle(BaseModel):
102
+ """Provider-agnostic availability and delete-semantics summary."""
103
+
104
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
105
+
106
+ availability: StorageAvailabilityModel | None = None
107
+ delete_semantics: StorageDeleteSemantics | None = Field(default=None, alias="deleteSemantics")
108
+
109
+
110
+ class ReplicationState(BaseModel):
111
+ """Optional replication state for backends such as Filecoin."""
112
+
113
+ model_config = ConfigDict(extra="ignore", populate_by_name=True)
114
+
115
+ desired_copies: int | None = Field(default=None, alias="desiredCopies")
116
+ confirmed_copies: int | None = Field(default=None, alias="confirmedCopies")
117
+
118
+
119
+ class VerificationState(BaseModel):
120
+ """Optional provider-proof or content-verification state."""
121
+
122
+ model_config = ConfigDict(extra="ignore", populate_by_name=True)
123
+
124
+ provider_proof_status: Literal["pending", "verified", "failed", "unsupported"] | None = Field(
125
+ default=None,
126
+ alias="providerProofStatus",
127
+ )
128
+ last_verified_at: str | None = Field(default=None, alias="lastVerifiedAt")
129
+
130
+
131
+ class RetrievalState(BaseModel):
132
+ """Optional retrieval-readiness state."""
133
+
134
+ model_config = ConfigDict(extra="ignore", populate_by_name=True)
135
+
136
+ status: Literal["not_checked", "retrievable", "not_retrievable", "unsupported"] | None = None
137
+ last_checked_at: str | None = Field(default=None, alias="lastCheckedAt")
138
+
139
+
140
+ class StoredArtifact(BaseModel):
141
+ """Artifact metadata returned by ``storage.put`` and ``storage.get``."""
142
+
143
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
144
+
145
+ artifact_id: str = Field(alias="artifactId")
146
+ provider: str
147
+ mode: StorageMode
148
+ uri: str | None
149
+ status: StorageArtifactStatus
150
+ size_bytes: int | None = Field(alias="sizeBytes")
151
+ content_type: str | None = Field(alias="contentType")
152
+ content_hash: str | None = Field(default=None, alias="contentHash")
153
+ content_encoding: ContentEncoding = Field(alias="contentEncoding")
154
+ identifiers: dict[str, str] = Field(default_factory=dict)
155
+ lifecycle: StorageLifecycle = Field(default_factory=StorageLifecycle)
156
+ replication: ReplicationState | None = None
157
+ verification: VerificationState | None = None
158
+ retrieval: RetrievalState | None = None
159
+ provider_details: dict[str, Any] | None = Field(default=None, alias="providerDetails")
160
+ metadata: ArtifactMetadata = Field(default_factory=dict)
161
+ created_at: str = Field(alias="createdAt")
162
+ updated_at: str = Field(alias="updatedAt")
163
+
164
+
165
+ class ArtifactRange(BaseModel):
166
+ """Byte range for future range-read capable storage backends."""
167
+
168
+ model_config = ConfigDict(extra="forbid")
169
+
170
+ start: int
171
+ end: int
172
+
173
+ @model_validator(mode="after")
174
+ def _validate_range(self) -> ArtifactRange:
175
+ if self.start < 0:
176
+ raise ValueError("start must be non-negative")
177
+ if self.end < self.start:
178
+ raise ValueError("end must be greater than or equal to start")
179
+ return self
180
+
181
+
182
+ class PutPointerInput(BaseModel):
183
+ """Pointer-mode put input. The server stores metadata only."""
184
+
185
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
186
+
187
+ mode: Literal["pointer"] = "pointer"
188
+ uri: str
189
+ content_type: str = Field(alias="contentType")
190
+ size_bytes: int | None = Field(default=None, alias="sizeBytes")
191
+ content_hash: str | None = Field(default=None, alias="contentHash")
192
+ metadata: ArtifactMetadata | None = None
193
+
194
+ @field_validator("content_type")
195
+ @classmethod
196
+ def _validate_content_type(cls, value: str) -> str:
197
+ stripped = value.strip()
198
+ if stripped == "":
199
+ raise ValueError("content_type must not be empty")
200
+ return stripped
201
+
202
+
203
+ class PutManagedInput(BaseModel):
204
+ """Managed-mode put input for known-length byte bodies."""
205
+
206
+ model_config = ConfigDict(extra="forbid", populate_by_name=True, arbitrary_types_allowed=True)
207
+
208
+ mode: Literal["managed"] = "managed"
209
+ body: ManagedBody
210
+ content_type: str = Field(alias="contentType")
211
+ disclose_content_hash: bool = Field(default=False, alias="discloseContentHash")
212
+ metadata: ArtifactMetadata | None = None
213
+
214
+ @field_validator("body", mode="before")
215
+ @classmethod
216
+ def _validate_body(cls, value: Any) -> Any:
217
+ if isinstance(value, bytes | bytearray | memoryview):
218
+ return value
219
+ raise ValueError("body must be bytes, bytearray, or memoryview")
220
+
221
+ @field_validator("content_type")
222
+ @classmethod
223
+ def _validate_content_type(cls, value: str) -> str:
224
+ stripped = value.strip()
225
+ if stripped == "":
226
+ raise ValueError("content_type must not be empty")
227
+ return stripped
228
+
229
+
230
+ PutArtifactInput = PutPointerInput | PutManagedInput
231
+
232
+
233
+ class ArtifactHead(BaseModel):
234
+ """Metadata projection returned by ``storage.head``."""
235
+
236
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
237
+
238
+ artifact_id: str = Field(alias="artifactId")
239
+ provider: str
240
+ mode: StorageMode
241
+ status: StorageArtifactStatus
242
+ size_bytes: int | None = Field(alias="sizeBytes")
243
+ content_type: str | None = Field(alias="contentType")
244
+
245
+
246
+ class DeleteArtifactOptions(BaseModel):
247
+ """Options for ``storage.delete``."""
248
+
249
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
250
+
251
+ policy: DeleteArtifactPolicy | None = None
252
+
253
+
254
+ class DeleteArtifactResult(BaseModel):
255
+ """Result returned by ``storage.delete``."""
256
+
257
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
258
+
259
+ artifact_id: str = Field(alias="artifactId")
260
+ status: StorageArtifactStatus
261
+ cascaded_document_ids: list[str] | None = Field(default=None, alias="cascadedDocumentIds")
262
+
263
+
264
+ class VerifyArtifactOptions(BaseModel):
265
+ """Reserved verification options for future storage backends."""
266
+
267
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
268
+
269
+ mode: Literal["head_only", "hash_verify"] | None = None
270
+
271
+
272
+ class VerificationResult(BaseModel):
273
+ """Provider verification result."""
274
+
275
+ model_config = ConfigDict(extra="forbid")
276
+
277
+ kind: Literal["verified", "failed", "unsupported"]
278
+ details: dict[str, Any] | None = None
279
+ reason: str | None = None
280
+
281
+
282
+ class StorageCapabilities(BaseModel):
283
+ """Direct storage API capability snapshot."""
284
+
285
+ model_config = ConfigDict(extra="forbid", populate_by_name=True)
286
+
287
+ provider: str
288
+ addressing: list[StorageAddressingMode]
289
+ consistency: StorageConsistency
290
+ max_upload_bytes: int | None = Field(default=None, alias="maxUploadBytes")
291
+ min_upload_bytes: int | None = Field(default=None, alias="minUploadBytes")
292
+ supports_direct_upload: bool = Field(alias="supportsDirectUpload")
293
+ supports_range_read: bool = Field(alias="supportsRangeRead")
294
+ supports_delete: bool = Field(alias="supportsDelete")
295
+ supports_tombstone: bool = Field(alias="supportsTombstone")
296
+ supports_bundles: bool = Field(alias="supportsBundles")
297
+ supported_bundle_formats: list[str] = Field(alias="supportedBundleFormats")
298
+ supports_verification: bool = Field(alias="supportsVerification")
299
+ supports_provider_proofs: bool = Field(alias="supportsProviderProofs")
300
+ supports_replication: bool = Field(alias="supportsReplication")
301
+ supports_retrieval_status: bool = Field(alias="supportsRetrievalStatus")
302
+ supports_content_hash: bool = Field(alias="supportsContentHash")
303
+ supports_content_addressed_uri: bool = Field(alias="supportsContentAddressedUri")
304
+ delete_semantics: list[StorageDeleteSemantics] = Field(alias="deleteSemantics")
305
+ availability_model: StorageAvailabilityModel = Field(alias="availabilityModel")
@@ -0,0 +1,5 @@
1
+ """Misc utility helpers shared across the SDK."""
2
+
3
+ from atomicmemory.utils.environment import is_test_environment
4
+
5
+ __all__ = ["is_test_environment"]
@@ -0,0 +1,23 @@
1
+ """Environment introspection helpers.
2
+
3
+ Port of `atomicmemory-sdk/src/utils/environment.ts`. Used internally to
4
+ gate noisy diagnostics and skip optional behavior in tests.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ import sys
11
+
12
+
13
+ def is_test_environment() -> bool:
14
+ """Return True when the SDK is running under pytest or `PYTEST_*`.
15
+
16
+ The check is deliberately heuristic — it asks "is pytest the entry
17
+ point" by inspecting `sys.modules` and `os.environ`. Callers must not
18
+ use this for security-sensitive branches; it exists only to silence
19
+ diagnostics that would otherwise spam test output.
20
+ """
21
+ if "pytest" in sys.modules:
22
+ return True
23
+ return "PYTEST_CURRENT_TEST" in os.environ
@@ -0,0 +1,146 @@
1
+ Metadata-Version: 2.4
2
+ Name: atomicmemory
3
+ Version: 1.0.0
4
+ Summary: Python client SDK for AtomicMemory memory and artifact storage.
5
+ Project-URL: Homepage, https://github.com/atomicstrata/atomicmemory-python
6
+ Project-URL: Repository, https://github.com/atomicstrata/atomicmemory-python
7
+ Project-URL: Issues, https://github.com/atomicstrata/atomicmemory-python/issues
8
+ Author: AtomicMemory
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent,atomicmemory,llm,mem0,memory,rag
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: httpx>=0.27
25
+ Requires-Dist: numpy>=1.26
26
+ Requires-Dist: pydantic>=2.7
27
+ Provides-Extra: dev
28
+ Requires-Dist: mypy>=1.10; extra == 'dev'
29
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
30
+ Requires-Dist: pytest-mock>=3.12; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0; extra == 'dev'
32
+ Requires-Dist: respx>=0.21; extra == 'dev'
33
+ Requires-Dist: ruff>=0.6; extra == 'dev'
34
+ Requires-Dist: vulture>=2.11; extra == 'dev'
35
+ Provides-Extra: embeddings
36
+ Requires-Dist: sentence-transformers>=3.0; extra == 'embeddings'
37
+ Description-Content-Type: text/markdown
38
+
39
+ # atomicmemory-python
40
+
41
+ Python client SDK for [AtomicMemory](https://github.com/atomicstrata) memory and artifact storage.
42
+
43
+ A backend-agnostic memory and storage client: ingest conversations and documents, search them semantically, package retrieval-ready context, register or upload raw artifacts, and access AtomicMemory-specific features (lifecycle, audit, lessons, agents/trust, runtime config) through typed namespace handles.
44
+
45
+ This is a Python port of the TypeScript [`atomicmemory-sdk`](https://github.com/atomicstrata/atomicmemory-sdk). It mirrors the public surface 1:1 while staying idiomatic to Python (Pydantic models, `httpx` sync + async clients, `match` statements, `snake_case`).
46
+
47
+ ## Status
48
+
49
+ Stable release — `1.0.0` on [PyPI](https://pypi.org/project/atomicmemory/).
50
+
51
+ ## Quick start
52
+
53
+ ```python
54
+ from atomicmemory import AtomicMemoryClient
55
+
56
+ with AtomicMemoryClient({
57
+ "apiUrl": "http://localhost:3050",
58
+ "apiKey": "server-api-key",
59
+ "userId": "demo",
60
+ }) as client:
61
+ client.memory.initialize()
62
+
63
+ client.memory.ingest({
64
+ "mode": "messages",
65
+ "messages": [
66
+ {"role": "user", "content": "I prefer aisle seats on flights."},
67
+ ],
68
+ "scope": {"user": "demo"},
69
+ })
70
+
71
+ page = client.memory.search({"query": "seat preference", "scope": {"user": "demo"}})
72
+ for hit in page.results:
73
+ print(hit.memory.content, hit.score)
74
+
75
+ artifact = client.storage.put({
76
+ "mode": "pointer",
77
+ "uri": "https://example.com/manual.pdf",
78
+ "contentType": "application/pdf",
79
+ })
80
+ print(artifact.artifact_id)
81
+ ```
82
+
83
+ ## Async usage
84
+
85
+ ```python
86
+ import asyncio
87
+ from atomicmemory import AsyncAtomicMemoryClient
88
+
89
+ async def main() -> None:
90
+ async with AsyncAtomicMemoryClient({
91
+ "apiUrl": "http://localhost:3050",
92
+ "apiKey": "server-api-key",
93
+ "userId": "demo",
94
+ }) as client:
95
+ await client.memory.initialize()
96
+ results = await client.memory.search({"query": "seat preference", "scope": {"user": "demo"}})
97
+ for hit in results.results:
98
+ print(hit.memory.content)
99
+
100
+ asyncio.run(main())
101
+ ```
102
+
103
+ ## AtomicMemory-specific features
104
+
105
+ When configured with the `atomicmemory` provider, the client exposes a typed handle for backend-specific routes:
106
+
107
+ ```python
108
+ trail = client.memory.atomicmemory.audit.trail(memory_id="mem-123", user_id="demo")
109
+ health = client.memory.atomicmemory.config.health()
110
+ ```
111
+
112
+ Categories: `lifecycle`, `audit`, `lessons`, `config`, `agents`.
113
+
114
+ ## Artifact storage
115
+
116
+ The `client.storage` namespace mirrors the TypeScript SDK's direct storage API:
117
+
118
+ - `capabilities()` reports active backend support.
119
+ - `put({"mode": "pointer", ...})` registers a pointer to caller-owned bytes.
120
+ - `put({"mode": "managed", "body": b"...", ...})` uploads known-length bytes to the configured raw content store.
121
+ - `get`, `get_content`, `head`, `delete`, and `verify` address artifacts by `artifact_id`.
122
+ - `stream_content` streams large artifact bodies without buffering the entire response in memory.
123
+
124
+ Every storage request sends `Authorization: Bearer <apiKey>` and `X-AtomicMemory-User-Id`. The SDK never sends the legacy `?user_id=` URL parameter.
125
+
126
+ ## Installation
127
+
128
+ ```bash
129
+ pip install atomicmemory # core + local search + SQLite store
130
+ pip install 'atomicmemory[embeddings]' # + sentence-transformers for local embeddings
131
+ ```
132
+
133
+ ## Development
134
+
135
+ ```bash
136
+ uv sync --extra dev --extra embeddings
137
+ uv run pytest
138
+ uv run ruff check .
139
+ uv run ruff format --check .
140
+ uv run mypy atomicmemory --strict
141
+ uv run vulture atomicmemory tests .vulture_whitelist.py --min-confidence 90
142
+ ```
143
+
144
+ ## License
145
+
146
+ MIT
@@ -0,0 +1,67 @@
1
+ atomicmemory/__init__.py,sha256=dGbYABwc3qpefct9OMCMmYW4kC-dcwrOM229db5heuo,3927
2
+ atomicmemory/_version.py,sha256=qtodX2wTJerDeZidLhVlfcZBglrhPmyrTn5pVe7DZyA,79
3
+ atomicmemory/client/__init__.py,sha256=ZOGuWYtVcnFOtISX5jj9Ii2f4UCPxdNQHqFFbn3Gpho,676
4
+ atomicmemory/client/async_memory_client.py,sha256=DHuMi1gk0u88uy1Vrooy37SzS_tDbizLQTyCRXX73ls,7443
5
+ atomicmemory/client/atomic_memory_client.py,sha256=7LtqEBgVmtmnzhyrMMohweggfMI3nOz6tTSrVcAbbZs,6199
6
+ atomicmemory/client/memory_client.py,sha256=HMzPV_nk_-lAanyg9_0txfbZlemH_fbfbnqYJ7mqI1A,11096
7
+ atomicmemory/core/__init__.py,sha256=YqnArzYJ4xC2xKj7_fob8wlkgf3sj90ugPpBa-2lbr8,897
8
+ atomicmemory/core/errors.py,sha256=rhzK2KV6p7e5lS1oeXbBtevVLn52iPWrZhQ_OKHdgY0,3847
9
+ atomicmemory/core/events.py,sha256=OMoH5SwAkC_BszpvRi9kPQqotQsJA-mVOMLv_Jm2MTM,2124
10
+ atomicmemory/core/logging.py,sha256=bh-I7LMvt2AuGaozYuiPxpzwpLxmdmizhmxd1wdUjGU,1151
11
+ atomicmemory/core/retry.py,sha256=tjes8NP2TwSGqQhvCWbmNnLRDeLGB269fJKfE9Loioc,4234
12
+ atomicmemory/core/validation.py,sha256=pTHBFd6Ksqc0DM6DIIKkJJwoNR5WNKdd4gmU8sZmRks,796
13
+ atomicmemory/embeddings/__init__.py,sha256=bJVq54A_s_TWV-Iim9vXgFtYJsCF3ijZFMcat7G_Dxw,602
14
+ atomicmemory/embeddings/base.py,sha256=gAo8I3euGkQ0_YhIy0a7EwP2PgVq-Ks-2SKU4R6YOiQ,971
15
+ atomicmemory/embeddings/sentence_transformers.py,sha256=_0K8klsV1V4EgAe0e4_PbWME1H7o_f-zrh-f7_0D3xY,3462
16
+ atomicmemory/kv_cache/__init__.py,sha256=pTm1kP-smBuTfSYRcjBQ9zyOYgDIrrNU7NfYG2WO89M,781
17
+ atomicmemory/kv_cache/adapter.py,sha256=BQ3ekePv3W_L7MQJN07IqfSaC-X3aT6BjDzcYTnx8UA,1468
18
+ atomicmemory/kv_cache/memory_storage.py,sha256=HYPV5J9_ShvH6QJcaNp1jBQvwLITJVuTqzqEMDuvqtE,2963
19
+ atomicmemory/kv_cache/sqlite_storage.py,sha256=noMe7OGqMsb0cRimv33UjtQPuNmpHIbF-lEyYluaAjA,4187
20
+ atomicmemory/memory/__init__.py,sha256=5j1vIE-DsO74ZzfKM6TW9aAPAzXCY_APBdbZHTEYsSY,1635
21
+ atomicmemory/memory/filters.py,sha256=7dVi_NQf2uqaftNaSRqFYhxS6FRa-qak1KVs5fLEULU,1568
22
+ atomicmemory/memory/pipeline.py,sha256=LbyufJMmSWVHRJVem_3SpdhWCiL5CGgCP3MkV3BYv1E,1467
23
+ atomicmemory/memory/provider.py,sha256=fZPqRW3rCqIG_oKJs49t0TYjOxawTb_-K_oFqaqIYt8,12619
24
+ atomicmemory/memory/registry.py,sha256=CNbXUPnqRQs7px7JJEvdWcCWazpRLXZiBEgS2tpfd6o,2975
25
+ atomicmemory/memory/service.py,sha256=AxhaMl4vGexJjq_tigoQ44Lheh2KnS6jXnGmNJV-m6U,7879
26
+ atomicmemory/memory/types.py,sha256=6TUYwC0JLGxjMymLyuZWdTa9TLScI4yQDkr36QbFySk,11138
27
+ atomicmemory/providers/__init__.py,sha256=DR8rK2eyn_VIgW3sMHWJnhLtb8W2pbnEajAMRM6jiIk,155
28
+ atomicmemory/providers/atomicmemory/__init__.py,sha256=GL2fdEW8fO4A458IS6cy9NQM3_yTUha-pG9voXNVGHE,1490
29
+ atomicmemory/providers/atomicmemory/agents.py,sha256=rbB0D_8sLDh9oTWth2eGoIdqUjaYRAqEl1V1KClFEYQ,5422
30
+ atomicmemory/providers/atomicmemory/async_handle_impl.py,sha256=2YfIuEiZGmfV2UyhT9HPcDAqi0FZ7f3LI8zaMS_DdUU,8125
31
+ atomicmemory/providers/atomicmemory/async_provider.py,sha256=J3hWUJDftpY7ctzXwueJpFyvxX_lq9B0VL1V7_I3c6c,9671
32
+ atomicmemory/providers/atomicmemory/audit.py,sha256=r8oonF9pZjMDocH0ICBPOb39OE91Hn0cyKKFv6REyfk,2929
33
+ atomicmemory/providers/atomicmemory/config.py,sha256=rt3-xe9hGZLZZw3zMA7CW80vyzFZzPUx6inybDDsRM0,1336
34
+ atomicmemory/providers/atomicmemory/config_handle.py,sha256=DfA81nEecRgRcbGJo7ONLi0zj2nHqbQWh_dI9eWkI4I,4751
35
+ atomicmemory/providers/atomicmemory/handle.py,sha256=cIjMICQCrGCTZFnj2F6iAOipF41bdQbyLI2eO9wnaBk,15361
36
+ atomicmemory/providers/atomicmemory/handle_impl.py,sha256=JoQYgJ1R1jWX_UGrP7Z5LfM5UNWi91RtIVfaDygkCzg,13366
37
+ atomicmemory/providers/atomicmemory/http.py,sha256=XU0NreFhGpseaES5HnFKRZKlfXTktI5a5DxR-QNjT5M,7052
38
+ atomicmemory/providers/atomicmemory/lessons.py,sha256=QnZgti96YdJ05w-1KbT8CPrLnJBI3c0qQ80pD8xO-IA,4512
39
+ atomicmemory/providers/atomicmemory/lifecycle.py,sha256=pX6gZTgeaCDzoSMh6O6K6Lw9tWH-eV4is9U4z_PVaWE,7000
40
+ atomicmemory/providers/atomicmemory/mappers.py,sha256=dsHC9Y0fP2vn83KmN4Aid7wg5Fl2X57EgkTRqSVIW20,4157
41
+ atomicmemory/providers/atomicmemory/path.py,sha256=-99ZiITsu9vYVoOkefMCGDrryNG8N90TwDLi6kz8YRI,538
42
+ atomicmemory/providers/atomicmemory/provider.py,sha256=g87TqZ6hzpTeNOEyW_CtWM3SUfHXsLORXOkem_9-G3k,11467
43
+ atomicmemory/providers/atomicmemory/scope_mapper.py,sha256=ndm6fEptppW6tItDjrzfgOEd1aCAfOUmBwB_5M1VR7E,3610
44
+ atomicmemory/providers/mem0/__init__.py,sha256=U56wstuAuchnPYw-nyLewb3JaHhUVPcqhqVyVhV0EQM,1266
45
+ atomicmemory/providers/mem0/async_provider.py,sha256=moKefYiLRCKDEOfg4U-tF3N3L-CGdPJkQk5BCCJQktU,6910
46
+ atomicmemory/providers/mem0/config.py,sha256=8fOpK19xgqJv4HCeg4HYHNovVKoclG9fvVe2H5XqZgg,1726
47
+ atomicmemory/providers/mem0/http.py,sha256=kDtLLQu6_y1CMMoyv23HxPBbRQ5nyxHriZ1e5_SRGZU,5541
48
+ atomicmemory/providers/mem0/mappers.py,sha256=CRFryLWkRhU_6sGnyrBi25McNjAgitPABks4RFtJCyI,4850
49
+ atomicmemory/providers/mem0/provider.py,sha256=IMnvDI6zegqmC7mhc2laq-NjgQPAjbvOpvSGaRrJmro,7268
50
+ atomicmemory/search/__init__.py,sha256=RD_G1WMR5ae9P2KqGLMrK2IJLatqvFYXxio7hmSESqM,1221
51
+ atomicmemory/search/chunking.py,sha256=rmevW2tuGZjSqHPg0XEkY8Xu4__zQcPH_sMnMhBRwEA,5514
52
+ atomicmemory/search/ranking.py,sha256=AzhyTmO6o0X5W9ORMk-V9Ec-wj4PuO1z-jGZM63GzNk,2922
53
+ atomicmemory/search/semantic_search.py,sha256=tJizviYA7Ewo3WSg0H1RO-jaSSXm6gR4AoDlyafptfw,4741
54
+ atomicmemory/search/similarity.py,sha256=8sTcnt1NecWEYRNPcfNfy6E0PRLanqUH-GhHutUe5OI,3602
55
+ atomicmemory/storage/__init__.py,sha256=fGZBT15cjm6TCyJby19vAmpHpyGOmv-fNkhnhZvbLq4,1684
56
+ atomicmemory/storage/_mapping.py,sha256=xS9CVFHmW3YLG2nXvSI8Sn39DwdfCa3kvt4teBlY4Xo,11841
57
+ atomicmemory/storage/async_client.py,sha256=6x0RW8uhepvUVU_pj3Izsaf3dtA0DbnQWMWurNFJoqI,7452
58
+ atomicmemory/storage/client.py,sha256=s78u-pGVG6DtWVPr8gwqryPLvMHeOT1xwT9KQwtuXek,12473
59
+ atomicmemory/storage/errors.py,sha256=3R8vbGfW_8RaFlYIZ5oAxrdVKqih34JVtshi-LYQdNU,3790
60
+ atomicmemory/storage/types.py,sha256=uzUP5NEKHYbVSJ-ljcsdZ5WKp2WOOO4avwKcTPepIK0,11030
61
+ atomicmemory/utils/__init__.py,sha256=RqKXEYX5ZNHdTOt_NOY7B1DU1VsiUDak1CL3YnDOCAU,149
62
+ atomicmemory/utils/environment.py,sha256=vTyN_opmNtfur9rsjGdXGSpouNT3MckUgTm7Voe7Qmw,723
63
+ atomicmemory/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
+ atomicmemory-1.0.0.dist-info/METADATA,sha256=NteFycOA0bUbVOut2QbxYXht0EOT3N5Kg9RCSjoCOMg,5226
65
+ atomicmemory-1.0.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
66
+ atomicmemory-1.0.0.dist-info/licenses/LICENSE,sha256=vMGL9gR35PGpiGIytzTt1H2uHZLO3N_bPAMu_Uk5pR0,1069
67
+ atomicmemory-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AtomicMemory
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.