mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
07778790d3
Signed-off-by: phernandez <paul@basicmachines.co> Signed-off-by: bm-clawd <clawd@basicmemory.com> Co-authored-by: bm-clawd <clawd@basicmemory.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
92 lines
3.1 KiB
Python
92 lines
3.1 KiB
Python
"""Semantic search service regression tests for local SQLite search."""
|
|
|
|
import pytest
|
|
|
|
from basic_memory.repository.semantic_errors import (
|
|
SemanticDependenciesMissingError,
|
|
SemanticSearchDisabledError,
|
|
)
|
|
from basic_memory.repository.sqlite_search_repository import SQLiteSearchRepository
|
|
from basic_memory.schemas.search import SearchItemType, SearchQuery, SearchRetrievalMode
|
|
|
|
|
|
def _sqlite_repo(search_service) -> SQLiteSearchRepository:
|
|
repository = search_service.repository
|
|
if not isinstance(repository, SQLiteSearchRepository):
|
|
pytest.skip("Semantic retrieval behavior is local SQLite-only in this phase.")
|
|
return repository
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_semantic_vector_search_fails_when_disabled(search_service, test_graph):
|
|
"""Vector mode should fail fast when semantic search is disabled."""
|
|
repository = _sqlite_repo(search_service)
|
|
repository._semantic_enabled = False
|
|
|
|
with pytest.raises(SemanticSearchDisabledError):
|
|
await search_service.search(
|
|
SearchQuery(
|
|
text="Connected Entity",
|
|
retrieval_mode=SearchRetrievalMode.VECTOR,
|
|
)
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_semantic_hybrid_search_fails_when_disabled(search_service, test_graph):
|
|
"""Hybrid mode should fail fast when semantic search is disabled."""
|
|
repository = _sqlite_repo(search_service)
|
|
repository._semantic_enabled = False
|
|
|
|
with pytest.raises(SemanticSearchDisabledError):
|
|
await search_service.search(
|
|
SearchQuery(
|
|
text="Root Entity",
|
|
retrieval_mode=SearchRetrievalMode.HYBRID,
|
|
)
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_semantic_vector_search_fails_when_provider_unavailable(search_service, test_graph):
|
|
"""Vector mode should fail fast when semantic provider is unavailable."""
|
|
repository = _sqlite_repo(search_service)
|
|
repository._semantic_enabled = True
|
|
repository._embedding_provider = None
|
|
repository._vector_tables_initialized = False
|
|
|
|
with pytest.raises(SemanticDependenciesMissingError):
|
|
await search_service.search(
|
|
SearchQuery(
|
|
text="Root Entity",
|
|
retrieval_mode=SearchRetrievalMode.VECTOR,
|
|
)
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_semantic_vector_mode_rejects_non_text_query(search_service, test_graph):
|
|
"""Vector mode should not silently fall back for title-only queries."""
|
|
with pytest.raises(ValueError):
|
|
await search_service.search(
|
|
SearchQuery(
|
|
title="Root",
|
|
retrieval_mode=SearchRetrievalMode.VECTOR,
|
|
entity_types=[SearchItemType.ENTITY],
|
|
)
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_semantic_fts_mode_still_returns_observations(search_service, test_graph):
|
|
"""Explicit FTS mode should preserve existing mixed result behavior."""
|
|
results = await search_service.search(
|
|
SearchQuery(
|
|
text="Root note 1",
|
|
retrieval_mode=SearchRetrievalMode.FTS,
|
|
)
|
|
)
|
|
|
|
assert results
|
|
assert any(result.type == SearchItemType.OBSERVATION.value for result in results)
|