Repository navigation
Conversation
…s memories `Neo4jCommunityGraphDB.delete_node_by_prams` deleted the Neo4j nodes but never removed their embeddings from `vec_db`, so a deleted memory stayed retrievable through vector search while the delete API still answered "success". `clear()` and `delete_node_by_mem_cube_id()` already purged `vec_db`; `delete_node_by_prams` simply omitted that step. Collect the matching node IDs before the graph delete and purge those vectors afterwards via `_delete_vectors_for_deleted_nodes`. A vector store failure is logged rather than raised, matching the existing `clear()` and `delete_node_by_mem_cube_id()` behaviour, so a committed graph deletion is never reported as failed. The `neo4j` backend has no `vec_db` (it searches Neo4j's native vector index), so the guard is a no-op there. Regression coverage lives in `tests/graph_dbs/test_delete_vec_cleanup.py`; it fails on the parent commit and passes with this change. Closes MemTensor#2331
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
🤖 Open Code ReviewTarget: PR #2533 🔍 OpenCodeReview found 5 issue(s) in this PR. 1.
|
Fix #2331: purge embeddings when delete_node_by_prams removes memories
Fixes #2331.
Neo4jCommunityGraphDB.delete_node_by_prams()deletes the matching graph nodesbut never purges their embeddings from
vec_db. Retrieval reads the vector storefirst, so a deleted memory stays retrievable while the delete API still answers
success — the symptom in the report. The sibling paths already do this:
clear()anddelete_node_by_mem_cube_id()both purgevec_db, anddelete_node_by_pramsis the one that was missed.With a
filter, the stale points also accumulate: they keep occupying the vectortop-k window, which is how a commenter saw search degrade to zero results after
roughly 520 orphans.
Change
Both implementations of
delete_node_by_pramsnow collect the matching node idsinside the same session, before the
DELETE, and purge them afterwards through anew
_delete_vectors_for_deleted_nodes()helper onNeo4jGraphDB:a vector-store outage must not turn a successful delete into "Failed to delete
memories". This matches what
clear()already does.Neo4jGraphDBhas novec_db(vec_configlives only onthe community config), so the helper resolves it with
getattr(self, "vec_db", None)and degrades to a no-op instead of raisingAttributeError.collected rather than running a separate
count(n)query — the same number,one query fewer.
round trip.
Testing
tests/graph_dbs/test_delete_vec_cleanup.py(new, no Neo4j, Qdrant or network —the driver and the vector store are fakes):
assert {'mem-1','mem-2','mem-3'} == {'mem-2'}in the filter path, and the sameshape for the memory-id path and the return-value assertion
tests/graph_dbs→ 39 passed, 3 skippedvec_db,nothing matched, vector-store failure) which legitimately hold before and after
tests/memories tests/api tests/mem_reader→ 256 passed, 5 failed, and the same5 fail on the untouched base tree (Ollama/environment), so they are pre-existing
ruffat the pinned0.11.8passescheckandformat --checkon all threefiles; repo-wide
format --checkreports 631 files already formattedCallers checked
Every caller of the changed method was grepped and checked for a changed
contract:
memories/textual/tree.py:415,435(ignore the return value),api/handlers/memory_handler.py:441-462(the delete API path — returns successor failure purely on exception, which is exactly what the fix makes truthful),
and
mem_reader/read_skill_memory/process_skill_memory.py:1184(deletes areplaced memory, now also purged).
vec_db.deleteaccepts an unbounded id list(
vec_dbs/qdrant.py:347, and the base class takes the same list signature), whichthe new caller relies on.
Two other methods share this gap — the inherited
Neo4jGraphDB.delete_node()andremove_oldest_memory(), used by L3 maintenance and eviction. They are outsidethe delete-memory API path this issue reports, so they are deliberately not
touched here; happy to file that separately if you want it.
AI assistance: this change was produced with AI assistance (an autonomous coding
agent) from the linked issue; the analysis, the reproduction, the before/after
test runs and the lint runs were executed locally, and a human reviewed the
result before submission.