fix: make semantic search dependencies optional extras (#566)

Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Paul Hernandez
2026-02-12 21:46:26 -06:00
committed by GitHub
parent 312662f382
commit 1428d18de1
13 changed files with 91 additions and 25 deletions
@@ -2,8 +2,6 @@
from basic_memory.config import BasicMemoryConfig
from basic_memory.repository.embedding_provider import EmbeddingProvider
from basic_memory.repository.fastembed_provider import FastEmbedEmbeddingProvider
from basic_memory.repository.openai_provider import OpenAIEmbeddingProvider
def create_embedding_provider(app_config: BasicMemoryConfig) -> EmbeddingProvider:
@@ -18,6 +16,9 @@ def create_embedding_provider(app_config: BasicMemoryConfig) -> EmbeddingProvide
extra_kwargs["dimensions"] = app_config.semantic_embedding_dimensions
if provider_name == "fastembed":
# Deferred import: fastembed (and its onnxruntime dep) may not be installed
from basic_memory.repository.fastembed_provider import FastEmbedEmbeddingProvider
return FastEmbedEmbeddingProvider(
model_name=app_config.semantic_embedding_model,
batch_size=app_config.semantic_embedding_batch_size,
@@ -25,6 +26,9 @@ def create_embedding_provider(app_config: BasicMemoryConfig) -> EmbeddingProvide
)
if provider_name == "openai":
# Deferred import: openai may not be installed
from basic_memory.repository.openai_provider import OpenAIEmbeddingProvider
model_name = app_config.semantic_embedding_model or "text-embedding-3-small"
if model_name == "bge-small-en-v1.5":
model_name = "text-embedding-3-small"
@@ -48,7 +48,7 @@ class FastEmbedEmbeddingProvider(EmbeddingProvider):
) as exc: # pragma: no cover - exercised via tests with monkeypatch
raise SemanticDependenciesMissingError(
"fastembed package is missing. "
"Reinstall basic-memory: pip install basic-memory"
"Install semantic extras: pip install 'basic-memory[semantic]'"
) from exc
resolved_model_name = self._MODEL_ALIASES.get(self.model_name, self.model_name)
return TextEmbedding(model_name=resolved_model_name)
@@ -44,7 +44,8 @@ class OpenAIEmbeddingProvider(EmbeddingProvider):
from openai import AsyncOpenAI
except ImportError as exc: # pragma: no cover - covered via monkeypatch tests
raise SemanticDependenciesMissingError(
"OpenAI dependency is missing. Reinstall basic-memory: pip install basic-memory"
"OpenAI dependency is missing. "
"Install semantic extras: pip install 'basic-memory[semantic]'"
) from exc
api_key = self._api_key or os.getenv("OPENAI_API_KEY")
@@ -353,7 +353,8 @@ class SearchRepositoryBase(ABC):
if self._embedding_provider is None:
raise SemanticDependenciesMissingError(
"No embedding provider configured. "
"Ensure semantic_search_enabled is true in your config."
"Install semantic extras: pip install 'basic-memory[semantic]' "
"and set semantic_search_enabled=true."
)
def _compose_row_source_text(self, row) -> str:
@@ -339,7 +339,8 @@ class SQLiteSearchRepository(SearchRepositoryBase):
import sqlite_vec
except ImportError as exc:
raise SemanticDependenciesMissingError(
"sqlite-vec package is missing. Reinstall basic-memory: pip install basic-memory"
"sqlite-vec package is missing. "
"Install semantic extras: pip install 'basic-memory[semantic]'"
) from exc
async with self._sqlite_vec_lock: