feat(knowledgebase): replace litellm-pgvector connector with memory-retrieval
Per docs/research/langchain-pgvector-vs-litellm-pgvector.md (issue #25): the vendored litellm-pgvector connector (793 lines, Prisma migrations, a fragile git-context build) is replaced by a ~90-line FastAPI service (services/memory-retrieval/) wrapping langchain_postgres.PGVector directly against pgvector-db. Same gateway boundary — it still calls litellm for embeddings, nothing talks to Postgres or the model directly except this service. - New services/memory-retrieval/ (main.py, Dockerfile, requirements.txt): POST /ingest, POST /query, GET /health. - docker-compose.yml: litellm-pgvector service replaced by memory-retrieval; pgvector-db and embedding-server untouched. - litellm-config.yaml: vector_store_registry block removed (no langchain_postgres provider exists to register against; callers query memory-retrieval directly instead of an in-band file_search tool call — that mechanism was never confirmed working per issue #24 anyway). - scripts/ingest-memory.sh rewritten for the new /ingest endpoint (same per-line chunking, no dedup). - .env vars renamed: LITELLM_PGVECTOR_API_KEY/LITELLM_PGVECTOR_EMBEDDING_KEY -> MEMORY_RETRIEVAL_API_KEY/MEMORY_RETRIEVAL_EMBEDDING_KEY. - vendor/litellm-pgvector/ removed entirely. - docs/memory-knowledgebase.md updated for the new setup/query flow. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
-90
@@ -1,90 +0,0 @@
|
||||
from typing import List, Optional
|
||||
from config import settings, EmbeddingConfig
|
||||
from litellm.types.utils import EmbeddingResponse
|
||||
import litellm
|
||||
import logging
|
||||
|
||||
class EmbeddingService:
|
||||
"""Service for generating embeddings using OpenAI SDK pointed at LiteLLM proxy"""
|
||||
|
||||
def __init__(self, config: Optional[EmbeddingConfig] = None):
|
||||
self.config = config or settings.embedding
|
||||
|
||||
|
||||
|
||||
async def generate_embedding(self, text: str) -> List[float]:
|
||||
"""
|
||||
Generate embedding for a single text using LiteLLM proxy
|
||||
|
||||
Args:
|
||||
text: Text to embed
|
||||
|
||||
Returns:
|
||||
List of floats representing the embedding vector
|
||||
"""
|
||||
try:
|
||||
response: EmbeddingResponse = await litellm.aembedding(
|
||||
model=self.config.model,
|
||||
input=[text],
|
||||
api_base=self.config.base_url,
|
||||
api_key=self.config.api_key
|
||||
)
|
||||
logging.debug(f"Embedding response: {response}")
|
||||
|
||||
# Extract embedding from response
|
||||
embedding = response.data[0]["embedding"]
|
||||
|
||||
# Validate embedding dimensions
|
||||
if len(embedding) != self.config.dimensions:
|
||||
raise ValueError(
|
||||
f"Expected embedding dimension {self.config.dimensions}, "
|
||||
f"got {len(embedding)}"
|
||||
)
|
||||
|
||||
return embedding
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to generate embedding: {str(e)}")
|
||||
|
||||
async def generate_embeddings(self, texts: List[str]) -> List[List[float]]:
|
||||
"""
|
||||
Generate embeddings for multiple texts
|
||||
|
||||
Args:
|
||||
texts: List of texts to embed
|
||||
|
||||
Returns:
|
||||
List of embedding vectors
|
||||
"""
|
||||
try:
|
||||
# Generate embeddings using LiteLLM
|
||||
response = await litellm.aembedding(
|
||||
model=self.config.model,
|
||||
input=texts,
|
||||
api_base=self.config.base_url,
|
||||
api_key=self.config.api_key
|
||||
)
|
||||
|
||||
# Extract embeddings from response
|
||||
embeddings = [item.embedding for item in response.data]
|
||||
|
||||
# Validate embedding dimensions
|
||||
for i, embedding in enumerate(embeddings):
|
||||
if len(embedding) != self.config.dimensions:
|
||||
raise ValueError(
|
||||
f"Expected embedding dimension {self.config.dimensions} for text {i}, "
|
||||
f"got {len(embedding)}"
|
||||
)
|
||||
|
||||
return embeddings
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Failed to generate embeddings: {str(e)}")
|
||||
|
||||
def update_config(self, new_config: EmbeddingConfig):
|
||||
"""Update the embedding configuration"""
|
||||
self.config = new_config
|
||||
|
||||
|
||||
# Global embedding service instance
|
||||
embedding_service = EmbeddingService()
|
||||
Reference in New Issue
Block a user