You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(memory): phase 2 smartness - semantic dedup, intent confidence, consolidation, index fingerprint, stats API
- semantic dedup on add: after the exact-match tier, atoms whose top-1
cosine similarity to a live atom exceeds semantic_dedup_threshold
(default 0.92, 0 disables) refresh the existing atom instead of
duplicating; in-batch duplicates handled via direct embedding
- predicted-intent confidence now weights recall scores; intents below
0.3 confidence are skipped entirely
- extractor confidence default is now 0.7 (was 1.0) so unconfident
extractions no longer get maximal retention and eviction resistance
- new ConsolidateAtoms: greedy similarity clustering (default 0.9) +
one LLM merge call per group; originals kept on any failure; merged
atoms keep highest confidence and union of associations; live store
only, quarantine untouched
- vector index persists a corpus fingerprint (count + FNV-1a of sorted
atom IDs) in vectors_meta.json; a mismatch on load forces a rebuild
instead of silently serving a stale corpus (legacy files rebuild once)
- new Stats() API: live/quarantined atoms, quarantine reason breakdown,
index vectors/dirty, store size, and recall timeout/failure counters
for degradation observability
├── user_model.json # persisted inferred user state + pending review queue
105
105
└── associations.json # bidirectional atom association links
106
106
```
107
107
108
-
All files are written atomically and use `0600` permissions. The vector store and metadata are rebuilt from the chunk files if they are ever corrupted. The user model and associations are loaded at startup and persisted on every change.
108
+
All files are written atomically and use `0600` permissions. The vector store and metadata are rebuilt from the chunk files if they are ever corrupted. `vectors_meta.json` records both the embedding-space fingerprint (which embedding backend produced the vectors) and a corpus fingerprint (atom count plus a hash of the sorted atom IDs); a mismatch on either — including a missing corpus fingerprint in files written before it was tracked — marks the persisted index stale so it is rebuilt once instead of silently serving an outdated corpus. The user model and associations are loaded at startup and persisted on every change.
109
109
110
110
## Dedicated Memory LLM
111
111
@@ -163,6 +163,23 @@ Extracted atoms are immediately:
163
163
4. Embedded and written to the atom store.
164
164
5. Checked against the 100 MB size cap; low-retention atoms are evicted if needed.
165
165
166
+
Explicit LLM-provided `confidence` values in (0, 1] are kept. A missing or out-of-range confidence defaults to **0.7** for extraction-origin atoms, so unqualified extracted memories do not inflate their retention score.
167
+
168
+
### Write-Path Deduplication
169
+
170
+
Atoms are deduplicated in two tiers at persistence time:
171
+
172
+
1.**Exact match**: an atom whose normalized text (lowercased, whitespace-collapsed) equals an existing live atom refreshes it — new `CreatedAt`, the higher confidence wins, the original ID is kept — instead of appending a duplicate.
173
+
2.**Semantic match**: if no exact match exists and `semantic_dedup_threshold` is non-zero, the incoming atom is compared against the live corpus via the vector index (top-1 similarity); atoms stored earlier in the same batch, which the index does not cover yet, are compared by embedding both texts directly. A match at or above the threshold is refreshed the same way. The dedup search uses the pre-batch index state and never triggers extra index rebuilds: the single index invalidation after the batch is preserved.
174
+
175
+
### Atom Consolidation
176
+
177
+
`ExtendedMemory.ConsolidateAtoms(ctx)` (no CLI yet) merges groups of live atoms that are near-duplicates (pairwise cosine similarity at or above `consolidate_similarity_threshold`). For each group it asks the memory LLM — one call per group — to merge the texts into a single concise atom, stores the merged atom through the normal add path (scan and size cap apply) keeping the group's highest confidence, a refreshed `CreatedAt`, and the union of the group's outward associations, then removes the originals. Quarantined atoms are never consolidated. On any failure for a group (LLM error, empty response, scan rejection) the originals are kept untouched.
178
+
179
+
### Observability
180
+
181
+
`ExtendedMemory.Stats()` returns a `Stats` snapshot for operators and monitoring: live/quarantined atom counts, quarantine entries grouped by reason prefix (`tainted`, `scan_rejected`), index vector count and dirty flag, on-disk store size, and recall error counters (`RecallTimeouts` for context-deadline-exceeded errors, `RecallFailures` for all other recall errors).
182
+
166
183
## Semantic Search
167
184
168
185
Extended Memory replaces episode-based recall with semantic search over atom vectors.
@@ -200,6 +217,8 @@ The final recall result is also bounded by `memory_budget_chars`. Tainted atoms
200
217
201
218
When `follow_up_anticipation_enabled` is true (default), the memory LLM receives the current user message, the last several user messages, and the current user-state model. It returns a JSON array of up to `predictive_intents` likely follow-up intents. Each intent is embedded and searched, and the union of literal-query matches and predicted-intent matches is injected into the main agent's context. For each predicted intent, the system also performs a type-targeted recall for `convention`, `file`, and `error` atoms so the agent can pre-load relevant conventions, references, and known failure modes.
202
219
220
+
Intents carry a `confidence` (0.0-1.0). Intents below 0.3 are skipped entirely; otherwise the composite score of every atom found via a predicted intent is multiplied by that intent's confidence, so a speculative intent cannot outrank literal-query matches.
221
+
203
222
Example:
204
223
205
224
- User: "Refactor the auth package to remove JWT."
@@ -355,6 +374,8 @@ Extended Memory is configured under the `memory.extended` section.
355
374
"user_state_max_pending": 20,
356
375
"associations_enabled": true,
357
376
"association_semantic_top_k": 3,
377
+
"semantic_dedup_threshold": 0.92,
378
+
"consolidate_similarity_threshold": 0.9,
358
379
"proactive_return_after_break": true,
359
380
"style_mirroring_enabled": true,
360
381
"anaphora_resolution_enabled": true,
@@ -401,6 +422,8 @@ Extended Memory is configured under the `memory.extended` section.
401
422
|`user_state_max_pending`|`20`| Maximum pending-review entries kept in the user model. |
402
423
|`associations_enabled`|`true`| Enable bidirectional atom associations (temporal, task, semantic). |
403
424
|`association_semantic_top_k`|`3`| Number of semantic neighbours linked when building associations. |
425
+
|`semantic_dedup_threshold`|`0.92`| Cosine similarity at or above which an incoming atom is treated as a paraphrase of an existing live atom and refreshes it instead of appending. `0` disables the semantic tier (exact-match dedup always runs). |
426
+
|`consolidate_similarity_threshold`|`0.9`| Cosine similarity at or above which live atoms are grouped as near-duplicates for `ConsolidateAtoms` merging. |
404
427
|`proactive_return_after_break`|`true`| On session resume, inject a "where you left off" summary. |
405
428
|`style_mirroring_enabled`|`true`| Inject a style-guidance directive based on the inferred user model. |
406
429
|`anaphora_resolution_enabled`|`true`| Resolve the first pronoun in a user message against recent trusted atoms when the top atom's score is high enough. |
0 commit comments