graph-mind-memory 0.3.0__tar.gz → 0.3.1__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.
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/PKG-INFO +10 -2
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/README.md +9 -1
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/conversation_memory.py +38 -1
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/graph_mind_memory.egg-info/PKG-INFO +10 -2
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/pyproject.toml +1 -1
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/LICENSE +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/associative_memory.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/automatic_capture.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/automatic_capture_cli.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/brain_log.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/clock.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/coding_memory.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/development_memory.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/development_paths.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/embedding_warmup.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/entity_timeline.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/forget.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/graph_mind_mcp_server.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/graph_mind_memory.egg-info/SOURCES.txt +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/graph_mind_memory.egg-info/dependency_links.txt +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/graph_mind_memory.egg-info/entry_points.txt +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/graph_mind_memory.egg-info/requires.txt +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/graph_mind_memory.egg-info/top_level.txt +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/install.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/local_brain.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/local_embedder.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/semantic_llm_extractor.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/semantic_memory.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/semantic_recall.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/setup.cfg +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/temporal_resolver.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/universal_personal_memory.py +0 -0
- {graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/vector_cache.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graph-mind-memory
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
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
|
|
@@ -164,7 +164,15 @@ Then restart your AI apps. The server is also listed in the
|
|
|
164
164
|
| Claude desktop: chat | what the model saves with `brain_remember` |
|
|
165
165
|
|
|
166
166
|
Before anything is stored, these are masked: API keys, tokens from GitHub, AWS, Google and Slack,
|
|
167
|
-
private keys,
|
|
167
|
+
private keys, passwords inside URLs, values written after `password:` / `api_key=` / `token:`,
|
|
168
|
+
and any long machine-random string even from a service no rule knows (by its randomness: 91% of
|
|
169
|
+
random 20-64 character tokens caught; in 246,750 ordinary chat turns it fired 92 times, nearly
|
|
170
|
+
all on real ids and tokens). Commit ids, hashes and UUIDs are kept, since you recall those on
|
|
171
|
+
purpose.
|
|
172
|
+
|
|
173
|
+
There is no switch to keep keys: a recalled memory goes to your model's provider with the question,
|
|
174
|
+
so a stored key would leave your PC the first time it is useful. To have Graph-MIND remember a key,
|
|
175
|
+
tell it **where the key is**, not the key: *"my OpenAI key is in 1Password, under Dev"*.
|
|
168
176
|
|
|
169
177
|
Only what you actually send is captured: the service reads each app's transcript, which is written
|
|
170
178
|
after you press Enter, so a paste you delete before sending never reaches it. A plain password
|
|
@@ -138,7 +138,15 @@ Then restart your AI apps. The server is also listed in the
|
|
|
138
138
|
| Claude desktop: chat | what the model saves with `brain_remember` |
|
|
139
139
|
|
|
140
140
|
Before anything is stored, these are masked: API keys, tokens from GitHub, AWS, Google and Slack,
|
|
141
|
-
private keys,
|
|
141
|
+
private keys, passwords inside URLs, values written after `password:` / `api_key=` / `token:`,
|
|
142
|
+
and any long machine-random string even from a service no rule knows (by its randomness: 91% of
|
|
143
|
+
random 20-64 character tokens caught; in 246,750 ordinary chat turns it fired 92 times, nearly
|
|
144
|
+
all on real ids and tokens). Commit ids, hashes and UUIDs are kept, since you recall those on
|
|
145
|
+
purpose.
|
|
146
|
+
|
|
147
|
+
There is no switch to keep keys: a recalled memory goes to your model's provider with the question,
|
|
148
|
+
so a stored key would leave your PC the first time it is useful. To have Graph-MIND remember a key,
|
|
149
|
+
tell it **where the key is**, not the key: *"my OpenAI key is in 1Password, under Dev"*.
|
|
142
150
|
|
|
143
151
|
Only what you actually send is captured: the service reads each app's transcript, which is written
|
|
144
152
|
after you press Enter, so a paste you delete before sending never reaches it. A plain password
|
|
@@ -5,8 +5,10 @@ from development_paths import use_wal
|
|
|
5
5
|
|
|
6
6
|
from datetime import datetime
|
|
7
7
|
from pathlib import Path
|
|
8
|
+
import collections
|
|
8
9
|
import hashlib
|
|
9
10
|
import json
|
|
11
|
+
import math
|
|
10
12
|
import os
|
|
11
13
|
import re
|
|
12
14
|
import sqlite3
|
|
@@ -30,7 +32,34 @@ SECRET_PATTERNS = (
|
|
|
30
32
|
re.DOTALL), "[REDACTED_PRIVATE_KEY]"),
|
|
31
33
|
# a database URL carries its password: postgres://user:PASSWORD@host
|
|
32
34
|
(re.compile(r"(\b[a-z][a-z0-9+.-]*://[^\s:/@]+:)[^\s@/]+(@)"), r"\1[REDACTED]\2"),
|
|
35
|
+
# a password written after its name: "password: x", "pwd=x", "비밀번호: x", "비번=x"
|
|
36
|
+
(re.compile(r"(?i)((?<![a-z])(?:password|passwd|pwd)\s*[:=]\s*)\S+"), r"\1[REDACTED]"),
|
|
37
|
+
(re.compile(r"((?:비밀번호|비번|암호)\s*[:=]\s*)\S+"), r"\1[REDACTED]"),
|
|
33
38
|
)
|
|
39
|
+
# A token no pattern above knows: long, machine-random (mixed case and digits, no word-shaped
|
|
40
|
+
# pieces, high character entropy). Measured: catches 91% of random 20-64 character tokens; in
|
|
41
|
+
# LongMemEval's 246,750 chat turns it fires 92 times, nearly all on real ids and tokens (an
|
|
42
|
+
# OAuth token, Drive file ids, ad click ids); in this repository's code and docs, never.
|
|
43
|
+
# Commit ids, hashes and UUIDs are left alone: those get recalled on purpose.
|
|
44
|
+
RANDOM_CANDIDATE = re.compile(r"(?<![A-Za-z0-9_\-])[A-Za-z0-9_\-]{20,}(?![A-Za-z0-9_\-])")
|
|
45
|
+
UUID = re.compile(r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}")
|
|
46
|
+
WORD_PIECE = re.compile(r"[A-Z]?[a-z]+|[A-Z]+(?![a-z])")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _looks_random(token):
|
|
50
|
+
if UUID.fullmatch(token):
|
|
51
|
+
return False
|
|
52
|
+
core = re.sub(r"[_\-]", "", token)
|
|
53
|
+
if len(core) < 18 or re.fullmatch(r"[0-9a-fA-F]+", core):
|
|
54
|
+
return False
|
|
55
|
+
if not (any(c.isupper() for c in core) and any(c.islower() for c in core)
|
|
56
|
+
and sum(c.isdigit() for c in core) >= 2):
|
|
57
|
+
return False
|
|
58
|
+
pieces = WORD_PIECE.findall(core) # code names are words strung together
|
|
59
|
+
if pieces and sum(map(len, pieces)) / len(pieces) >= 3.0:
|
|
60
|
+
return False
|
|
61
|
+
counts = collections.Counter(core)
|
|
62
|
+
return -sum(n / len(core) * math.log2(n / len(core)) for n in counts.values()) >= 3.7
|
|
34
63
|
AUTOMATIC_BLOCKS = re.compile(
|
|
35
64
|
r"<(?:environment_context|recommended_plugins|in-app-browser-context)\b[^>]*>.*?"
|
|
36
65
|
r"</(?:environment_context|recommended_plugins|in-app-browser-context)>",
|
|
@@ -56,7 +85,15 @@ def _redact(value):
|
|
|
56
85
|
for pattern, replacement in SECRET_PATTERNS:
|
|
57
86
|
cleaned, replacements = pattern.subn(replacement, cleaned)
|
|
58
87
|
count += replacements
|
|
59
|
-
|
|
88
|
+
found = [0]
|
|
89
|
+
|
|
90
|
+
def unknown_token(match):
|
|
91
|
+
if not _looks_random(match.group(0)):
|
|
92
|
+
return match.group(0)
|
|
93
|
+
found[0] += 1
|
|
94
|
+
return "[REDACTED_SECRET]"
|
|
95
|
+
cleaned = RANDOM_CANDIDATE.sub(unknown_token, cleaned)
|
|
96
|
+
return cleaned.strip(), count + found[0]
|
|
60
97
|
|
|
61
98
|
|
|
62
99
|
def _message_text(payload):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graph-mind-memory
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
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
|
|
@@ -164,7 +164,15 @@ Then restart your AI apps. The server is also listed in the
|
|
|
164
164
|
| Claude desktop: chat | what the model saves with `brain_remember` |
|
|
165
165
|
|
|
166
166
|
Before anything is stored, these are masked: API keys, tokens from GitHub, AWS, Google and Slack,
|
|
167
|
-
private keys,
|
|
167
|
+
private keys, passwords inside URLs, values written after `password:` / `api_key=` / `token:`,
|
|
168
|
+
and any long machine-random string even from a service no rule knows (by its randomness: 91% of
|
|
169
|
+
random 20-64 character tokens caught; in 246,750 ordinary chat turns it fired 92 times, nearly
|
|
170
|
+
all on real ids and tokens). Commit ids, hashes and UUIDs are kept, since you recall those on
|
|
171
|
+
purpose.
|
|
172
|
+
|
|
173
|
+
There is no switch to keep keys: a recalled memory goes to your model's provider with the question,
|
|
174
|
+
so a stored key would leave your PC the first time it is useful. To have Graph-MIND remember a key,
|
|
175
|
+
tell it **where the key is**, not the key: *"my OpenAI key is in 1Password, under Dev"*.
|
|
168
176
|
|
|
169
177
|
Only what you actually send is captured: the service reads each app's transcript, which is written
|
|
170
178
|
after you press Enter, so a paste you delete before sending never reaches it. A plain password
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "graph-mind-memory"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.1"
|
|
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"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/graph_mind_memory.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/graph_mind_memory.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{graph_mind_memory-0.3.0 → graph_mind_memory-0.3.1}/graph_mind_memory.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|