import numpy as np import pytest from haiku.rag.config import Config from haiku.rag.embeddings.ollama import Embedder as OllamaEmbedder from haiku.rag.embeddings.openai import Embedder as OpenAIEmbedder from haiku.rag.embeddings.vllm import Embedder as VLLMEmbedder OPENAI_AVAILABLE = bool(Config.providers.api_keys.openai) VOYAGEAI_AVAILABLE = bool(Config.providers.api_keys.voyage) VLLM_EMBEDDINGS_AVAILABLE = bool(Config.providers.vllm.embeddings_base_url) # Calculate cosine similarity def similarities(embeddings, test_embedding): return [ np.dot(embedding, test_embedding) / (np.linalg.norm(embedding) * np.linalg.norm(test_embedding)) for embedding in embeddings ] @pytest.mark.asyncio async def test_ollama_embedder(): embedder = OllamaEmbedder("mxbai-embed-large", 1024) phrases = [ "I enjoy eating great food.", "Python is my favorite programming language.", "I love to travel and see new places.", ] # Test batch embedding embeddings = await embedder.embed(phrases) assert isinstance(embeddings, list) assert len(embeddings) == 3 assert all(isinstance(emb, list) for emb in embeddings) embeddings = [np.array(emb) for emb in embeddings] test_phrase = "I am going for a camping trip." test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[2] test_phrase = "When is dinner ready?" test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[0] test_phrase = "I work as a software developer." test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[1] @pytest.mark.asyncio @pytest.mark.skipif(not OPENAI_AVAILABLE, reason="OpenAI API key not available") async def test_openai_embedder(): embedder = OpenAIEmbedder("text-embedding-3-small", 1536) phrases = [ "I enjoy eating great food.", "Python is my favorite programming language.", "I love to travel and see new places.", ] # Test batch embedding embeddings = await embedder.embed(phrases) assert isinstance(embeddings, list) assert len(embeddings) == 3 assert all(isinstance(emb, list) for emb in embeddings) embeddings = [np.array(emb) for emb in embeddings] test_phrase = "I am going for a camping trip." test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[2] test_phrase = "When is dinner ready?" test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[0] test_phrase = "I work as a software developer." test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[1] @pytest.mark.asyncio @pytest.mark.skipif(not VOYAGEAI_AVAILABLE, reason="VoyageAI API key not available") async def test_voyageai_embedder(): try: from haiku.rag.embeddings.voyageai import Embedder as VoyageAIEmbedder embedder = VoyageAIEmbedder("voyage-3.5", 1024) phrases = [ "I enjoy eating great food.", "Python is my favorite programming language.", "I love to travel and see new places.", ] # Test batch embedding embeddings = await embedder.embed(phrases) assert isinstance(embeddings, list) assert len(embeddings) == 3 assert all(isinstance(emb, list) for emb in embeddings) embeddings = [np.array(emb) for emb in embeddings] test_phrase = "I am going for a camping trip." test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[2] test_phrase = "When is dinner ready?" test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[0] test_phrase = "I work as a software developer." test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[1] except ImportError: pytest.skip("VoyageAI package not installed") @pytest.mark.asyncio @pytest.mark.skipif( not VLLM_EMBEDDINGS_AVAILABLE, reason="vLLM embeddings server not configured" ) async def test_vllm_embedder(): embedder = VLLMEmbedder("mixedbread-ai/mxbai-embed-large-v1", 512) phrases = [ "I enjoy eating great food.", "Python is my favorite programming language.", "I love to travel and see new places.", ] # Test batch embedding embeddings = await embedder.embed(phrases) assert isinstance(embeddings, list) assert len(embeddings) == 3 assert all(isinstance(emb, list) for emb in embeddings) embeddings = [np.array(emb) for emb in embeddings] test_phrase = "I am going for a camping trip." test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[2] test_phrase = "When is dinner ready?" test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[0] test_phrase = "I work as a software developer." test_embedding = await embedder.embed(test_phrase) sims = similarities(embeddings, test_embedding) assert max(sims) == sims[1]