yourmemory 1.2.2__tar.gz → 1.2.3__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 (34) hide show
  1. {yourmemory-1.2.2/yourmemory.egg-info → yourmemory-1.2.3}/PKG-INFO +12 -6
  2. {yourmemory-1.2.2 → yourmemory-1.2.3}/README.md +11 -5
  3. {yourmemory-1.2.2 → yourmemory-1.2.3}/pyproject.toml +1 -1
  4. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/services/resolve.py +44 -23
  5. {yourmemory-1.2.2 → yourmemory-1.2.3/yourmemory.egg-info}/PKG-INFO +12 -6
  6. {yourmemory-1.2.2 → yourmemory-1.2.3}/LICENSE +0 -0
  7. {yourmemory-1.2.2 → yourmemory-1.2.3}/memory_mcp.py +0 -0
  8. {yourmemory-1.2.2 → yourmemory-1.2.3}/setup.cfg +0 -0
  9. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/__init__.py +0 -0
  10. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/app.py +0 -0
  11. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/db/connection.py +0 -0
  12. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/db/duckdb_schema.sql +0 -0
  13. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/db/migrate.py +0 -0
  14. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/db/schema.sql +0 -0
  15. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/db/sqlite_schema.sql +0 -0
  16. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/jobs/decay_job.py +0 -0
  17. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/routes/__init__.py +0 -0
  18. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/routes/agents.py +0 -0
  19. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/routes/memories.py +0 -0
  20. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/routes/retrieve.py +0 -0
  21. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/services/__init__.py +0 -0
  22. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/services/agent_registry.py +0 -0
  23. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/services/api_keys.py +0 -0
  24. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/services/decay.py +0 -0
  25. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/services/embed.py +0 -0
  26. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/services/extract.py +0 -0
  27. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/services/extract_fallback.py +0 -0
  28. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/services/resolve_fallback.py +0 -0
  29. {yourmemory-1.2.2 → yourmemory-1.2.3}/src/services/retrieve.py +0 -0
  30. {yourmemory-1.2.2 → yourmemory-1.2.3}/yourmemory.egg-info/SOURCES.txt +0 -0
  31. {yourmemory-1.2.2 → yourmemory-1.2.3}/yourmemory.egg-info/dependency_links.txt +0 -0
  32. {yourmemory-1.2.2 → yourmemory-1.2.3}/yourmemory.egg-info/entry_points.txt +0 -0
  33. {yourmemory-1.2.2 → yourmemory-1.2.3}/yourmemory.egg-info/requires.txt +0 -0
  34. {yourmemory-1.2.2 → yourmemory-1.2.3}/yourmemory.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yourmemory
3
- Version: 1.2.2
3
+ Version: 1.2.3
4
4
  Summary: Persistent memory for Claude — Ebbinghaus forgetting curve, semantic deduplication, MCP-native
5
5
  Author-email: Sachit Misra <mishrasachit1@gmail.com>
6
6
  License: Apache License
@@ -256,17 +256,23 @@ pip install yourmemory
256
256
 
257
257
  All dependencies installed automatically. No clone, no Docker, no database setup.
258
258
 
259
- ### 2. Get your config
259
+ ### 2. Run setup (once)
260
260
 
261
- Run this once to get your exact config:
261
+ ```bash
262
+ yourmemory-setup
263
+ ```
264
+
265
+ Downloads the spaCy language model and initialises the database. Run this once after install.
266
+
267
+ ### 3. Get your config
262
268
 
263
269
  ```bash
264
270
  yourmemory-path
265
271
  ```
266
272
 
267
- It prints your full executable path and a ready-to-paste config for any MCP client. Copy it.
273
+ Prints your full executable path and a ready-to-paste config for any MCP client. Copy it.
268
274
 
269
- ### 3. Wire into your AI client
275
+ ### 4. Wire into your AI client
270
276
 
271
277
  The database is created automatically at `~/.yourmemory/memories.duckdb` on first use.
272
278
 
@@ -352,7 +358,7 @@ Restart Claude Desktop.
352
358
 
353
359
  YourMemory is a standard stdio MCP server. Works with Claude Code, Claude Desktop, Cline, Cursor, Windsurf, Continue, and Zed. Use the full path from `yourmemory-path` if the client doesn't inherit shell PATH.
354
360
 
355
- ### 4. Add memory instructions to your project
361
+ ### 5. Add memory instructions to your project
356
362
 
357
363
  Copy `sample_CLAUDE.md` into your project root as `CLAUDE.md` and replace:
358
364
  - `YOUR_NAME` — your name (e.g. `Alice`)
@@ -61,17 +61,23 @@ pip install yourmemory
61
61
 
62
62
  All dependencies installed automatically. No clone, no Docker, no database setup.
63
63
 
64
- ### 2. Get your config
64
+ ### 2. Run setup (once)
65
65
 
66
- Run this once to get your exact config:
66
+ ```bash
67
+ yourmemory-setup
68
+ ```
69
+
70
+ Downloads the spaCy language model and initialises the database. Run this once after install.
71
+
72
+ ### 3. Get your config
67
73
 
68
74
  ```bash
69
75
  yourmemory-path
70
76
  ```
71
77
 
72
- It prints your full executable path and a ready-to-paste config for any MCP client. Copy it.
78
+ Prints your full executable path and a ready-to-paste config for any MCP client. Copy it.
73
79
 
74
- ### 3. Wire into your AI client
80
+ ### 4. Wire into your AI client
75
81
 
76
82
  The database is created automatically at `~/.yourmemory/memories.duckdb` on first use.
77
83
 
@@ -157,7 +163,7 @@ Restart Claude Desktop.
157
163
 
158
164
  YourMemory is a standard stdio MCP server. Works with Claude Code, Claude Desktop, Cline, Cursor, Windsurf, Continue, and Zed. Use the full path from `yourmemory-path` if the client doesn't inherit shell PATH.
159
165
 
160
- ### 4. Add memory instructions to your project
166
+ ### 5. Add memory instructions to your project
161
167
 
162
168
  Copy `sample_CLAUDE.md` into your project root as `CLAUDE.md` and replace:
163
169
  - `YOUR_NAME` — your name (e.g. `Alice`)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "yourmemory"
7
- version = "1.2.2"
7
+ version = "1.2.3"
8
8
  description = "Persistent memory for Claude — Ebbinghaus forgetting curve, semantic deduplication, MCP-native"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -16,17 +16,6 @@ from src.db.connection import get_backend
16
16
  DEDUP_THRESHOLD = 0.65 # below → always new memory
17
17
  REINFORCE_THRESHOLD = 0.85 # at or above → reinforce (near-identical paraphrase)
18
18
 
19
- # Polarity verb antonym pairs (spaCy lemma → antonym lemma)
20
- _ANTONYMS = {
21
- "love": "hate", "hate": "love",
22
- "like": "dislike", "dislike": "like",
23
- "prefer": "avoid", "avoid": "prefer",
24
- "use": "stop", "stop": "use",
25
- "want": "refuse", "refuse": "want",
26
- "enjoy": "dislike",
27
- "start": "stop",
28
- }
29
-
30
19
 
31
20
  def _cosine(a: list, b: list) -> float:
32
21
  import numpy as np
@@ -101,19 +90,50 @@ def find_near_duplicate(user_id: str, embedding: list, conn) -> dict | None:
101
90
  "importance": best[3], "recall_count": best[4], "similarity": sim}
102
91
 
103
92
 
93
+ _POSITIVE_VERBS = {
94
+ "love", "like", "prefer", "enjoy", "use", "want", "start",
95
+ "adopt", "recommend", "favor", "support", "trust", "appreciate",
96
+ }
97
+ _NEGATIVE_VERBS = {
98
+ "hate", "dislike", "avoid", "stop", "refuse", "abandon",
99
+ "reject", "distrust", "dislike", "despise",
100
+ }
101
+
102
+
103
+ def _polarity(doc) -> int:
104
+ """
105
+ Return +1 (positive), -1 (negative), or 0 (neutral) for a doc.
106
+ Uses root verb lemma + negation detection — no sentiment model needed.
107
+ """
108
+ for token in doc:
109
+ # Use both lemma and raw text to handle spaCy lemmatization bugs
110
+ # e.g. "hates" → lemma "hat" (wrong) but text.rstrip("s") → "hate"
111
+ lemma = token.lemma_.lower()
112
+ raw = token.text.lower().rstrip("s") # crude but catches loves/hates/likes/dislikes
113
+ is_negated = any(child.dep_ == "neg" for child in token.children)
114
+
115
+ if lemma in _POSITIVE_VERBS or raw in _POSITIVE_VERBS:
116
+ return -1 if is_negated else +1
117
+ if lemma in _NEGATIVE_VERBS or raw in _NEGATIVE_VERBS:
118
+ return +1 if is_negated else -1
119
+ return 0
120
+
121
+
104
122
  def detect_contradiction(existing_text: str, incoming_text: str) -> bool:
105
123
  """
106
124
  Return True if the incoming text contradicts the existing one.
107
- Uses spaCy lemmas to find polarity verb antonym pairs.
125
+ Detects polarity flip using verb lemmas + negation generalizes beyond
126
+ a fixed antonym list by treating any positive→negative or negative→positive
127
+ shift on the same topic as a contradiction.
108
128
  """
109
- existing_verbs = {tok.lemma_.lower() for tok in _nlp(existing_text) if tok.pos_ == "VERB"}
110
- incoming_verbs = {tok.lemma_.lower() for tok in _nlp(incoming_text) if tok.pos_ == "VERB"}
129
+ if _nlp is None:
130
+ return False
131
+
132
+ existing_pol = _polarity(_nlp(existing_text))
133
+ incoming_pol = _polarity(_nlp(incoming_text))
111
134
 
112
- for verb in existing_verbs:
113
- antonym = _ANTONYMS.get(verb)
114
- if antonym and antonym in incoming_verbs:
115
- return True
116
- return False
135
+ # Both sentences must have clear polarity and they must be opposite
136
+ return existing_pol != 0 and incoming_pol != 0 and existing_pol != incoming_pol
117
137
 
118
138
 
119
139
  def merge_entities(existing_text: str, incoming_text: str) -> str:
@@ -168,13 +188,14 @@ def resolve(user_id: str, content: str, embedding: list, conn) -> dict:
168
188
 
169
189
  sim = match["similarity"]
170
190
 
171
- if sim >= REINFORCE_THRESHOLD:
172
- return {"action": "reinforce", "content": match["content"], "existing": match}
173
-
174
- # DEDUP_THRESHOLD ≤ sim < REINFORCE_THRESHOLD
191
+ # Check contradiction first — even near-identical sentences can be opposites
192
+ # e.g. "dislike JavaScript" vs "love JavaScript" → sim ~0.92 but must replace
175
193
  if detect_contradiction(match["content"], content):
176
194
  return {"action": "replace", "content": content, "existing": match}
177
195
 
196
+ if sim >= REINFORCE_THRESHOLD:
197
+ return {"action": "reinforce", "content": match["content"], "existing": match}
198
+
178
199
  merged = merge_entities(match["content"], content)
179
200
  if merged == match["content"]:
180
201
  # No new entities found — treat as paraphrase
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yourmemory
3
- Version: 1.2.2
3
+ Version: 1.2.3
4
4
  Summary: Persistent memory for Claude — Ebbinghaus forgetting curve, semantic deduplication, MCP-native
5
5
  Author-email: Sachit Misra <mishrasachit1@gmail.com>
6
6
  License: Apache License
@@ -256,17 +256,23 @@ pip install yourmemory
256
256
 
257
257
  All dependencies installed automatically. No clone, no Docker, no database setup.
258
258
 
259
- ### 2. Get your config
259
+ ### 2. Run setup (once)
260
260
 
261
- Run this once to get your exact config:
261
+ ```bash
262
+ yourmemory-setup
263
+ ```
264
+
265
+ Downloads the spaCy language model and initialises the database. Run this once after install.
266
+
267
+ ### 3. Get your config
262
268
 
263
269
  ```bash
264
270
  yourmemory-path
265
271
  ```
266
272
 
267
- It prints your full executable path and a ready-to-paste config for any MCP client. Copy it.
273
+ Prints your full executable path and a ready-to-paste config for any MCP client. Copy it.
268
274
 
269
- ### 3. Wire into your AI client
275
+ ### 4. Wire into your AI client
270
276
 
271
277
  The database is created automatically at `~/.yourmemory/memories.duckdb` on first use.
272
278
 
@@ -352,7 +358,7 @@ Restart Claude Desktop.
352
358
 
353
359
  YourMemory is a standard stdio MCP server. Works with Claude Code, Claude Desktop, Cline, Cursor, Windsurf, Continue, and Zed. Use the full path from `yourmemory-path` if the client doesn't inherit shell PATH.
354
360
 
355
- ### 4. Add memory instructions to your project
361
+ ### 5. Add memory instructions to your project
356
362
 
357
363
  Copy `sample_CLAUDE.md` into your project root as `CLAUDE.md` and replace:
358
364
  - `YOUR_NAME` — your name (e.g. `Alice`)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes