Symptom: TS OSS `memory.search()` returns entity rows (fragment text
like "a fan of", "recommending thriller movies and") mixed in with
real memories. The broken rows have `hash: undefined` and
`createdAt: undefined` because they came from the entity store, not
the memory pipeline.
Root cause: `MemoryVectorStore` uses a single `vectors` SQLite table
and ignores `collectionName` internally. The entity store is created
as a parallel instance with `collectionName: "${name}_entities"` in
`memory/index.ts:193`, but both default to the same `dbPath`
(`~/.mem0/vector_store.db`) when the caller doesn't set one. Both
writers append to the same `vectors` table, so a search that reads
that table returns rows from both collections.
The existing mitigation at `memory/index.ts:199` (dbPath.replace) only
fires when `dbPath` is set explicitly. The default (unset) case fell
through with no isolation.
Fix: `getDefaultVectorStoreDbPath(collectionName?)` now derives the
default filename from the collection name
(`vector_store_${name}.db`). `MemoryVectorStore` passes
`config.collectionName` into the helper. Memory vs entity stores now
land in separate files automatically, even when the caller doesn't set
`dbPath`. Explicit `dbPath` users are unaffected — the existing
suffix-swap in `memory/index.ts` still handles them.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- _get_all_from_vector_store: top_k -> limit (2 missed occurrences)
- test_empty_llm_response_fact_extraction (sync+async): add
db.get_last_messages mock returning [], set custom_instructions=None,
fix log assertion to use record.message not record.msg
- test_thinking_tags (sync+async): add embed_batch mock, db mock
with get_last_messages=[], set custom_instructions=None
Root cause: v3 pipeline calls self.db.get_last_messages() and
self.embedding_model.embed_batch() which weren't mocked, causing
the pipeline to silently fail before reaching the LLM call.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The async context manager tests that used asyncio were deleted in the
previous commit. The import is no longer needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Take team's upstream changes for search return type
(Promise<{results: Array<Memory>}>) and test assertions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests were written for the old two-pass extraction pipeline (extract
facts + merge with ADD/UPDATE/DELETE). V3 uses single-pass ADD-only
extraction with one LLM call returning {"memory": [...]}.
Changes by category:
Old pipeline tests (13 failures):
- Delete TestHallucinatedIdGuard entirely (tests UPDATE/DELETE ID
resolution that no longer exists)
- Update error log assertions to match v3 log messages
- Change LLM mock from 2-call side_effect to 1-call return_value
- Update vllm thinking tag tests for single-call format
ensure_json_instruction removed (3):
- Delete source-inspection tests (function still exists in utils
but is no longer called from _add_to_vector_store)
UTC timestamp normalization removed (2):
- Update expected timestamps to stored-as-is (no UTC conversion)
- Remove _normalize_iso_timestamp_to_utc import
_search_vector_store signature: top_k -> limit (2):
- Update test calls to use limit= parameter
Context manager + close/db removed (6):
- Delete tests for __enter__/__exit__/close/db that were removed
Vector store BM25 config (3):
- Qdrant: add sparse_vectors_config to create_col assertion,
named vector format {"": vector} in update assertion
- MongoDB: assert_any_call for both vector + text search indexes
Misc (6):
- test_search_handles_incomplete_payloads: expect 1 result (v3
filters entries without 'data' key)
- Embedding cache tests: update for embed_batch (1 call) vs
individual embed (was 2 calls)
- Graph reset tests: delete (graph support removed)
- use_azure_credential: update expected sensitivity to True
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
search() now unwraps { results: [...] } -> [...] internally (same
pattern getAll() already uses), so callers always get Array<Memory>.
Removes redundant unwrap logic from integration test helpers and
search.test.ts that caused TS2339 'Property results does not exist
on type never' — the false branch of Array.isArray() was unreachable
since search() is typed as returning Array<Memory>.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>