graph-mind-memory 0.1.0__tar.gz → 0.1.2__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 (51) hide show
  1. {graph_mind_memory-0.1.0/graph_mind_memory.egg-info → graph_mind_memory-0.1.2}/PKG-INFO +22 -5
  2. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/README.md +20 -3
  3. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/brain_log.py +8 -2
  4. graph_mind_memory-0.1.2/clock.py +19 -0
  5. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/coding_memory.py +1 -1
  6. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/conversation_memory.py +1 -1
  7. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/development_memory.py +1 -1
  8. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2/graph_mind_memory.egg-info}/PKG-INFO +22 -5
  9. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/graph_mind_memory.egg-info/SOURCES.txt +2 -18
  10. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/graph_mind_memory.egg-info/requires.txt +3 -1
  11. graph_mind_memory-0.1.2/graph_mind_memory.egg-info/top_level.txt +21 -0
  12. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/install.py +8 -5
  13. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/local_brain.py +1 -1
  14. graph_mind_memory-0.1.2/local_embedder.py +112 -0
  15. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/pyproject.toml +7 -22
  16. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/semantic_recall.py +1 -1
  17. graph_mind_memory-0.1.0/concept_plan_benchmark_v071.py +0 -248
  18. graph_mind_memory-0.1.0/executable_memory.py +0 -312
  19. graph_mind_memory-0.1.0/executable_plan_v2_diagnostic.py +0 -272
  20. graph_mind_memory-0.1.0/graph_mind_memory.egg-info/top_level.txt +0 -37
  21. graph_mind_memory-0.1.0/grounded_concept_bridge_v072.py +0 -511
  22. graph_mind_memory-0.1.0/ingestion_gate.py +0 -113
  23. graph_mind_memory-0.1.0/ingestion_synonyms.py +0 -165
  24. graph_mind_memory-0.1.0/llm_concept_planner.py +0 -170
  25. graph_mind_memory-0.1.0/longmemeval_adapter.py +0 -120
  26. graph_mind_memory-0.1.0/longmemeval_ingestion_calibration.py +0 -366
  27. graph_mind_memory-0.1.0/longmemeval_ingestion_preflight.py +0 -188
  28. graph_mind_memory-0.1.0/longmemeval_ingestion_v7.py +0 -356
  29. graph_mind_memory-0.1.0/memory_algebra.py +0 -155
  30. graph_mind_memory-0.1.0/memory_contract.py +0 -154
  31. graph_mind_memory-0.1.0/memory_normalization.py +0 -13
  32. graph_mind_memory-0.1.0/memory_vocabulary.py +0 -34
  33. graph_mind_memory-0.1.0/semantic_grounding_v073.py +0 -501
  34. graph_mind_memory-0.1.0/state_relation_contract.py +0 -158
  35. graph_mind_memory-0.1.0/temporal_state.py +0 -210
  36. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/LICENSE +0 -0
  37. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/associative_memory.py +0 -0
  38. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/automatic_capture.py +0 -0
  39. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/automatic_capture_cli.py +0 -0
  40. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/development_paths.py +0 -0
  41. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/embedding_warmup.py +0 -0
  42. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/entity_timeline.py +0 -0
  43. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/graph_mind_mcp_server.py +0 -0
  44. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/graph_mind_memory.egg-info/dependency_links.txt +0 -0
  45. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/graph_mind_memory.egg-info/entry_points.txt +0 -0
  46. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/semantic_llm_extractor.py +0 -0
  47. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/semantic_memory.py +0 -0
  48. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/setup.cfg +0 -0
  49. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/temporal_resolver.py +0 -0
  50. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/universal_personal_memory.py +0 -0
  51. {graph_mind_memory-0.1.0 → graph_mind_memory-0.1.2}/vector_cache.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graph-mind-memory
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Local-first memory for AI coding assistants: verbatim, on your own PC, no LLM calls at write time.
5
5
  Author-email: Yohan Ko <goyohan0611@gmail.com>
6
6
  License-Expression: AGPL-3.0-only
@@ -18,7 +18,7 @@ Requires-Dist: mcp<3,>=2
18
18
  Requires-Dist: numpy
19
19
  Requires-Dist: transformers
20
20
  Requires-Dist: tiktoken
21
- Requires-Dist: pgserver
21
+ Requires-Dist: pgserver; python_version < "3.13"
22
22
  Requires-Dist: psycopg[binary]
23
23
  Requires-Dist: psutil
24
24
  Requires-Dist: fasteners
@@ -37,6 +37,7 @@ Local-first memory for AI coding assistants. Verbatim storage, on your own PC:
37
37
  [![][platform-shield]][platform-link]
38
38
  [![][longmemeval-shield]][benchmarks-link]
39
39
  [![][ci-shield]][ci-link]
40
+ [![][pypi-shield]][pypi-link]
40
41
 
41
42
  *Switch models; keep the memory.*
42
43
 
@@ -107,7 +108,9 @@ saves them. Graph-MIND does not.
107
108
 
108
109
  ## Install
109
110
 
110
- Requires Python 3.10+ (64-bit). Windows, macOS or Linux.
111
+ Requires Python 3.10+ (64-bit). Windows, macOS or Linux. Hosting a brain that other PCs join
112
+ needs Python 3.12 or older on that one PC (its Postgres helper, pgserver, has no newer build yet);
113
+ everything else, joining included, works on 3.13 and 3.14 too.
111
114
 
112
115
  ```bash
113
116
  pip install graph-mind-memory
@@ -131,7 +134,8 @@ The installer:
131
134
  autostart entry on Linux);
132
135
  - downloads the embedding model.
133
136
 
134
- Then restart your AI apps. Running the installer again is safe. Run it again if you move the folder.
137
+ Then restart your AI apps. The server is also listed in the
138
+ [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.goyohan0611-png/graph-mind`. Running the installer again is safe. Run it again if you move the folder.
135
139
 
136
140
  > [!TIP]
137
141
  > If `pip` fails with "No such file or directory", Windows' 260-character path limit is the usual
@@ -224,10 +228,21 @@ python -m unittest discover -p "test_*.py"
224
228
  can stop capture until Graph-MIND is updated.
225
229
  - **Multi-session questions are the weakest type at 80%.** These are questions that count or
226
230
  combine facts across many conversations.
227
- - **The code base still carries modules from the research phase.** It will be slimmed down.
231
+ - **The repository still holds the research-phase experiments** next to the product (see
232
+ [Repository layout](#repository-layout)); the installed package carries only the 21 product
233
+ modules.
228
234
 
229
235
  The full list is in [REPORT.md §9](REPORT.md#9-known-limits).
230
236
 
237
+ ## Repository layout
238
+
239
+ | | files |
240
+ |---|---|
241
+ | **Product** (what `pip install graph-mind-memory` installs) | `graph_mind_mcp_server.py` (MCP server), `automatic_capture*.py` (capture service), `install.py`, `brain_log.py` (sharing across PCs), `local_brain.py` / `conversation_memory.py` / `coding_memory.py` / `development_memory.py` (stores), `semantic_recall.py` / `local_embedder.py` / `vector_cache.py` / `embedding_warmup.py` (search), and their helpers |
242
+ | **Benchmarks** | `product_answer_eval.py`, `official_judge_v073.py`, `rival_mem0.py`, `rival_mempalace.py`, `rival_clean_prereg.py`, and the result files under `runs/` |
243
+ | **Research phase** | the other modules: earlier extraction pipelines and analyses that REPORT.md cites |
244
+ | **Tests** | `test_*.py` |
245
+
231
246
  ## Contributing
232
247
 
233
248
  Issues and pull requests are welcome. Contributions are accepted under the [CLA](CLA.md), which
@@ -250,3 +265,5 @@ available for products that cannot.
250
265
  [benchmarks-link]: #benchmarks
251
266
  [ci-shield]: https://img.shields.io/github/actions/workflow/status/goyohan0611-png/graph-mind/tests.yml?style=flat-square&label=tests
252
267
  [ci-link]: https://github.com/goyohan0611-png/graph-mind/actions/workflows/tests.yml
268
+ [pypi-shield]: https://img.shields.io/pypi/v/graph-mind-memory?style=flat-square&label=pypi
269
+ [pypi-link]: https://pypi.org/project/graph-mind-memory/
@@ -11,6 +11,7 @@ Local-first memory for AI coding assistants. Verbatim storage, on your own PC:
11
11
  [![][platform-shield]][platform-link]
12
12
  [![][longmemeval-shield]][benchmarks-link]
13
13
  [![][ci-shield]][ci-link]
14
+ [![][pypi-shield]][pypi-link]
14
15
 
15
16
  *Switch models; keep the memory.*
16
17
 
@@ -81,7 +82,9 @@ saves them. Graph-MIND does not.
81
82
 
82
83
  ## Install
83
84
 
84
- Requires Python 3.10+ (64-bit). Windows, macOS or Linux.
85
+ Requires Python 3.10+ (64-bit). Windows, macOS or Linux. Hosting a brain that other PCs join
86
+ needs Python 3.12 or older on that one PC (its Postgres helper, pgserver, has no newer build yet);
87
+ everything else, joining included, works on 3.13 and 3.14 too.
85
88
 
86
89
  ```bash
87
90
  pip install graph-mind-memory
@@ -105,7 +108,8 @@ The installer:
105
108
  autostart entry on Linux);
106
109
  - downloads the embedding model.
107
110
 
108
- Then restart your AI apps. Running the installer again is safe. Run it again if you move the folder.
111
+ Then restart your AI apps. The server is also listed in the
112
+ [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.goyohan0611-png/graph-mind`. Running the installer again is safe. Run it again if you move the folder.
109
113
 
110
114
  > [!TIP]
111
115
  > If `pip` fails with "No such file or directory", Windows' 260-character path limit is the usual
@@ -198,10 +202,21 @@ python -m unittest discover -p "test_*.py"
198
202
  can stop capture until Graph-MIND is updated.
199
203
  - **Multi-session questions are the weakest type at 80%.** These are questions that count or
200
204
  combine facts across many conversations.
201
- - **The code base still carries modules from the research phase.** It will be slimmed down.
205
+ - **The repository still holds the research-phase experiments** next to the product (see
206
+ [Repository layout](#repository-layout)); the installed package carries only the 21 product
207
+ modules.
202
208
 
203
209
  The full list is in [REPORT.md §9](REPORT.md#9-known-limits).
204
210
 
211
+ ## Repository layout
212
+
213
+ | | files |
214
+ |---|---|
215
+ | **Product** (what `pip install graph-mind-memory` installs) | `graph_mind_mcp_server.py` (MCP server), `automatic_capture*.py` (capture service), `install.py`, `brain_log.py` (sharing across PCs), `local_brain.py` / `conversation_memory.py` / `coding_memory.py` / `development_memory.py` (stores), `semantic_recall.py` / `local_embedder.py` / `vector_cache.py` / `embedding_warmup.py` (search), and their helpers |
216
+ | **Benchmarks** | `product_answer_eval.py`, `official_judge_v073.py`, `rival_mem0.py`, `rival_mempalace.py`, `rival_clean_prereg.py`, and the result files under `runs/` |
217
+ | **Research phase** | the other modules: earlier extraction pipelines and analyses that REPORT.md cites |
218
+ | **Tests** | `test_*.py` |
219
+
205
220
  ## Contributing
206
221
 
207
222
  Issues and pull requests are welcome. Contributions are accepted under the [CLA](CLA.md), which
@@ -224,3 +239,5 @@ available for products that cannot.
224
239
  [benchmarks-link]: #benchmarks
225
240
  [ci-shield]: https://img.shields.io/github/actions/workflow/status/goyohan0611-png/graph-mind/tests.yml?style=flat-square&label=tests
226
241
  [ci-link]: https://github.com/goyohan0611-png/graph-mind/actions/workflows/tests.yml
242
+ [pypi-shield]: https://img.shields.io/pypi/v/graph-mind-memory?style=flat-square&label=pypi
243
+ [pypi-link]: https://pypi.org/project/graph-mind-memory/
@@ -85,7 +85,13 @@ def local_postgres() -> str:
85
85
  role other PCs log in as."""
86
86
  if "uri" not in _LOCAL_URI:
87
87
  import fasteners
88
- from pgserver._commands import initdb, pg_ctl
88
+ try:
89
+ from pgserver._commands import initdb, pg_ctl
90
+ except ImportError:
91
+ raise RuntimeError(
92
+ "Hosting the shared brain on this PC needs pgserver, which is built for Python "
93
+ "3.9-3.12 only. Run Graph-MIND on this PC with Python 3.12, or use a synced "
94
+ "folder instead. Joining a brain another PC hosts works on any Python.") from None
89
95
  from pgserver.utils import PostmasterInfo
90
96
  data = _pg_data()
91
97
  data.parent.mkdir(parents=True, exist_ok=True)
@@ -121,8 +127,8 @@ def share(open_firewall: bool = True) -> dict:
121
127
  to the user and never posted anywhere."""
122
128
  import psycopg
123
129
  import secrets
130
+ local_postgres() # first: it explains a missing pgserver
124
131
  from pgserver._commands import pg_ctl
125
- local_postgres()
126
132
  password = _config().get("share_password") or secrets.token_urlsafe(18)
127
133
  data = _pg_data()
128
134
  with psycopg.connect(_admin_uri(), autocommit=True) as admin:
@@ -0,0 +1,19 @@
1
+ """Timestamps as the stores accept them: ISO 8601 with a time, in one declared clock."""
2
+ from __future__ import annotations
3
+
4
+ from datetime import datetime, timezone
5
+
6
+
7
+ def timestamp(value, clock):
8
+ if not isinstance(value, str) or "T" not in value:
9
+ raise ValueError("TIMESTAMP_REQUIRED")
10
+ try:
11
+ result = datetime.fromisoformat(value)
12
+ except ValueError:
13
+ raise ValueError("INVALID_TIMESTAMP") from None
14
+ aware = result.utcoffset() is not None
15
+ if clock == "UTC" and aware:
16
+ return result.astimezone(timezone.utc)
17
+ if clock == "SOURCE_LOCAL" and not aware:
18
+ return result
19
+ raise ValueError("CLOCK_DOMAIN_MISMATCH")
@@ -13,7 +13,7 @@ import os
13
13
  import re
14
14
  import sqlite3
15
15
 
16
- from temporal_state import timestamp
16
+ from clock import timestamp
17
17
 
18
18
 
19
19
  CAPTURE_VERSION = "coding-memory-v0.1"
@@ -11,7 +11,7 @@ import os
11
11
  import re
12
12
  import sqlite3
13
13
 
14
- from temporal_state import timestamp
14
+ from clock import timestamp
15
15
 
16
16
 
17
17
  CAPTURE_VERSION = "codex-conversation-capture-v0.1"
@@ -14,7 +14,7 @@ import re
14
14
  import sqlite3
15
15
  import uuid
16
16
 
17
- from temporal_state import timestamp
17
+ from clock import timestamp
18
18
 
19
19
 
20
20
  CONTRACT_VERSION = "development-memory-v0.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: graph-mind-memory
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Local-first memory for AI coding assistants: verbatim, on your own PC, no LLM calls at write time.
5
5
  Author-email: Yohan Ko <goyohan0611@gmail.com>
6
6
  License-Expression: AGPL-3.0-only
@@ -18,7 +18,7 @@ Requires-Dist: mcp<3,>=2
18
18
  Requires-Dist: numpy
19
19
  Requires-Dist: transformers
20
20
  Requires-Dist: tiktoken
21
- Requires-Dist: pgserver
21
+ Requires-Dist: pgserver; python_version < "3.13"
22
22
  Requires-Dist: psycopg[binary]
23
23
  Requires-Dist: psutil
24
24
  Requires-Dist: fasteners
@@ -37,6 +37,7 @@ Local-first memory for AI coding assistants. Verbatim storage, on your own PC:
37
37
  [![][platform-shield]][platform-link]
38
38
  [![][longmemeval-shield]][benchmarks-link]
39
39
  [![][ci-shield]][ci-link]
40
+ [![][pypi-shield]][pypi-link]
40
41
 
41
42
  *Switch models; keep the memory.*
42
43
 
@@ -107,7 +108,9 @@ saves them. Graph-MIND does not.
107
108
 
108
109
  ## Install
109
110
 
110
- Requires Python 3.10+ (64-bit). Windows, macOS or Linux.
111
+ Requires Python 3.10+ (64-bit). Windows, macOS or Linux. Hosting a brain that other PCs join
112
+ needs Python 3.12 or older on that one PC (its Postgres helper, pgserver, has no newer build yet);
113
+ everything else, joining included, works on 3.13 and 3.14 too.
111
114
 
112
115
  ```bash
113
116
  pip install graph-mind-memory
@@ -131,7 +134,8 @@ The installer:
131
134
  autostart entry on Linux);
132
135
  - downloads the embedding model.
133
136
 
134
- Then restart your AI apps. Running the installer again is safe. Run it again if you move the folder.
137
+ Then restart your AI apps. The server is also listed in the
138
+ [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.goyohan0611-png/graph-mind`. Running the installer again is safe. Run it again if you move the folder.
135
139
 
136
140
  > [!TIP]
137
141
  > If `pip` fails with "No such file or directory", Windows' 260-character path limit is the usual
@@ -224,10 +228,21 @@ python -m unittest discover -p "test_*.py"
224
228
  can stop capture until Graph-MIND is updated.
225
229
  - **Multi-session questions are the weakest type at 80%.** These are questions that count or
226
230
  combine facts across many conversations.
227
- - **The code base still carries modules from the research phase.** It will be slimmed down.
231
+ - **The repository still holds the research-phase experiments** next to the product (see
232
+ [Repository layout](#repository-layout)); the installed package carries only the 21 product
233
+ modules.
228
234
 
229
235
  The full list is in [REPORT.md §9](REPORT.md#9-known-limits).
230
236
 
237
+ ## Repository layout
238
+
239
+ | | files |
240
+ |---|---|
241
+ | **Product** (what `pip install graph-mind-memory` installs) | `graph_mind_mcp_server.py` (MCP server), `automatic_capture*.py` (capture service), `install.py`, `brain_log.py` (sharing across PCs), `local_brain.py` / `conversation_memory.py` / `coding_memory.py` / `development_memory.py` (stores), `semantic_recall.py` / `local_embedder.py` / `vector_cache.py` / `embedding_warmup.py` (search), and their helpers |
242
+ | **Benchmarks** | `product_answer_eval.py`, `official_judge_v073.py`, `rival_mem0.py`, `rival_mempalace.py`, `rival_clean_prereg.py`, and the result files under `runs/` |
243
+ | **Research phase** | the other modules: earlier extraction pipelines and analyses that REPORT.md cites |
244
+ | **Tests** | `test_*.py` |
245
+
231
246
  ## Contributing
232
247
 
233
248
  Issues and pull requests are welcome. Contributions are accepted under the [CLA](CLA.md), which
@@ -250,3 +265,5 @@ available for products that cannot.
250
265
  [benchmarks-link]: #benchmarks
251
266
  [ci-shield]: https://img.shields.io/github/actions/workflow/status/goyohan0611-png/graph-mind/tests.yml?style=flat-square&label=tests
252
267
  [ci-link]: https://github.com/goyohan0611-png/graph-mind/actions/workflows/tests.yml
268
+ [pypi-shield]: https://img.shields.io/pypi/v/graph-mind-memory?style=flat-square&label=pypi
269
+ [pypi-link]: https://pypi.org/project/graph-mind-memory/
@@ -4,38 +4,22 @@ associative_memory.py
4
4
  automatic_capture.py
5
5
  automatic_capture_cli.py
6
6
  brain_log.py
7
+ clock.py
7
8
  coding_memory.py
8
- concept_plan_benchmark_v071.py
9
9
  conversation_memory.py
10
10
  development_memory.py
11
11
  development_paths.py
12
12
  embedding_warmup.py
13
13
  entity_timeline.py
14
- executable_memory.py
15
- executable_plan_v2_diagnostic.py
16
14
  graph_mind_mcp_server.py
17
- grounded_concept_bridge_v072.py
18
- ingestion_gate.py
19
- ingestion_synonyms.py
20
15
  install.py
21
- llm_concept_planner.py
22
16
  local_brain.py
23
- longmemeval_adapter.py
24
- longmemeval_ingestion_calibration.py
25
- longmemeval_ingestion_preflight.py
26
- longmemeval_ingestion_v7.py
27
- memory_algebra.py
28
- memory_contract.py
29
- memory_normalization.py
30
- memory_vocabulary.py
17
+ local_embedder.py
31
18
  pyproject.toml
32
- semantic_grounding_v073.py
33
19
  semantic_llm_extractor.py
34
20
  semantic_memory.py
35
21
  semantic_recall.py
36
- state_relation_contract.py
37
22
  temporal_resolver.py
38
- temporal_state.py
39
23
  universal_personal_memory.py
40
24
  vector_cache.py
41
25
  graph_mind_memory.egg-info/PKG-INFO
@@ -3,7 +3,9 @@ mcp<3,>=2
3
3
  numpy
4
4
  transformers
5
5
  tiktoken
6
- pgserver
7
6
  psycopg[binary]
8
7
  psutil
9
8
  fasteners
9
+
10
+ [:python_version < "3.13"]
11
+ pgserver
@@ -0,0 +1,21 @@
1
+ associative_memory
2
+ automatic_capture
3
+ automatic_capture_cli
4
+ brain_log
5
+ clock
6
+ coding_memory
7
+ conversation_memory
8
+ development_memory
9
+ development_paths
10
+ embedding_warmup
11
+ entity_timeline
12
+ graph_mind_mcp_server
13
+ install
14
+ local_brain
15
+ local_embedder
16
+ semantic_llm_extractor
17
+ semantic_memory
18
+ semantic_recall
19
+ temporal_resolver
20
+ universal_personal_memory
21
+ vector_cache
@@ -108,10 +108,13 @@ def capture_service(start: bool) -> str:
108
108
  sys.path.insert(0, str(HERE))
109
109
  from automatic_capture import _atomic_json, default_config_path, default_service_state_dir, make_config
110
110
  if not default_config_path().exists():
111
- _atomic_json(default_config_path(), make_config(
112
- workspace=str(HERE), project_id="project:graph-mind",
113
- session_id="service:automatic-capture-v0.2",
114
- sessions_root=str(Path.home() / ".codex" / "sessions")))
111
+ config = make_config(workspace=str(HERE), project_id="project:graph-mind",
112
+ session_id="service:automatic-capture-v0.2",
113
+ sessions_root=str(Path.home() / ".codex" / "sessions"))
114
+ # Conversations only. Watching a code folder is opt-in: this folder is Graph-MIND itself,
115
+ # or site-packages after a pip install, and the service would rescan it every 2 minutes.
116
+ config["code_workspaces"], config["workspace_scopes"] = [], {}
117
+ _atomic_json(default_config_path(), config)
115
118
  script = HERE / "automatic_capture_cli.py"
116
119
  system = platform.system()
117
120
  if system == "Windows":
@@ -156,7 +159,7 @@ def capture_service(start: bool) -> str:
156
159
 
157
160
  def embedding_model():
158
161
  sys.path.insert(0, str(HERE))
159
- from semantic_grounding_v073 import LOCAL_MODEL
162
+ from local_embedder import LOCAL_MODEL
160
163
  from transformers import AutoModel, AutoTokenizer
161
164
  AutoTokenizer.from_pretrained(LOCAL_MODEL)
162
165
  AutoModel.from_pretrained(LOCAL_MODEL)
@@ -11,7 +11,7 @@ import sqlite3
11
11
  import unicodedata
12
12
  import uuid
13
13
 
14
- from temporal_state import timestamp
14
+ from clock import timestamp
15
15
  from universal_personal_memory import (PROFILE_FIELDS, SCHEMA_VERSION,
16
16
  default_profile, normalize_profile)
17
17
 
@@ -0,0 +1,112 @@
1
+ """The on-device embedder: multilingual MiniLM, mean pooling, vectors cached on disk.
2
+
3
+ No text leaves the machine. Split out of the v0.7.3 research script (semantic_grounding_v073.py),
4
+ which still imports it from here, so the product no longer pulls that script's experiment chain.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from pathlib import Path
9
+ import hashlib
10
+ import math
11
+ import threading
12
+
13
+ from associative_memory import _terms
14
+ from vector_cache import VectorCache, convert
15
+
16
+ LOCAL_MODEL = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
17
+ ACTIVATE = dict(seed_limit=12, hops=2, fanout=8, max_nodes=24, limit=8) # frozen v0.7.1 params
18
+ SEED_LIMIT = ACTIVATE["seed_limit"]
19
+
20
+
21
+ class LocalEmbedder:
22
+ """On-device multilingual embeddings via raw transformers (mean pooling, L2-normalized).
23
+ No text leaves the machine — required by the user-owned local-brain promise."""
24
+
25
+ _model = None
26
+ _tok = None
27
+ _lock = threading.RLock() # model load + cache writes are not thread-safe
28
+
29
+ FLUSH_EVERY = 5000 # vectors between writes: bounds lost work without rewriting per call
30
+
31
+ def __init__(self, cache_path, model=LOCAL_MODEL):
32
+ # float32 rows in a sibling directory: the old JSON cache turned 1.1GB on disk into 3-4GB
33
+ # of Python float objects and got two evaluation runs killed for memory pressure.
34
+ self.cache_path = Path(cache_path)
35
+ self.model_name = model
36
+ self.cache = VectorCache(self.cache_path.with_suffix(".vec"), model=model)
37
+ if not len(self.cache) and self.cache_path.exists():
38
+ self.cache = convert(self.cache_path, self.cache_path.with_suffix(".vec"), model)
39
+ self._since = 0
40
+
41
+ def _load(self):
42
+ if LocalEmbedder._model is None:
43
+ import torch
44
+ from transformers import AutoModel, AutoTokenizer
45
+ LocalEmbedder._tok = AutoTokenizer.from_pretrained(self.model_name)
46
+ LocalEmbedder._model = AutoModel.from_pretrained(self.model_name).eval()
47
+ LocalEmbedder._torch = torch
48
+
49
+ def _key(self, text):
50
+ return hashlib.sha256((self.model_name + "\0" + text).encode("utf-8")).hexdigest()
51
+
52
+ def _encode(self, texts):
53
+ import torch
54
+ torch = LocalEmbedder._torch
55
+ batch = LocalEmbedder._tok(texts, padding=True, truncation=True,
56
+ max_length=256, return_tensors="pt")
57
+ with torch.no_grad():
58
+ out = LocalEmbedder._model(**batch)
59
+ mask = batch["attention_mask"].unsqueeze(-1).float()
60
+ emb = (out.last_hidden_state * mask).sum(1) / mask.sum(1).clamp(min=1e-9)
61
+ emb = torch.nn.functional.normalize(emb, dim=1)
62
+ return emb.tolist()
63
+
64
+ def embed(self, texts):
65
+ texts = [t.strip()[:2000] for t in texts]
66
+ missing = [t for t in dict.fromkeys(texts) if self._key(t) not in self.cache]
67
+ if missing:
68
+ with LocalEmbedder._lock:
69
+ missing = [t for t in dict.fromkeys(texts) if self._key(t) not in self.cache]
70
+ self._load()
71
+ for start in range(0, len(missing), 128): # larger batch = higher CPU throughput
72
+ chunk = missing[start:start + 128]
73
+ for text, vector in zip(chunk, self._encode(chunk)):
74
+ self.cache.put(self._key(text), vector)
75
+ self._since += 1
76
+ if self._since >= LocalEmbedder.FLUSH_EVERY:
77
+ self.flush()
78
+ return [self.cache.get(self._key(t)) for t in texts]
79
+
80
+ def flush(self):
81
+ with LocalEmbedder._lock:
82
+ self.cache.flush()
83
+ self._since = 0
84
+
85
+
86
+ def cosine(a, b):
87
+ dot = sum(i * j for i, j in zip(a, b))
88
+ na = math.sqrt(sum(i * i for i in a))
89
+ nb = math.sqrt(sum(j * j for j in b))
90
+ return dot / (na * nb) if na and nb else 0.0
91
+
92
+
93
+ def semantic_coverage(cue_vecs, seed_vecs):
94
+ """Mean over cues of the best cosine similarity of that cue to any seed text."""
95
+ if not cue_vecs or not seed_vecs:
96
+ return 0.0
97
+ return sum(max(cosine(c, s) for s in seed_vecs) for c in cue_vecs) / len(cue_vecs)
98
+
99
+
100
+ def _seed_texts(index, query, cues):
101
+ terms = _terms(" ".join([query, *cues]))
102
+ if not terms:
103
+ return []
104
+ expression = " OR ".join('"' + t.replace('"', '""') + '"' for t in terms)
105
+ rows = index.db.execute(
106
+ """SELECT associative_engrams_fts.text AS text
107
+ FROM associative_engrams_fts JOIN associative_engrams e
108
+ ON e.engram_id=associative_engrams_fts.engram_id
109
+ WHERE associative_engrams_fts MATCH ?
110
+ ORDER BY bm25(associative_engrams_fts), e.revision DESC LIMIT ?""",
111
+ [expression, SEED_LIMIT]).fetchall()
112
+ return [r["text"] for r in rows]
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "graph-mind-memory"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  description = "Local-first memory for AI coding assistants: verbatim, on your own PC, no LLM calls at write time."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -23,7 +23,9 @@ dependencies = [
23
23
  "numpy",
24
24
  "transformers",
25
25
  "tiktoken",
26
- "pgserver",
26
+ # hosts the shared brain's Postgres; built for Python 3.9-3.12 only. Joining another PC's
27
+ # brain (psycopg) and everything else work on any supported Python.
28
+ "pgserver; python_version < '3.13'",
27
29
  "psycopg[binary]",
28
30
  "psutil",
29
31
  "fasteners",
@@ -39,44 +41,27 @@ graph-mind-install = "install:main"
39
41
  graph-mind-capture = "automatic_capture_cli:main"
40
42
 
41
43
  [tool.setuptools]
42
- # ponytail: flat modules, as in the repository; a graph_mind/ package is the upgrade once the
43
- # research-phase modules are trimmed out of the product's imports.
44
+ # ponytail: flat modules, as in the repository; a graph_mind/ package is the upgrade path.
44
45
  py-modules = [
45
46
  "associative_memory",
46
47
  "automatic_capture",
47
48
  "automatic_capture_cli",
48
49
  "brain_log",
50
+ "clock",
49
51
  "coding_memory",
50
- "concept_plan_benchmark_v071",
51
52
  "conversation_memory",
52
53
  "development_memory",
53
54
  "development_paths",
54
55
  "embedding_warmup",
55
56
  "entity_timeline",
56
- "executable_memory",
57
- "executable_plan_v2_diagnostic",
58
57
  "graph_mind_mcp_server",
59
- "grounded_concept_bridge_v072",
60
- "ingestion_gate",
61
- "ingestion_synonyms",
62
58
  "install",
63
- "llm_concept_planner",
64
59
  "local_brain",
65
- "longmemeval_adapter",
66
- "longmemeval_ingestion_calibration",
67
- "longmemeval_ingestion_preflight",
68
- "longmemeval_ingestion_v7",
69
- "memory_algebra",
70
- "memory_contract",
71
- "memory_normalization",
72
- "memory_vocabulary",
73
- "semantic_grounding_v073",
60
+ "local_embedder",
74
61
  "semantic_llm_extractor",
75
62
  "semantic_memory",
76
63
  "semantic_recall",
77
- "state_relation_contract",
78
64
  "temporal_resolver",
79
- "temporal_state",
80
65
  "universal_personal_memory",
81
66
  "vector_cache",
82
67
  ]
@@ -16,7 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  from pathlib import Path
18
18
 
19
- from semantic_grounding_v073 import (ACTIVATE, LocalEmbedder, cosine,
19
+ from local_embedder import (ACTIVATE, LocalEmbedder, cosine,
20
20
  _seed_texts, semantic_coverage)
21
21
 
22
22
  DEFAULT_THRESHOLD = 0.35 # pre-registered on the local MiniLM scale (dev safe window [0.30,0.40])