3tears-agent-memory 0.14.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 (44) hide show
  1. 3tears_agent_memory-0.14.0.dist-info/METADATA +231 -0
  2. 3tears_agent_memory-0.14.0.dist-info/RECORD +44 -0
  3. 3tears_agent_memory-0.14.0.dist-info/WHEEL +4 -0
  4. 3tears_agent_memory-0.14.0.dist-info/licenses/LICENSE +21 -0
  5. threetears/agent/memory/__init__.py +229 -0
  6. threetears/agent/memory/access.py +205 -0
  7. threetears/agent/memory/authorize.py +505 -0
  8. threetears/agent/memory/collections.py +3197 -0
  9. threetears/agent/memory/embedding_utils.py +138 -0
  10. threetears/agent/memory/entities.py +1134 -0
  11. threetears/agent/memory/events.py +229 -0
  12. threetears/agent/memory/extraction.py +758 -0
  13. threetears/agent/memory/integration.py +361 -0
  14. threetears/agent/memory/merge.py +192 -0
  15. threetears/agent/memory/middleware.py +297 -0
  16. threetears/agent/memory/migrations/__init__.py +222 -0
  17. threetears/agent/memory/migrations/v001_create_memories_table.py +73 -0
  18. threetears/agent/memory/migrations/v002_create_conversation_memory_refs.py +50 -0
  19. threetears/agent/memory/migrations/v003_memory_column_reconciliation.py +110 -0
  20. threetears/agent/memory/migrations/v004_memory_lifecycle_columns.py +75 -0
  21. threetears/agent/memory/migrations/v005_memory_fts.py +78 -0
  22. threetears/agent/memory/migrations/v006_memory_media_content.py +123 -0
  23. threetears/agent/memory/migrations/v007_memory_chunks.py +96 -0
  24. threetears/agent/memory/migrations/v008_restore_memories_agent_customer_not_null.py +73 -0
  25. threetears/agent/memory/migrations/v009_media_composite_fk.py +132 -0
  26. threetears/agent/memory/migrations/v010_media_content_composite_fk.py +94 -0
  27. threetears/agent/memory/migrations/v011_memory_chunks_composite_fk.py +93 -0
  28. threetears/agent/memory/migrations/v012_memories_media_composite_fk.py +133 -0
  29. threetears/agent/memory/migrations/v013_datetime_to_datetimetz.py +256 -0
  30. threetears/agent/memory/migrations/v014_memory_refs_date_columns.py +131 -0
  31. threetears/agent/memory/migrations/v015_unified_memory_columns.py +123 -0
  32. threetears/agent/memory/migrations/v016_backfill_memory_ids.py +276 -0
  33. threetears/agent/memory/migrations/v017_memory_fk_flip.py +168 -0
  34. threetears/agent/memory/migrations/v018_drop_legacy_memory_columns.py +171 -0
  35. threetears/agent/memory/migrations/v019_conversation_id_not_null.py +82 -0
  36. threetears/agent/memory/migrations/v020_memories_alias.py +64 -0
  37. threetears/agent/memory/migrations/v021_memory_chunks_index_and_token.py +304 -0
  38. threetears/agent/memory/migrations/v022_add_hnsw_gin_indexes.py +241 -0
  39. threetears/agent/memory/migrations/v023_fix_idx_chunks_message_id_start.py +79 -0
  40. threetears/agent/memory/prompts.py +112 -0
  41. threetears/agent/memory/py.typed +0 -0
  42. threetears/agent/memory/retrieval.py +633 -0
  43. threetears/agent/memory/tools.py +1584 -0
  44. threetears/agent/memory/types.py +75 -0
@@ -0,0 +1,231 @@
1
+ Metadata-Version: 2.4
2
+ Name: 3tears-agent-memory
3
+ Version: 0.14.0
4
+ Summary: Memory system for LLM agents -- extraction, retrieval, hybrid search, and MMR reranking
5
+ Project-URL: Repository, https://github.com/pacepace/3tears
6
+ Author: pace
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Framework :: AsyncIO
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.14
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Classifier: Topic :: Software Development :: Libraries
16
+ Classifier: Typing :: Typed
17
+ Requires-Python: >=3.14
18
+ Requires-Dist: 3tears
19
+ Requires-Dist: 3tears-agent-acl
20
+ Requires-Dist: 3tears-langgraph
21
+ Requires-Dist: 3tears-observe
22
+ Requires-Dist: langchain-core
23
+ Requires-Dist: pgvector
24
+ Description-Content-Type: text/markdown
25
+
26
+ # 3tears Agent Memory
27
+
28
+ Memory system for LLM agents. Handles extraction of memorable facts from conversations, hybrid retrieval (semantic + full-text + recency), and memory lifecycle management.
29
+
30
+ Part of the [3tears](https://github.com/pacepace/3tears) framework.
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ pip install 3tears-agent-memory
36
+ ```
37
+
38
+ ## Components
39
+
40
+ ### Collections are the single entry point for memory-table SQL
41
+
42
+ Every memory-table write, single-row read, batch read, and hybrid-search query goes through one of four `BaseCollection` subclasses; no consumer of this package holds an `asyncpg.Pool` reference directly.
43
+
44
+ - `MemoriesCollection` -- `memories` table. CRUD through `get` / `save_entity` / `delete`; complex queries through `hybrid_search`, `search_by_ids`, `search_by_semantic`, `search_by_fts`, `find_similar_for_dedup`, `count_by_user`, `fetch_content_for_recall`.
45
+ - `MediaCollection` -- `media` parent table. CRUD only.
46
+ - `MediaContentCollection` -- `media_content` child table. CRUD + `hybrid_search`, `search_by_ids`, `search_by_semantic`, `search_by_fts`, `fetch_content_for_recall`.
47
+ - `MemoryChunkCollection` -- `memory_chunks` child table. CRUD + `hybrid_search`, `search_by_ids`, `search_by_semantic`, `fetch_content_for_recall`.
48
+
49
+ All four resolve their L3 pool through `CollectionRegistry` (same pattern `ConversationCollection` uses); an L1 `SQLiteBackend` attached to the registry populates on `save_entity` and serves subsequent by-id `get` calls without an L3 round-trip. The `media` / `media_content` / `memory_chunks` tables are introduced by migrations v006 / v007.
50
+
51
+ Hybrid-search methods carry documented `# cache-bypass: <reason>` inline comments because the query shape (vector distance, FTS rank, multi-table joins) is not primary-key-addressable and the L1 row cache cannot serve the lookup. Keeping the SQL on the Collection preserves the single entry point. The cache-primitive enforcement walker recognises in-Collection bypass sites as legitimate and reports any bypass that leaks back into `retrieval.py` / `extraction.py` / `tools.py` as a violation.
52
+
53
+ ### MemoryExtractor
54
+
55
+ Extracts memorable facts from conversation turns. Uses a multi-stage pipeline: candidate extraction via LLM, deduplication against existing memories via embedding similarity, and action resolution (ADD / UPDATE / DELETE).
56
+
57
+ ```python
58
+ from threetears.agent.memory import (
59
+ MemoriesCollection,
60
+ MemoryConfig,
61
+ MemoryExtractor,
62
+ )
63
+
64
+ extractor = MemoryExtractor(
65
+ config=MemoryConfig(),
66
+ embedding_provider=my_embedding_provider,
67
+ chat_model_factory=my_chat_model_factory,
68
+ authorizer=authorizer_bundle,
69
+ memories_collection=memories_collection,
70
+ summary_callback=on_new_memory,
71
+ )
72
+
73
+ await extractor.extract(
74
+ user_id=user_id,
75
+ conversation_id=conv_id,
76
+ message_id_source=msg_id,
77
+ user_message="I just moved to Portland",
78
+ assistant_response="That's exciting! Portland has great food...",
79
+ turn_count=5,
80
+ agent_id=agent_id,
81
+ customer_id=customer_id,
82
+ )
83
+ ```
84
+
85
+ ### MemoryRetriever
86
+
87
+ Retrieves relevant memories using hybrid search: pgvector semantic similarity, PostgreSQL full-text search, recency decay, and MMR reranking for diversity. Takes the three search-bearing Collections at construction; no pool.
88
+
89
+ ```python
90
+ from threetears.agent.memory import MemoryRetriever, MemoryConfig
91
+
92
+ retriever = MemoryRetriever(
93
+ config=MemoryConfig(),
94
+ embedding_provider=my_embedding_provider,
95
+ authorizer=authorizer_bundle,
96
+ memories_collection=memories_collection,
97
+ media_content_collection=media_content_collection,
98
+ memory_chunk_collection=memory_chunk_collection,
99
+ )
100
+
101
+ result = await retriever.retrieve_with_candidates(
102
+ user_id,
103
+ "Tell me about Portland",
104
+ agent_id=agent_id,
105
+ customer_id=customer_id,
106
+ caller_user_id=user_id,
107
+ caller_agent_id=agent_id,
108
+ )
109
+
110
+ # result.context -- formatted string for injection into system prompt
111
+ # result.memories -- raw memory dicts with similarity scores
112
+ # result.media_content -- matched media content
113
+ # result.memory_chunks -- matched document chunks
114
+ ```
115
+
116
+ ### Protocols
117
+
118
+ Implement these to integrate with your infrastructure:
119
+
120
+ ```python
121
+ from threetears.agent.memory import EmbeddingProvider, ChatModelFactory
122
+
123
+ class MyEmbeddingProvider(EmbeddingProvider):
124
+ async def embed(self, text: str) -> tuple[list[float], int, UUID]:
125
+ # Returns (embedding_vector, token_count, model_id)
126
+ ...
127
+
128
+ class MyChatModelFactory(ChatModelFactory):
129
+ async def create_chat_model(self, purpose: str = "extraction"):
130
+ # Returns a langchain BaseChatModel
131
+ ...
132
+ ```
133
+
134
+ ### Tools
135
+
136
+ LangChain tools for agent use: memory search, recall, and explicit add. Factories take Collection references; no pool:
137
+
138
+ ```python
139
+ from threetears.agent.memory import (
140
+ load_memory_add_tool,
141
+ load_memory_search_tool,
142
+ load_memory_recall_tool,
143
+ )
144
+
145
+ search_tool = await load_memory_search_tool(
146
+ user_id=user_id,
147
+ embedding_provider=embedding_provider,
148
+ agent_id=agent_id,
149
+ customer_id=customer_id,
150
+ authorizer=authorizer_bundle,
151
+ memories_collection=memories_collection,
152
+ media_content_collection=media_content_collection,
153
+ memory_chunk_collection=memory_chunk_collection,
154
+ )
155
+ recall_tool = await load_memory_recall_tool(
156
+ user_id=user_id,
157
+ agent_id=agent_id,
158
+ customer_id=customer_id,
159
+ authorizer=authorizer_bundle,
160
+ memories_collection=memories_collection,
161
+ media_content_collection=media_content_collection,
162
+ memory_chunk_collection=memory_chunk_collection,
163
+ )
164
+ add_tool = await load_memory_add_tool(
165
+ user_id=user_id,
166
+ conversation_id=conv_id,
167
+ message_id=msg_id,
168
+ embedding_provider=embedding_provider,
169
+ agent_id=agent_id,
170
+ customer_id=customer_id,
171
+ authorizer=authorizer_bundle,
172
+ memories_collection=memories_collection,
173
+ )
174
+ ```
175
+
176
+ ### Configuration
177
+
178
+ ```python
179
+ from threetears.agent.memory import MemoryConfig
180
+
181
+ config = MemoryConfig(
182
+ similarity_threshold=0.4, # minimum cosine similarity for retrieval
183
+ detail_threshold=0.85, # threshold for including full memory detail
184
+ context_budget=15, # max memories in context
185
+ dedup_threshold=0.85, # similarity threshold for deduplication
186
+ max_candidates=10, # max candidates per extraction
187
+ )
188
+ ```
189
+
190
+ ## Database Schema
191
+
192
+ Requires PostgreSQL with the `pgvector` extension. The package's own migration runner (`threetears.agent.memory.migrations.register`) produces the full schema per agent schema. Registered versions:
193
+
194
+ - **v001** -- `memories` (PK `memory_id`, pgvector `embedding`, scoping ids, content, summary, lifecycle timestamps).
195
+ - **v002** -- `conversation_memory_refs` (ledger of per-conversation surfaced items).
196
+ - **v003** -- column reconciliation: renames PK and discriminator to match the package code (`id` to `memory_id`, `memory_type` to `type_memory`), drops columns the code does not read (`embedding_model`, `importance`, `metadata`, `date_accessed`), loosens `agent_id`/`customer_id` to NULL.
197
+ - **v004** -- lifecycle + conversation-link columns on `memories` (`conversation_id`, `message_id_source`, `is_deleted`, `media_id`, `date_deleted`, `summary`) with indexes.
198
+ - **v005** -- FTS: `search_vector TSVECTOR` + GIN index + maintenance trigger on `memories`.
199
+ - **v006** -- `media` (parent) + `media_content` (chunked extracted text with embedding + FTS).
200
+ - **v007** -- `memory_chunks` (document-style chunks with heading / page metadata + embedding + FTS).
201
+
202
+ Every FTS column is trigger-maintained from `content` + `summary` (weighted A/B); callers do not have to populate `search_vector` manually. Integration tests under `tests/integration/` exercise the full chain + every public API surface against `pgvector/pgvector:pg16` via testcontainers.
203
+
204
+ ## RBAC Enforcement
205
+
206
+ Memory reads, writes, and extractions flow through the unified rbac evaluator in `threetears.agent.acl`. Every (agent, customer) pair is a `memory`-type namespace in the `namespaces` table; each access resolves the namespace and evaluates one of three canonical actions against the caller's `(user_id, agent_id)` pair:
207
+
208
+ - `memory.read` -- retrieval / search / recall. Guarded on `MemoryRetriever.retrieve*`, `MemoriesCollection.find_by_user`, `MemoriesCollection.find_by_scope`, the `memory_search` + `memory_recall` LangChain tools.
209
+ - `memory.write` -- user-initiated writes. Guarded on `MemoriesCollection.save_memory` and the `memory_add` LangChain tool.
210
+ - `memory.extract` -- agent-internal extraction path. Guarded on `MemoryExtractor.extract`; the owner short-circuit keeps the common case (agent emitting memories on its own namespace) grant-free.
211
+
212
+ Owner short-circuit: the evaluator allows any action when the calling agent owns the memory namespace. Agent-internal retrieval and extraction therefore work without explicit grants; user-initiated reads and writes require evaluator assignments.
213
+
214
+ Auto-assignment on first user-write: `memory_add` ensures a `MemoryOwner` assignment for the calling user on their first write (idempotent-by-state; the ensurer only fires when the user has zero memory rows in the target schema). Subsequent writes authorize against the materialized grant; admin-revoked grants stay revoked (the ensurer does not resurrect them).
215
+
216
+ Wiring shape: every consumer of the memory surface REQUIRES a `MemoryAuthorizerDependencies` bundle exposing:
217
+
218
+ - `acl_cache` -- shared `threetears.agent.acl.AclCache` instance;
219
+ - `membership_loader` + `grant_loader` -- the evaluator's loaders (`threetears.agent.acl.MembershipLoader` / `GrantLoader`);
220
+ - `namespace_collection` -- three-tier `NamespaceCollection` used to resolve the memory namespace via `get_by_owner_and_customer(namespace_type="memory", owner_agent_id, customer_id)` (create-if-absent flows through `save_entity`);
221
+ - `group_collection` + `group_member_collection` + `role_collection` + `role_assignment_collection` -- the rbac Collections the first-write owner-assignment path uses via `ensure_memory_owner_assignment(...)`.
222
+
223
+ There is no bypass. Every `MemoriesCollection`, `MemoryRetriever`, `MemoryExtractor`, and LangChain tool factory (`load_memory_search_tool`, `load_memory_add_tool`, `load_memory_recall_tool`) takes the bundle as a required constructor/factory argument; every code path that touches a memory row runs `authorize_memory_access` first. Callers that omit the bundle fail at the type checker and the Python signature boundary.
224
+
225
+ - Production wiring builds the bundle directly from the agent-side three-tier stack's Collections (`NatsProxyL3Backend`-backed `NamespaceCollection` / `GroupCollection` / ...).
226
+ - Test wiring injects a permissive fixture `permissive_memory_authorizer` (see `tests/conftest.py`) that carries in-memory Collection stand-ins and a permissive evaluator. Fixture usage is explicit in every test file that constructs a memory surface.
227
+ - Back-office / admin tooling that genuinely needs to read or write memories without an identity must construct its own bundle with Collections bound directly to an asyncpg pool; there is no global escape hatch.
228
+
229
+ See `threetears.agent.memory.authorize` for the full public surface.
230
+
231
+ The three platform roles (`MemoryOwner` / `MemoryReader` / `MemoryWriter`) carry the canonical action vocabulary. Platform-side migrations seed these roles and backfill the rbac rows required for evaluator resolution.
@@ -0,0 +1,44 @@
1
+ threetears/agent/memory/__init__.py,sha256=jGo_9QlPJ8eFMX6e6VBAlH5WJYt4Q5zSPMYAjgQJ7do,10678
2
+ threetears/agent/memory/access.py,sha256=Hk9WQda_ssC-kcR2PfiTDx5uUCfh5uPgihQEqfFZu_w,8309
3
+ threetears/agent/memory/authorize.py,sha256=07mPdKHSjFgilmdOgBXxVFLKklDcCc5Dwk7deJfSfLY,19705
4
+ threetears/agent/memory/collections.py,sha256=QCojKCUVKAdsRdXnP1gRiyumvaNV3oHJSrM5Gp2S3Vk,128370
5
+ threetears/agent/memory/embedding_utils.py,sha256=cFZ4pHxzAShLCFfytDA8fwwRtCUExku8ILj0HE-5YzU,5323
6
+ threetears/agent/memory/entities.py,sha256=0PocHbBQUtOY_WNw8RgvnyJzxvXnmdxfTetxAhIvg6U,34495
7
+ threetears/agent/memory/events.py,sha256=8yhFcprivqFgLiZyJfs-UdMWifGodGJQtxp5gNd-X30,9355
8
+ threetears/agent/memory/extraction.py,sha256=LamsymOrCwwsRLaqchtSdB-0goNjR0gg0ZZ7K3oGSi4,31173
9
+ threetears/agent/memory/integration.py,sha256=aKJXO5rOdwTPpY_JpWW-edpd8FNG9XeBrrzH029Wd_o,13406
10
+ threetears/agent/memory/merge.py,sha256=mjNja4X94OR9un3gKCG9B_mw4fGV3gCEnmmQAVR8jXY,7400
11
+ threetears/agent/memory/middleware.py,sha256=YGDfLBpnuj1ZEeM4iZvKiVjgLjHl0U01vF_C5sqWgQM,15072
12
+ threetears/agent/memory/prompts.py,sha256=ms1OEM295Zd-2eJvpCjFTIcK4oh6S6wzMzgQ-PIIn80,6217
13
+ threetears/agent/memory/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ threetears/agent/memory/retrieval.py,sha256=lAVW648E6Fi893eXlsnD8szAOISdBK6QoIgoIy8yNw0,24338
15
+ threetears/agent/memory/tools.py,sha256=2h-XNpefK79Lr1IhjZBriOADLPKLa8AJe30CvZVOcN0,64570
16
+ threetears/agent/memory/types.py,sha256=MesgOsGGgjbdgWUh7g84ADCxzcdgfa9H_8NQAR8S5RE,1980
17
+ threetears/agent/memory/migrations/__init__.py,sha256=H5olHd_veZC9dVvaUSg1Nx2dNM5ZVKxjSnFJOJGoja4,8808
18
+ threetears/agent/memory/migrations/v001_create_memories_table.py,sha256=Ls_rkYDdVSMO5ioVG-_J2GGhVx3kWXlxIt0BjYoata8,2602
19
+ threetears/agent/memory/migrations/v002_create_conversation_memory_refs.py,sha256=pXV_yBm44NswVIGYvCIEoxdAExAw-0yFehe96LjuVx4,1544
20
+ threetears/agent/memory/migrations/v003_memory_column_reconciliation.py,sha256=LU7q2KIAFbvMy86yp9WjAw94RHjC2TJD_nvD6LUSE50,4055
21
+ threetears/agent/memory/migrations/v004_memory_lifecycle_columns.py,sha256=jhb4uLZqe9SZJtgBezyZAMl9Au7JagmEGKBTZwxL1bA,2952
22
+ threetears/agent/memory/migrations/v005_memory_fts.py,sha256=lTerrZ9_i4oWbkttN6rZDDEBstcO0YIzeYWwJktTaLc,2519
23
+ threetears/agent/memory/migrations/v006_memory_media_content.py,sha256=FmB8og7DCKjG2pBDLu8-NMfGbnWg23T92eTuLQQQabk,4076
24
+ threetears/agent/memory/migrations/v007_memory_chunks.py,sha256=muGDAttKEn411MBX3kI45TT_bObzA39u8qXJIKLLd0g,3341
25
+ threetears/agent/memory/migrations/v008_restore_memories_agent_customer_not_null.py,sha256=UhyDYOTEsoeP3Oj_fZuiK57eceTpRps_WoOe0MqoqV8,2842
26
+ threetears/agent/memory/migrations/v009_media_composite_fk.py,sha256=wlM19dxcz836wQCunOQkFWgh1lJ3xNhrvBozEJEyuis,4937
27
+ threetears/agent/memory/migrations/v010_media_content_composite_fk.py,sha256=IU0RfAWqY2Ukwu-YclyRtDKqOxqFvPKefkCy3oqe_wc,3188
28
+ threetears/agent/memory/migrations/v011_memory_chunks_composite_fk.py,sha256=_hwAkREFlIcwrDcok5EqOFiB1JVcsydXjD1MK3utw9c,3105
29
+ threetears/agent/memory/migrations/v012_memories_media_composite_fk.py,sha256=vRhn97Vz6Sqmz_kkl1VpQtDfzTeTQWLewrZOA1jXlqQ,5069
30
+ threetears/agent/memory/migrations/v013_datetime_to_datetimetz.py,sha256=mjSDeZiES7PtPYzzw9tcJddm7xHg63h5ww-siK1F1lA,8081
31
+ threetears/agent/memory/migrations/v014_memory_refs_date_columns.py,sha256=KDSCeWXz9obpOPFdn6B_zzS1snBrzmC00PdE2GLBhV0,4546
32
+ threetears/agent/memory/migrations/v015_unified_memory_columns.py,sha256=aifypnMEji3y3GW0uqsNwM-BTyHNZ7sJiDHJHolsVTw,5112
33
+ threetears/agent/memory/migrations/v016_backfill_memory_ids.py,sha256=Lng6Hih_FShYtLOjvnKWjA5zN26xgDTyLSiWfHD9dK0,9594
34
+ threetears/agent/memory/migrations/v017_memory_fk_flip.py,sha256=COGO7QrgLTULE4-5MO4DnNoy5a35xtpiaGIFRd4GXMM,5423
35
+ threetears/agent/memory/migrations/v018_drop_legacy_memory_columns.py,sha256=S65m9ujHQgp89Ti03x_dRnu2zO_YXWBy9C8rbD7Z5E8,5936
36
+ threetears/agent/memory/migrations/v019_conversation_id_not_null.py,sha256=8GHKou_JBqWA1BT8gGuPxG5H2Hel0xnZK_mtP4FSEe8,2390
37
+ threetears/agent/memory/migrations/v020_memories_alias.py,sha256=yyl6GYnl5gzA5glfXuubSO47kun_ixzWVgo-BYvZCZ8,1763
38
+ threetears/agent/memory/migrations/v021_memory_chunks_index_and_token.py,sha256=QY5mysFEnnTsePLo0C4t2gkXyewjQNa9WzV3ZN5SbW4,14088
39
+ threetears/agent/memory/migrations/v022_add_hnsw_gin_indexes.py,sha256=55zu4kDqTsWmiH3JR34lfeEpkgM9wjzKOB9NkSbI8Pc,9652
40
+ threetears/agent/memory/migrations/v023_fix_idx_chunks_message_id_start.py,sha256=4nZZVR_94XapT0PSBMYExBVbMVNuQhzstrNtXnPtcok,2995
41
+ 3tears_agent_memory-0.14.0.dist-info/METADATA,sha256=MUXbhpydR3YibUXsj5ujV-Q9D3yqI_R8H_QmZKQdF9E,12216
42
+ 3tears_agent_memory-0.14.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
43
+ 3tears_agent_memory-0.14.0.dist-info/licenses/LICENSE,sha256=7GWEoEOcFJenZLt4LDzqH2K7QLxo_2m8rzG7Vv8VGXo,1066
44
+ 3tears_agent_memory-0.14.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mark Pace
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.
@@ -0,0 +1,229 @@
1
+ """Agent memory package -- memory entities, collections, and embedding protocol."""
2
+
3
+ from __future__ import annotations
4
+
5
+ # Version derived from pyproject.toml so the metadata is the single
6
+ # source of truth -- a future release that bumps pyproject without
7
+ # updating ``__init__.py`` can't drift the runtime ``__version__``.
8
+ # The except guard handles the rare case where the package isn't
9
+ # installed via importlib.metadata (e.g. running directly from a
10
+ # checked-out source tree without ``uv sync``); the fallback keeps
11
+ # imports working but reports ``unknown`` rather than crashing.
12
+ from importlib.metadata import PackageNotFoundError as _PackageNotFoundError
13
+ from importlib.metadata import version as _version
14
+ from typing import TYPE_CHECKING
15
+
16
+ try:
17
+ __version__ = _version("3tears-agent-memory")
18
+ except _PackageNotFoundError: # pragma: no cover - dev fallback
19
+ __version__ = "unknown"
20
+
21
+ # lazy public API (PEP 562). the package namespace no longer imports its
22
+ # implementation modules eagerly: importing this package (or any of its
23
+ # submodules) costs only this file, and each public attribute resolves
24
+ # its defining module on first access. the TYPE_CHECKING block carries
25
+ # the real imports so mypy and IDEs see the full statically-typed API;
26
+ # the _LAZY map is the runtime equivalent. the three-way agreement
27
+ # between __all__, _LAZY, and the TYPE_CHECKING block is pinned by the
28
+ # package's lazy-surface consistency test.
29
+ # decision record: docs/separate-concerns-decisions.md (hand-rolled
30
+ # PEP 562 over lazy_loader -- zero added runtime deps, no stub drift).
31
+ if TYPE_CHECKING:
32
+ from threetears.agent.memory.access import MemoryAccessService
33
+ from threetears.agent.memory.authorize import (
34
+ ACTION_MEMORY_EXTRACT,
35
+ ACTION_MEMORY_READ,
36
+ ACTION_MEMORY_WRITE,
37
+ MEMORY_NAMESPACE_TYPE,
38
+ MEMORY_OWNER_GROUP_PREFIX,
39
+ MEMORY_OWNER_ROLE_NAME,
40
+ MemoryAccessDenied,
41
+ MemoryAuthorizerDependencies,
42
+ authorize_memory_access,
43
+ ensure_memory_owner_assignment,
44
+ memory_namespace_name,
45
+ )
46
+ from threetears.agent.memory.collections import (
47
+ MediaCollection,
48
+ MediaContentCollection,
49
+ MemoriesCollection,
50
+ MemoryChunkCollection,
51
+ MemoryRefsCollection,
52
+ conversation_memory_refs_table,
53
+ )
54
+ from threetears.agent.memory.embedding_utils import embedding_attribution_scope
55
+ from threetears.agent.memory.entities import (
56
+ MediaContentEntity,
57
+ MediaEntity,
58
+ MemoryChunkEntity,
59
+ MemoryEntity,
60
+ MemoryRefEntity,
61
+ )
62
+ from threetears.agent.memory.events import (
63
+ MemoryCreatedEvent,
64
+ MemoryRetrievedEvent,
65
+ default_memory_created_dispatcher,
66
+ )
67
+ from threetears.agent.memory.extraction import ChatModelFactory, MemoryExtractor
68
+ from threetears.agent.memory.integration import (
69
+ MemoryIntegration,
70
+ NatsEmbeddingAdapter,
71
+ extract_memories,
72
+ retrieve_memories,
73
+ )
74
+ from threetears.agent.memory.merge import MemoryRepointResult, repoint_user
75
+ from threetears.agent.memory.middleware import MemoryInjectionMiddleware
76
+ from threetears.agent.memory.prompts import ExtractionPrompts
77
+ from threetears.agent.memory.retrieval import MemoryRetriever, RetrievalResult
78
+ from threetears.agent.memory.tools import (
79
+ ChunkRecallInput,
80
+ ChunkSearchInput,
81
+ MemoryAddInput,
82
+ MemoryRecallInput,
83
+ MemorySearchInput,
84
+ load_chunk_recall_tool,
85
+ load_chunk_search_tool,
86
+ load_memory_add_tool,
87
+ load_memory_recall_tool,
88
+ load_memory_search_tool,
89
+ )
90
+ from threetears.agent.memory.types import MemoryConfig, MemoryType
91
+
92
+ # public attribute -> (defining module, attribute name in that module)
93
+ _LAZY: dict[str, tuple[str, str]] = {
94
+ "ACTION_MEMORY_EXTRACT": ("threetears.agent.memory.authorize", "ACTION_MEMORY_EXTRACT"),
95
+ "ACTION_MEMORY_READ": ("threetears.agent.memory.authorize", "ACTION_MEMORY_READ"),
96
+ "ACTION_MEMORY_WRITE": ("threetears.agent.memory.authorize", "ACTION_MEMORY_WRITE"),
97
+ "ChatModelFactory": ("threetears.agent.memory.extraction", "ChatModelFactory"),
98
+ "ChunkRecallInput": ("threetears.agent.memory.tools", "ChunkRecallInput"),
99
+ "ChunkSearchInput": ("threetears.agent.memory.tools", "ChunkSearchInput"),
100
+ "ExtractionPrompts": ("threetears.agent.memory.prompts", "ExtractionPrompts"),
101
+ "MEMORY_NAMESPACE_TYPE": ("threetears.agent.memory.authorize", "MEMORY_NAMESPACE_TYPE"),
102
+ "MEMORY_OWNER_GROUP_PREFIX": ("threetears.agent.memory.authorize", "MEMORY_OWNER_GROUP_PREFIX"),
103
+ "MEMORY_OWNER_ROLE_NAME": ("threetears.agent.memory.authorize", "MEMORY_OWNER_ROLE_NAME"),
104
+ "MediaCollection": ("threetears.agent.memory.collections", "MediaCollection"),
105
+ "MediaContentCollection": ("threetears.agent.memory.collections", "MediaContentCollection"),
106
+ "MediaContentEntity": ("threetears.agent.memory.entities", "MediaContentEntity"),
107
+ "MediaEntity": ("threetears.agent.memory.entities", "MediaEntity"),
108
+ "MemoriesCollection": ("threetears.agent.memory.collections", "MemoriesCollection"),
109
+ "MemoryAccessDenied": ("threetears.agent.memory.authorize", "MemoryAccessDenied"),
110
+ "MemoryAccessService": ("threetears.agent.memory.access", "MemoryAccessService"),
111
+ "MemoryAddInput": ("threetears.agent.memory.tools", "MemoryAddInput"),
112
+ "MemoryAuthorizerDependencies": ("threetears.agent.memory.authorize", "MemoryAuthorizerDependencies"),
113
+ "MemoryChunkCollection": ("threetears.agent.memory.collections", "MemoryChunkCollection"),
114
+ "MemoryChunkEntity": ("threetears.agent.memory.entities", "MemoryChunkEntity"),
115
+ "MemoryConfig": ("threetears.agent.memory.types", "MemoryConfig"),
116
+ "MemoryCreatedEvent": ("threetears.agent.memory.events", "MemoryCreatedEvent"),
117
+ "MemoryEntity": ("threetears.agent.memory.entities", "MemoryEntity"),
118
+ "MemoryExtractor": ("threetears.agent.memory.extraction", "MemoryExtractor"),
119
+ "MemoryInjectionMiddleware": ("threetears.agent.memory.middleware", "MemoryInjectionMiddleware"),
120
+ "MemoryIntegration": ("threetears.agent.memory.integration", "MemoryIntegration"),
121
+ "MemoryRecallInput": ("threetears.agent.memory.tools", "MemoryRecallInput"),
122
+ "MemoryRefEntity": ("threetears.agent.memory.entities", "MemoryRefEntity"),
123
+ "MemoryRefsCollection": ("threetears.agent.memory.collections", "MemoryRefsCollection"),
124
+ "MemoryRetrievedEvent": ("threetears.agent.memory.events", "MemoryRetrievedEvent"),
125
+ "MemoryRepointResult": ("threetears.agent.memory.merge", "MemoryRepointResult"),
126
+ "MemoryRetriever": ("threetears.agent.memory.retrieval", "MemoryRetriever"),
127
+ "MemorySearchInput": ("threetears.agent.memory.tools", "MemorySearchInput"),
128
+ "MemoryType": ("threetears.agent.memory.types", "MemoryType"),
129
+ "NatsEmbeddingAdapter": ("threetears.agent.memory.integration", "NatsEmbeddingAdapter"),
130
+ "RetrievalResult": ("threetears.agent.memory.retrieval", "RetrievalResult"),
131
+ "authorize_memory_access": ("threetears.agent.memory.authorize", "authorize_memory_access"),
132
+ "conversation_memory_refs_table": ("threetears.agent.memory.collections", "conversation_memory_refs_table"),
133
+ "default_memory_created_dispatcher": ("threetears.agent.memory.events", "default_memory_created_dispatcher"),
134
+ "embedding_attribution_scope": ("threetears.agent.memory.embedding_utils", "embedding_attribution_scope"),
135
+ "ensure_memory_owner_assignment": ("threetears.agent.memory.authorize", "ensure_memory_owner_assignment"),
136
+ "extract_memories": ("threetears.agent.memory.integration", "extract_memories"),
137
+ "load_chunk_recall_tool": ("threetears.agent.memory.tools", "load_chunk_recall_tool"),
138
+ "load_chunk_search_tool": ("threetears.agent.memory.tools", "load_chunk_search_tool"),
139
+ "load_memory_add_tool": ("threetears.agent.memory.tools", "load_memory_add_tool"),
140
+ "load_memory_recall_tool": ("threetears.agent.memory.tools", "load_memory_recall_tool"),
141
+ "load_memory_search_tool": ("threetears.agent.memory.tools", "load_memory_search_tool"),
142
+ "memory_namespace_name": ("threetears.agent.memory.authorize", "memory_namespace_name"),
143
+ "repoint_user": ("threetears.agent.memory.merge", "repoint_user"),
144
+ "retrieve_memories": ("threetears.agent.memory.integration", "retrieve_memories"),
145
+ }
146
+
147
+ __all__ = [
148
+ "ACTION_MEMORY_EXTRACT",
149
+ "ACTION_MEMORY_READ",
150
+ "ACTION_MEMORY_WRITE",
151
+ "ChatModelFactory",
152
+ "ChunkRecallInput",
153
+ "ChunkSearchInput",
154
+ "ExtractionPrompts",
155
+ "MEMORY_NAMESPACE_TYPE",
156
+ "MEMORY_OWNER_GROUP_PREFIX",
157
+ "MEMORY_OWNER_ROLE_NAME",
158
+ "MediaCollection",
159
+ "MediaContentCollection",
160
+ "MediaContentEntity",
161
+ "MediaEntity",
162
+ "MemoriesCollection",
163
+ "MemoryAccessDenied",
164
+ "MemoryAccessService",
165
+ "MemoryAddInput",
166
+ "MemoryAuthorizerDependencies",
167
+ "MemoryChunkCollection",
168
+ "MemoryChunkEntity",
169
+ "MemoryConfig",
170
+ "MemoryCreatedEvent",
171
+ "MemoryEntity",
172
+ "MemoryExtractor",
173
+ "MemoryInjectionMiddleware",
174
+ "MemoryIntegration",
175
+ "MemoryRecallInput",
176
+ "MemoryRefEntity",
177
+ "MemoryRefsCollection",
178
+ "MemoryRepointResult",
179
+ "MemoryRetrievedEvent",
180
+ "MemoryRetriever",
181
+ "MemorySearchInput",
182
+ "MemoryType",
183
+ "NatsEmbeddingAdapter",
184
+ "RetrievalResult",
185
+ "authorize_memory_access",
186
+ "conversation_memory_refs_table",
187
+ "default_memory_created_dispatcher",
188
+ "embedding_attribution_scope",
189
+ "ensure_memory_owner_assignment",
190
+ "extract_memories",
191
+ "load_chunk_recall_tool",
192
+ "load_chunk_search_tool",
193
+ "load_memory_add_tool",
194
+ "load_memory_recall_tool",
195
+ "load_memory_search_tool",
196
+ "memory_namespace_name",
197
+ "repoint_user",
198
+ "retrieve_memories",
199
+ ]
200
+
201
+
202
+ def __getattr__(name: str) -> object:
203
+ """resolve a public attribute from its defining module on first access.
204
+
205
+ :param name: attribute name being resolved
206
+ :ptype name: str
207
+ :return: the resolved attribute (also cached in module globals so
208
+ ``__getattr__`` fires at most once per name)
209
+ :rtype: object
210
+ :raises AttributeError: when ``name`` is not part of the public API
211
+ """
212
+ entry = _LAZY.get(name)
213
+ if entry is None:
214
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
215
+ from importlib import import_module
216
+
217
+ module_name, attr = entry
218
+ value: object = getattr(import_module(module_name), attr)
219
+ globals()[name] = value
220
+ return value
221
+
222
+
223
+ def __dir__() -> list[str]:
224
+ """include lazy attributes in ``dir()`` output.
225
+
226
+ :return: sorted union of materialized globals and lazy names
227
+ :rtype: list[str]
228
+ """
229
+ return sorted(set(globals()) | set(_LAZY))