mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
fix(core): harden LiteLLM provider configuration
Signed-off-by: phernandez <paul@basicmachines.co>
This commit is contained in:
@@ -245,7 +245,11 @@ class BasicMemoryConfig(BaseSettings):
|
||||
)
|
||||
semantic_embedding_dimensions: int | None = Field(
|
||||
default=None,
|
||||
description="Embedding vector dimensions. Auto-detected from provider if not set (384 for FastEmbed, 1536 for OpenAI).",
|
||||
description=(
|
||||
"Embedding vector dimensions. Uses provider defaults when unset "
|
||||
"(384 for FastEmbed, 1536 for OpenAI and LiteLLM OpenAI default); "
|
||||
"required for custom LiteLLM models."
|
||||
),
|
||||
)
|
||||
# Trigger: full local rebuilds spend most of their time waiting behind shared
|
||||
# embed flushes, not constructing vectors themselves.
|
||||
|
||||
@@ -107,8 +107,11 @@ def reset_embedding_provider_cache() -> None:
|
||||
def create_embedding_provider(app_config: BasicMemoryConfig) -> EmbeddingProvider:
|
||||
"""Create an embedding provider based on semantic config.
|
||||
|
||||
When semantic_embedding_dimensions is set in config, it overrides
|
||||
the provider's default dimensions (384 for FastEmbed, 1536 for OpenAI).
|
||||
When semantic_embedding_dimensions is set in config, it overrides the
|
||||
provider's default dimensions (384 for FastEmbed, 1536 for OpenAI and
|
||||
the LiteLLM OpenAI default). Custom LiteLLM models require an explicit
|
||||
dimension because the vector table schema is created before the first
|
||||
embedding response is available.
|
||||
"""
|
||||
cache_key = _provider_cache_key(app_config)
|
||||
with _EMBEDDING_PROVIDER_CACHE_LOCK:
|
||||
@@ -161,6 +164,15 @@ def create_embedding_provider(app_config: BasicMemoryConfig) -> EmbeddingProvide
|
||||
model_name = app_config.semantic_embedding_model or "openai/text-embedding-3-small"
|
||||
if model_name == "bge-small-en-v1.5":
|
||||
model_name = "openai/text-embedding-3-small"
|
||||
if (
|
||||
app_config.semantic_embedding_dimensions is None
|
||||
and model_name != "openai/text-embedding-3-small"
|
||||
):
|
||||
raise ValueError(
|
||||
"semantic_embedding_dimensions must be set when "
|
||||
"semantic_embedding_provider='litellm' uses a non-default model. "
|
||||
f"Configured model: {model_name!r}."
|
||||
)
|
||||
provider = LiteLLMEmbeddingProvider(
|
||||
model_name=model_name,
|
||||
batch_size=app_config.semantic_embedding_batch_size,
|
||||
|
||||
@@ -15,6 +15,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import math
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
from basic_memory.repository.embedding_provider import EmbeddingProvider
|
||||
@@ -45,6 +46,24 @@ def _default_input_types(model_name: str) -> tuple[str | None, str | None]:
|
||||
return None, None
|
||||
|
||||
|
||||
def _import_litellm() -> Any:
|
||||
"""Import LiteLLM without letting its import-time dotenv hook read cwd secrets."""
|
||||
# Constraint: LiteLLM 1.85.0 loads .env files at import time when
|
||||
# LITELLM_MODE defaults to DEV. Basic Memory intentionally does not load
|
||||
# arbitrary cwd .env files, so set the production mode before importing
|
||||
# unless the caller already made an explicit LiteLLM choice.
|
||||
os.environ.setdefault("LITELLM_MODE", "PRODUCTION")
|
||||
|
||||
try:
|
||||
import litellm
|
||||
except ImportError as exc:
|
||||
raise SemanticDependenciesMissingError(
|
||||
"litellm dependency is missing. Install with: pip install litellm"
|
||||
) from exc
|
||||
|
||||
return litellm
|
||||
|
||||
|
||||
class LiteLLMEmbeddingProvider(EmbeddingProvider):
|
||||
"""Embedding provider backed by the litellm SDK."""
|
||||
|
||||
@@ -86,12 +105,7 @@ class LiteLLMEmbeddingProvider(EmbeddingProvider):
|
||||
if not texts:
|
||||
return []
|
||||
|
||||
try:
|
||||
import litellm
|
||||
except ImportError as exc:
|
||||
raise SemanticDependenciesMissingError(
|
||||
"litellm dependency is missing. Install with: pip install litellm"
|
||||
) from exc
|
||||
litellm = _import_litellm()
|
||||
|
||||
batches = [
|
||||
texts[start : start + self.batch_size]
|
||||
|
||||
Reference in New Issue
Block a user