grounded-memory 0.1.0__tar.gz

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 (76) hide show
  1. grounded_memory-0.1.0/LICENSE +21 -0
  2. grounded_memory-0.1.0/PKG-INFO +305 -0
  3. grounded_memory-0.1.0/README.md +257 -0
  4. grounded_memory-0.1.0/pyproject.toml +106 -0
  5. grounded_memory-0.1.0/setup.cfg +4 -0
  6. grounded_memory-0.1.0/src/gmem/__init__.py +35 -0
  7. grounded_memory-0.1.0/src/gmem/service.py +5 -0
  8. grounded_memory-0.1.0/src/grounded_memory/__init__.py +114 -0
  9. grounded_memory-0.1.0/src/grounded_memory/adapters/__init__.py +46 -0
  10. grounded_memory-0.1.0/src/grounded_memory/adapters/base_agent.py +55 -0
  11. grounded_memory-0.1.0/src/grounded_memory/adapters/discovery.py +251 -0
  12. grounded_memory-0.1.0/src/grounded_memory/adapters/generic_agent.py +783 -0
  13. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/__init__.py +95 -0
  14. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/agent.py +121 -0
  15. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/constraints.py +471 -0
  16. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/extractor.py +424 -0
  17. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/kb_manager.py +207 -0
  18. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/knowledge.py +403 -0
  19. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/lifecycle.py +138 -0
  20. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/loaders/__init__.py +16 -0
  21. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/loaders/cache.py +219 -0
  22. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/loaders/openfda.py +172 -0
  23. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/loaders/rxnorm.py +206 -0
  24. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/models.py +129 -0
  25. grounded_memory-0.1.0/src/grounded_memory/adapters/healthcare/retrieval.py +788 -0
  26. grounded_memory-0.1.0/src/grounded_memory/adapters/identity_service.py +103 -0
  27. grounded_memory-0.1.0/src/grounded_memory/adapters/registry.py +215 -0
  28. grounded_memory-0.1.0/src/grounded_memory/adapters/result.py +20 -0
  29. grounded_memory-0.1.0/src/grounded_memory/adapters/seeds.py +322 -0
  30. grounded_memory-0.1.0/src/grounded_memory/configs/engineering_constraints.yaml +187 -0
  31. grounded_memory-0.1.0/src/grounded_memory/configs/finance_constraints.yaml +175 -0
  32. grounded_memory-0.1.0/src/grounded_memory/configs/generic_constraints.yaml +174 -0
  33. grounded_memory-0.1.0/src/grounded_memory/configs/healthcare_constraints.yaml +282 -0
  34. grounded_memory-0.1.0/src/grounded_memory/configs/healthcare_kb.yaml +126 -0
  35. grounded_memory-0.1.0/src/grounded_memory/configs/legal_constraints.yaml +182 -0
  36. grounded_memory-0.1.0/src/grounded_memory/configs/llm_config.yaml +50 -0
  37. grounded_memory-0.1.0/src/grounded_memory/configs/neo4j_config.yaml +44 -0
  38. grounded_memory-0.1.0/src/grounded_memory/core/__init__.py +122 -0
  39. grounded_memory-0.1.0/src/grounded_memory/core/conflict_resolution.py +323 -0
  40. grounded_memory-0.1.0/src/grounded_memory/core/constraints.py +1022 -0
  41. grounded_memory-0.1.0/src/grounded_memory/core/entity_identity.py +62 -0
  42. grounded_memory-0.1.0/src/grounded_memory/core/grounding.py +722 -0
  43. grounded_memory-0.1.0/src/grounded_memory/core/hybrid_store.py +342 -0
  44. grounded_memory-0.1.0/src/grounded_memory/core/intent.py +342 -0
  45. grounded_memory-0.1.0/src/grounded_memory/core/models.py +474 -0
  46. grounded_memory-0.1.0/src/grounded_memory/core/neo4j_store.py +1124 -0
  47. grounded_memory-0.1.0/src/grounded_memory/core/postgres_hybrid_store.py +264 -0
  48. grounded_memory-0.1.0/src/grounded_memory/core/postgres_store.py +1505 -0
  49. grounded_memory-0.1.0/src/grounded_memory/core/store.py +548 -0
  50. grounded_memory-0.1.0/src/grounded_memory/core/system.py +133 -0
  51. grounded_memory-0.1.0/src/grounded_memory/core/tuple_normalization.py +176 -0
  52. grounded_memory-0.1.0/src/grounded_memory/llm/__init__.py +52 -0
  53. grounded_memory-0.1.0/src/grounded_memory/llm/client.py +558 -0
  54. grounded_memory-0.1.0/src/grounded_memory/llm/extractor.py +72 -0
  55. grounded_memory-0.1.0/src/grounded_memory/llm/prompts.py +437 -0
  56. grounded_memory-0.1.0/src/grounded_memory/logging_utils.py +60 -0
  57. grounded_memory-0.1.0/src/grounded_memory/memory.py +2267 -0
  58. grounded_memory-0.1.0/src/grounded_memory/retrieval/__init__.py +17 -0
  59. grounded_memory-0.1.0/src/grounded_memory/retrieval/graph.py +1474 -0
  60. grounded_memory-0.1.0/src/grounded_memory/service/__init__.py +5 -0
  61. grounded_memory-0.1.0/src/grounded_memory/service/app.py +331 -0
  62. grounded_memory-0.1.0/src/grounded_memory/service/models.py +130 -0
  63. grounded_memory-0.1.0/src/grounded_memory/system.py +106 -0
  64. grounded_memory-0.1.0/src/grounded_memory.egg-info/PKG-INFO +305 -0
  65. grounded_memory-0.1.0/src/grounded_memory.egg-info/SOURCES.txt +74 -0
  66. grounded_memory-0.1.0/src/grounded_memory.egg-info/dependency_links.txt +1 -0
  67. grounded_memory-0.1.0/src/grounded_memory.egg-info/requires.txt +34 -0
  68. grounded_memory-0.1.0/src/grounded_memory.egg-info/top_level.txt +2 -0
  69. grounded_memory-0.1.0/tests/test_adapters.py +290 -0
  70. grounded_memory-0.1.0/tests/test_end_to_end.py +443 -0
  71. grounded_memory-0.1.0/tests/test_governance.py +574 -0
  72. grounded_memory-0.1.0/tests/test_healthcare_reconciliation.py +372 -0
  73. grounded_memory-0.1.0/tests/test_healthcare_retrieval.py +676 -0
  74. grounded_memory-0.1.0/tests/test_hybrid_storage.py +563 -0
  75. grounded_memory-0.1.0/tests/test_memory_layer.py +58 -0
  76. grounded_memory-0.1.0/tests/test_postgres_storage.py +122 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Faycal & Marouane
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,305 @@
1
+ Metadata-Version: 2.4
2
+ Name: grounded-memory
3
+ Version: 0.1.0
4
+ Summary: Correctness-First Structured Memory Layer for LLM Agents
5
+ Author: Faycal & Marouane
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://github.com/marouaneoa/GroundedMemory
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: pydantic>=2.0
21
+ Requires-Dist: typing-extensions>=4.14.1
22
+ Requires-Dist: python-dateutil>=2.8
23
+ Requires-Dist: python-dotenv>=1.0
24
+ Requires-Dist: pyyaml>=6.0
25
+ Requires-Dist: networkx>=3.0
26
+ Requires-Dist: rich>=13.0
27
+ Requires-Dist: httpx>=0.25.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: black>=24.0; extra == "dev"
30
+ Requires-Dist: pytest>=7.0; extra == "dev"
31
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
32
+ Requires-Dist: ruff>=0.6.0; extra == "dev"
33
+ Provides-Extra: llm
34
+ Requires-Dist: pydantic-ai>=1.0; extra == "llm"
35
+ Provides-Extra: api
36
+ Requires-Dist: fastapi>=0.116.0; extra == "api"
37
+ Requires-Dist: uvicorn>=0.35.0; extra == "api"
38
+ Provides-Extra: benchmark
39
+ Requires-Dist: datasets<3.0.0,>=2.19.0; extra == "benchmark"
40
+ Provides-Extra: postgres
41
+ Requires-Dist: asyncpg>=0.29.0; extra == "postgres"
42
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == "postgres"
43
+ Provides-Extra: neo4j
44
+ Requires-Dist: neo4j>=5.0.0; extra == "neo4j"
45
+ Provides-Extra: all
46
+ Requires-Dist: grounded-memory[api,benchmark,dev,llm,neo4j,postgres]; extra == "all"
47
+ Dynamic: license-file
48
+
49
+ <p align="center">
50
+ <img src="assets/gmem-logo.svg" alt="gmem" width="860" />
51
+ </p>
52
+
53
+ <p align="center">
54
+ <strong>gmem</strong> is a correctness-first memory runtime for LLM agents.<br/>
55
+ It stores only grounded facts, keeps temporal history, and stays adapter-driven instead of usecase-coupled.
56
+ </p>
57
+
58
+ ---
59
+
60
+ ## Why gmem
61
+
62
+ Most memory layers optimize retrieval speed first.
63
+ gmem optimizes correctness first:
64
+
65
+ - candidate tuples are proposed by the LLM
66
+ - constraints validate before persistence
67
+ - accepted facts become durable memory with supersession
68
+ - retrieval builds compact context from governed state
69
+
70
+ ## Core Model
71
+
72
+ gmem keeps six objects explicit:
73
+
74
+ 1. `Interaction` (immutable observed event)
75
+ 2. `Entity` (symbolic anchor)
76
+ 3. `CandidateFact` (untrusted proposal)
77
+ 4. `ValidatedFact` (accepted fact with valid-time boundaries)
78
+ 5. `Constraint` (write-time governance)
79
+ 6. `AnswerContext` (ephemeral retrieval view)
80
+
81
+ ## Quick Start
82
+
83
+ Install:
84
+
85
+ ```bash
86
+ pip install -e .[llm]
87
+ ```
88
+
89
+ Minimal usage:
90
+
91
+ ```python
92
+ from gmem import Memory
93
+
94
+ memory = Memory(adapter="generic", storage_backend="memory")
95
+
96
+ memory.add("My project codename is Atlas.", user_id="demo")
97
+ results = memory.search("What is my project codename?", user_id="demo", limit=3)
98
+
99
+ print(results)
100
+ memory.close()
101
+ ```
102
+
103
+ Intent routing (auto-classify and route natural-language input):
104
+
105
+ ```python
106
+ from gmem import Memory
107
+
108
+ memory = Memory(adapter="generic", storage_backend="memory")
109
+
110
+ # Explicit intent classification
111
+ intent = memory.route("What is my project codename?")
112
+ print(intent.action) # "recall"
113
+
114
+ # Auto-routing: REMEMBER -> add(), RECALL -> search(), etc.
115
+ result = memory.process("My project codename is Atlas.", user_id="demo")
116
+ print(result["intent"]["action"]) # "remember"
117
+
118
+ memory.close()
119
+ ```
120
+
121
+ ## OpenRouter Setup
122
+
123
+ In `.env`:
124
+
125
+ ```bash
126
+ LLM_PROVIDER=openrouter
127
+ LLM_MODEL=z-ai/glm-4.5-air:free
128
+ OPENROUTER_API_KEY=...
129
+ ```
130
+
131
+ Quick API smoke check:
132
+
133
+ ```bash
134
+ make smoke-openrouter
135
+ ```
136
+
137
+ ## Local Dev UX
138
+
139
+ Start databases:
140
+
141
+ ```bash
142
+ make services-up
143
+ ```
144
+
145
+ Stop databases:
146
+
147
+ ```bash
148
+ make services-down
149
+ ```
150
+
151
+ Run memory smoke behavior test:
152
+
153
+ ```bash
154
+ make smoke-memory
155
+ ```
156
+
157
+ Run deterministic hybrid write + backend inspection (in-memory facts, Neo4j graph, PostgreSQL counts):
158
+
159
+ ```bash
160
+ make inspect-backends
161
+ ```
162
+
163
+ Run the healthcare medication-reconciliation demo stack:
164
+
165
+ ```bash
166
+ make services-up
167
+ PYTHONPATH=src python demos/demo_bitemporal.py
168
+ ```
169
+
170
+ Then query the same data interactively (scope values match automatically):
171
+
172
+ ```bash
173
+ PYTHONPATH=src python demos/demo_interactive.py --adapter healthcare
174
+ ```
175
+
176
+ > **Scope alignment note:** Both demos use `require_scope=True` by default. Facts are tagged with scope fields (`tenant_id`, `app_id`, `user_id`, `agent_id`, `run_id`). To query data written by one demo from another, the scope values must match. The demos share default scope values so they align automatically; override with `--user-id`, `--agent-id`, `--run-id`, or env vars (`GM_SCOPE_*`) if needed.
177
+
178
+ Run the Postgres + Neo4j healthcare smoke check:
179
+
180
+ ```bash
181
+ make smoke-healthcare-backends
182
+ ```
183
+
184
+ ## Adapter-Decoupled Runtime
185
+
186
+ The runtime is no longer tied to repository `usecases/` trees.
187
+
188
+ - `GM_ADAPTER` selects behavior profile (default: `generic`)
189
+ - adapters are registered via runtime adapter registry APIs
190
+ - `domain_profile` remains as compatibility alias in the API
191
+ - experiment-stage labels for research ablations stay in the sibling [ClinicaLongMem-Interact](../ClinicaLongMem-Interact/) benchmark repository and docs, not as hardcoded runtime stage classes
192
+
193
+ ## Engineering Workflow
194
+
195
+ - contribution guide: [CONTRIBUTING.md](CONTRIBUTING.md)
196
+ - development conventions: [DEVELOPING.md](DEVELOPING.md)
197
+
198
+ ## API Stability
199
+
200
+ Stable entry points:
201
+
202
+ - `gmem` facade imports
203
+ - `grounded_memory.memory.Memory` SDK facade
204
+ - FastAPI service endpoints under `grounded_memory.service`
205
+
206
+ Internal modules may evolve faster as research and storage internals iterate.
207
+
208
+ ## Repository Layout
209
+
210
+ ```text
211
+ src/
212
+ gmem/ # facade package
213
+ grounded_memory/ # implementation runtime
214
+ adapters/ # adapter registry + generic agent
215
+ core/ # models, constraints, stores
216
+ llm/ # LLM client + extraction
217
+ retrieval/ # graph retrieval
218
+ service/ # FastAPI service layer
219
+
220
+ assets/ # brand and diagram assets
221
+ demos/ # runnable demos and showcase scripts
222
+ tests/ # regression tests
223
+ configs/ # runtime yaml configs
224
+ scripts/ # operational and migration scripts
225
+ docs/
226
+ architecture/ # architecture and roadmap docs
227
+ sdk/ # SDK reference docs
228
+ ```
229
+
230
+ Benchmark runners, scenarios, and evaluation scripts live in the sibling repository [ClinicaLongMem-Interact](../ClinicaLongMem-Interact/).
231
+
232
+ ## Compose Stack
233
+
234
+ The compose stack is intentionally simple:
235
+
236
+ - PostgreSQL: source of truth store
237
+ - Neo4j: active graph projection
238
+
239
+ Configured via [docker-compose.yml](docker-compose.yml) and [.env.example](.env.example).
240
+
241
+ ## Demos
242
+
243
+ | Demo | Command | What it shows |
244
+ |---|---|---|
245
+ | **Bitemporal medication reconciliation** | `python demos/demo_bitemporal.py` | Write-time constraints, supersession, discontinuation, current + historical retrieval |
246
+ | **Multi-patient write** | `python demos/demo_multi_patient_write.py` | Scale write-phase with 10 patients, allergy/interaction rejection |
247
+ | **Multi-patient retrieval** | `python demos/demo_multi_patient_retrieval.py` | Cross-patient isolation, shared entity queries, historical as-of |
248
+ | **Interactive REPL** | `python demos/demo_interactive.py --adapter healthcare` | Intent routing, auto-routing of natural language, real-time grounding diagnostics |
249
+ | **OpenRouter system** | `python demos/demo_openrouter.py` | Full OpenRouter pipeline with extraction, grounding, and retrieval |
250
+
251
+ ## Tests
252
+
253
+ Run all regression tests:
254
+
255
+ ```bash
256
+ pytest tests/ -q
257
+ ```
258
+
259
+ Key test suites:
260
+
261
+ | Test file | Coverage |
262
+ |---|---|
263
+ | `tests/test_governance.py` | Supersession, duplicate detection, conflict resolution strategies, constraint enforcement |
264
+ | `tests/test_healthcare_reconciliation.py` | Allergy conflict, drug interaction, therapeutic duplication, dose supersession |
265
+ | `tests/test_healthcare_retrieval.py` | Retrieval planning, seed resolution, discontinuation closure, historical as-of, scope isolation |
266
+ | `tests/test_end_to_end.py` | Engineering knowledge graph, multi-domain facts, constraint rejection with audit trail |
267
+ | `tests/test_adapters.py` | Adapter registry, YAML constraint configs, entity/relation type coverage |
268
+
269
+ ## Healthcare Demo
270
+
271
+ The demo uses the healthcare adapter with PostgreSQL as the durable
272
+ bitemporal store and Neo4j as the active graph projection:
273
+
274
+ ```python
275
+ Memory(
276
+ adapter="healthcare",
277
+ storage_backend="postgres_hybrid",
278
+ require_scope=True,
279
+ )
280
+ ```
281
+
282
+ It demonstrates LLM-backed clinical extraction, write-time safety constraints,
283
+ allergy/interaction rejections, dose supersession, discontinuation lifecycle
284
+ closure, current retrieval, and historical as-of retrieval.
285
+
286
+ ## Academic Direction
287
+
288
+ The current roadmap emphasizes novelty around:
289
+
290
+ - bitemporal memory semantics for grounded tuples
291
+ - constraint lifecycle governance (`proposed -> shadow -> active -> deprecated`)
292
+ - adapter-level safety policies without domain hard-coding into core memory runtime
293
+
294
+ See [docs/architecture/ARCHITECTURE.md](docs/architecture/ARCHITECTURE.md) for
295
+ the implementation-aligned architecture and
296
+ [docs/architecture/GMEM_V2_BLUEPRINT.md](docs/architecture/GMEM_V2_BLUEPRINT.md)
297
+ for the broader roadmap.
298
+
299
+ ## Status
300
+
301
+ This repository is under active demo development.
302
+
303
+ ## License
304
+
305
+ MIT
@@ -0,0 +1,257 @@
1
+ <p align="center">
2
+ <img src="assets/gmem-logo.svg" alt="gmem" width="860" />
3
+ </p>
4
+
5
+ <p align="center">
6
+ <strong>gmem</strong> is a correctness-first memory runtime for LLM agents.<br/>
7
+ It stores only grounded facts, keeps temporal history, and stays adapter-driven instead of usecase-coupled.
8
+ </p>
9
+
10
+ ---
11
+
12
+ ## Why gmem
13
+
14
+ Most memory layers optimize retrieval speed first.
15
+ gmem optimizes correctness first:
16
+
17
+ - candidate tuples are proposed by the LLM
18
+ - constraints validate before persistence
19
+ - accepted facts become durable memory with supersession
20
+ - retrieval builds compact context from governed state
21
+
22
+ ## Core Model
23
+
24
+ gmem keeps six objects explicit:
25
+
26
+ 1. `Interaction` (immutable observed event)
27
+ 2. `Entity` (symbolic anchor)
28
+ 3. `CandidateFact` (untrusted proposal)
29
+ 4. `ValidatedFact` (accepted fact with valid-time boundaries)
30
+ 5. `Constraint` (write-time governance)
31
+ 6. `AnswerContext` (ephemeral retrieval view)
32
+
33
+ ## Quick Start
34
+
35
+ Install:
36
+
37
+ ```bash
38
+ pip install -e .[llm]
39
+ ```
40
+
41
+ Minimal usage:
42
+
43
+ ```python
44
+ from gmem import Memory
45
+
46
+ memory = Memory(adapter="generic", storage_backend="memory")
47
+
48
+ memory.add("My project codename is Atlas.", user_id="demo")
49
+ results = memory.search("What is my project codename?", user_id="demo", limit=3)
50
+
51
+ print(results)
52
+ memory.close()
53
+ ```
54
+
55
+ Intent routing (auto-classify and route natural-language input):
56
+
57
+ ```python
58
+ from gmem import Memory
59
+
60
+ memory = Memory(adapter="generic", storage_backend="memory")
61
+
62
+ # Explicit intent classification
63
+ intent = memory.route("What is my project codename?")
64
+ print(intent.action) # "recall"
65
+
66
+ # Auto-routing: REMEMBER -> add(), RECALL -> search(), etc.
67
+ result = memory.process("My project codename is Atlas.", user_id="demo")
68
+ print(result["intent"]["action"]) # "remember"
69
+
70
+ memory.close()
71
+ ```
72
+
73
+ ## OpenRouter Setup
74
+
75
+ In `.env`:
76
+
77
+ ```bash
78
+ LLM_PROVIDER=openrouter
79
+ LLM_MODEL=z-ai/glm-4.5-air:free
80
+ OPENROUTER_API_KEY=...
81
+ ```
82
+
83
+ Quick API smoke check:
84
+
85
+ ```bash
86
+ make smoke-openrouter
87
+ ```
88
+
89
+ ## Local Dev UX
90
+
91
+ Start databases:
92
+
93
+ ```bash
94
+ make services-up
95
+ ```
96
+
97
+ Stop databases:
98
+
99
+ ```bash
100
+ make services-down
101
+ ```
102
+
103
+ Run memory smoke behavior test:
104
+
105
+ ```bash
106
+ make smoke-memory
107
+ ```
108
+
109
+ Run deterministic hybrid write + backend inspection (in-memory facts, Neo4j graph, PostgreSQL counts):
110
+
111
+ ```bash
112
+ make inspect-backends
113
+ ```
114
+
115
+ Run the healthcare medication-reconciliation demo stack:
116
+
117
+ ```bash
118
+ make services-up
119
+ PYTHONPATH=src python demos/demo_bitemporal.py
120
+ ```
121
+
122
+ Then query the same data interactively (scope values match automatically):
123
+
124
+ ```bash
125
+ PYTHONPATH=src python demos/demo_interactive.py --adapter healthcare
126
+ ```
127
+
128
+ > **Scope alignment note:** Both demos use `require_scope=True` by default. Facts are tagged with scope fields (`tenant_id`, `app_id`, `user_id`, `agent_id`, `run_id`). To query data written by one demo from another, the scope values must match. The demos share default scope values so they align automatically; override with `--user-id`, `--agent-id`, `--run-id`, or env vars (`GM_SCOPE_*`) if needed.
129
+
130
+ Run the Postgres + Neo4j healthcare smoke check:
131
+
132
+ ```bash
133
+ make smoke-healthcare-backends
134
+ ```
135
+
136
+ ## Adapter-Decoupled Runtime
137
+
138
+ The runtime is no longer tied to repository `usecases/` trees.
139
+
140
+ - `GM_ADAPTER` selects behavior profile (default: `generic`)
141
+ - adapters are registered via runtime adapter registry APIs
142
+ - `domain_profile` remains as compatibility alias in the API
143
+ - experiment-stage labels for research ablations stay in the sibling [ClinicaLongMem-Interact](../ClinicaLongMem-Interact/) benchmark repository and docs, not as hardcoded runtime stage classes
144
+
145
+ ## Engineering Workflow
146
+
147
+ - contribution guide: [CONTRIBUTING.md](CONTRIBUTING.md)
148
+ - development conventions: [DEVELOPING.md](DEVELOPING.md)
149
+
150
+ ## API Stability
151
+
152
+ Stable entry points:
153
+
154
+ - `gmem` facade imports
155
+ - `grounded_memory.memory.Memory` SDK facade
156
+ - FastAPI service endpoints under `grounded_memory.service`
157
+
158
+ Internal modules may evolve faster as research and storage internals iterate.
159
+
160
+ ## Repository Layout
161
+
162
+ ```text
163
+ src/
164
+ gmem/ # facade package
165
+ grounded_memory/ # implementation runtime
166
+ adapters/ # adapter registry + generic agent
167
+ core/ # models, constraints, stores
168
+ llm/ # LLM client + extraction
169
+ retrieval/ # graph retrieval
170
+ service/ # FastAPI service layer
171
+
172
+ assets/ # brand and diagram assets
173
+ demos/ # runnable demos and showcase scripts
174
+ tests/ # regression tests
175
+ configs/ # runtime yaml configs
176
+ scripts/ # operational and migration scripts
177
+ docs/
178
+ architecture/ # architecture and roadmap docs
179
+ sdk/ # SDK reference docs
180
+ ```
181
+
182
+ Benchmark runners, scenarios, and evaluation scripts live in the sibling repository [ClinicaLongMem-Interact](../ClinicaLongMem-Interact/).
183
+
184
+ ## Compose Stack
185
+
186
+ The compose stack is intentionally simple:
187
+
188
+ - PostgreSQL: source of truth store
189
+ - Neo4j: active graph projection
190
+
191
+ Configured via [docker-compose.yml](docker-compose.yml) and [.env.example](.env.example).
192
+
193
+ ## Demos
194
+
195
+ | Demo | Command | What it shows |
196
+ |---|---|---|
197
+ | **Bitemporal medication reconciliation** | `python demos/demo_bitemporal.py` | Write-time constraints, supersession, discontinuation, current + historical retrieval |
198
+ | **Multi-patient write** | `python demos/demo_multi_patient_write.py` | Scale write-phase with 10 patients, allergy/interaction rejection |
199
+ | **Multi-patient retrieval** | `python demos/demo_multi_patient_retrieval.py` | Cross-patient isolation, shared entity queries, historical as-of |
200
+ | **Interactive REPL** | `python demos/demo_interactive.py --adapter healthcare` | Intent routing, auto-routing of natural language, real-time grounding diagnostics |
201
+ | **OpenRouter system** | `python demos/demo_openrouter.py` | Full OpenRouter pipeline with extraction, grounding, and retrieval |
202
+
203
+ ## Tests
204
+
205
+ Run all regression tests:
206
+
207
+ ```bash
208
+ pytest tests/ -q
209
+ ```
210
+
211
+ Key test suites:
212
+
213
+ | Test file | Coverage |
214
+ |---|---|
215
+ | `tests/test_governance.py` | Supersession, duplicate detection, conflict resolution strategies, constraint enforcement |
216
+ | `tests/test_healthcare_reconciliation.py` | Allergy conflict, drug interaction, therapeutic duplication, dose supersession |
217
+ | `tests/test_healthcare_retrieval.py` | Retrieval planning, seed resolution, discontinuation closure, historical as-of, scope isolation |
218
+ | `tests/test_end_to_end.py` | Engineering knowledge graph, multi-domain facts, constraint rejection with audit trail |
219
+ | `tests/test_adapters.py` | Adapter registry, YAML constraint configs, entity/relation type coverage |
220
+
221
+ ## Healthcare Demo
222
+
223
+ The demo uses the healthcare adapter with PostgreSQL as the durable
224
+ bitemporal store and Neo4j as the active graph projection:
225
+
226
+ ```python
227
+ Memory(
228
+ adapter="healthcare",
229
+ storage_backend="postgres_hybrid",
230
+ require_scope=True,
231
+ )
232
+ ```
233
+
234
+ It demonstrates LLM-backed clinical extraction, write-time safety constraints,
235
+ allergy/interaction rejections, dose supersession, discontinuation lifecycle
236
+ closure, current retrieval, and historical as-of retrieval.
237
+
238
+ ## Academic Direction
239
+
240
+ The current roadmap emphasizes novelty around:
241
+
242
+ - bitemporal memory semantics for grounded tuples
243
+ - constraint lifecycle governance (`proposed -> shadow -> active -> deprecated`)
244
+ - adapter-level safety policies without domain hard-coding into core memory runtime
245
+
246
+ See [docs/architecture/ARCHITECTURE.md](docs/architecture/ARCHITECTURE.md) for
247
+ the implementation-aligned architecture and
248
+ [docs/architecture/GMEM_V2_BLUEPRINT.md](docs/architecture/GMEM_V2_BLUEPRINT.md)
249
+ for the broader roadmap.
250
+
251
+ ## Status
252
+
253
+ This repository is under active demo development.
254
+
255
+ ## License
256
+
257
+ MIT
@@ -0,0 +1,106 @@
1
+ [project]
2
+ name = "grounded-memory"
3
+ version = "0.1.0"
4
+ description = "Correctness-First Structured Memory Layer for LLM Agents"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ license = "MIT"
8
+ authors = [
9
+ {name = "Faycal & Marouane"}
10
+ ]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Intended Audience :: Developers",
14
+ "Intended Audience :: Science/Research",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
21
+ ]
22
+
23
+ dependencies = [
24
+ "pydantic>=2.0",
25
+ "typing-extensions>=4.14.1",
26
+ "python-dateutil>=2.8",
27
+ "python-dotenv>=1.0",
28
+ "pyyaml>=6.0",
29
+ "networkx>=3.0",
30
+ "rich>=13.0",
31
+ "httpx>=0.25.0",
32
+ ]
33
+
34
+ [project.urls]
35
+ Repository = "https://github.com/marouaneoa/GroundedMemory"
36
+
37
+ [project.optional-dependencies]
38
+ dev = [
39
+ "black>=24.0",
40
+ "pytest>=7.0",
41
+ "pytest-asyncio>=0.21",
42
+ "ruff>=0.6.0",
43
+ ]
44
+ llm = [
45
+ "pydantic-ai>=1.0",
46
+ ]
47
+ api = [
48
+ "fastapi>=0.116.0",
49
+ "uvicorn>=0.35.0",
50
+ ]
51
+ benchmark = [
52
+ "datasets>=2.19.0,<3.0.0",
53
+ ]
54
+ postgres = [
55
+ "asyncpg>=0.29.0",
56
+ "psycopg2-binary>=2.9.0",
57
+ ]
58
+ neo4j = [
59
+ "neo4j>=5.0.0",
60
+ ]
61
+ all = [
62
+ "grounded-memory[dev,llm,api,benchmark,postgres,neo4j]",
63
+ ]
64
+
65
+ [build-system]
66
+ requires = ["setuptools>=61.0"]
67
+ build-backend = "setuptools.build_meta"
68
+
69
+ [tool.setuptools.packages.find]
70
+ where = ["src"]
71
+
72
+ [tool.setuptools.package-data]
73
+ "grounded_memory.configs" = ["*.yaml"]
74
+
75
+ [tool.black]
76
+ line-length = 100
77
+ target-version = ["py310"]
78
+
79
+ [tool.ruff]
80
+ line-length = 100
81
+ target-version = "py310"
82
+ src = ["src", "tests", "demos", "scripts"]
83
+
84
+ [tool.pytest.ini_options]
85
+ testpaths = ["tests"]
86
+ pythonpath = ["src"]
87
+
88
+ [tool.ruff.lint]
89
+ select = [
90
+ "E",
91
+ "F",
92
+ "I",
93
+ "B",
94
+ "UP",
95
+ "SIM",
96
+ ]
97
+ ignore = [
98
+ "E501",
99
+ ]
100
+
101
+ [tool.ruff.lint.isort]
102
+ known-first-party = ["grounded_memory", "gmem"]
103
+
104
+ [tool.ruff.format]
105
+ quote-style = "double"
106
+ indent-style = "space"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+