File size: 2,819 Bytes
45c5a08
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import os
from typing import List, Dict, Any, Optional
import logging

from openai import AsyncOpenAI

logger = logging.getLogger(__name__)

class Embedder:
    def __init__(self):
        """
        Initialize the embedder with OpenAI-compatible API
        """
        # Use OpenAI-compatible endpoint for Gemini
        base_url = os.getenv("OPENAI_BASE_URL", "https://generativelanguage.googleapis.com/v1beta/openai/")
        api_key = os.getenv("OPENAI_API_KEY")

        if not api_key:
            raise ValueError("OPENAI_API_KEY environment variable is required")

        self.client = AsyncOpenAI(
            base_url=base_url,
            api_key=api_key
        )

        # Use Gemini embedding model
        self.model = os.getenv("EMBEDDING_MODEL", "text-embedding-004")  # Default to a common embedding model
        self.dimension = int(os.getenv("EMBEDDING_DIMENSION", "768"))  # Default to 768

    async def generate_embedding(self, text: str) -> List[float]:
        """
        Generate embedding for a single text
        """
        try:
            response = await self.client.embeddings.create(
                input=text,
                model=self.model
            )

            embedding = response.data[0].embedding
            return embedding
        except Exception as e:
            logger.error(f"Failed to generate embedding: {e}")
            raise

    async def generate_embeddings_batch(self, texts: List[str]) -> List[List[float]]:
        """
        Generate embeddings for a batch of texts
        """
        try:
            # Process in smaller batches to avoid rate limits
            batch_size = 20  # Typical safe batch size
            all_embeddings = []

            for i in range(0, len(texts), batch_size):
                batch = texts[i:i + batch_size]
                response = await self.client.embeddings.create(
                    input=batch,
                    model=self.model
                )

                batch_embeddings = [item.embedding for item in response.data]
                all_embeddings.extend(batch_embeddings)

            return all_embeddings
        except Exception as e:
            logger.error(f"Failed to generate embeddings batch: {e}")
            raise

    async def get_embedding_dimension(self) -> int:
        """
        Get the dimension of the embeddings
        """
        # Test with a short text to determine actual dimension
        test_embedding = await self.generate_embedding("test")
        return len(test_embedding)


# Lazy-initialized embedder instance
_embedder: Optional[Embedder] = None

def get_embedder() -> Embedder:
    """Get or create the Embedder instance (lazy initialization)"""
    global _embedder
    if _embedder is None:
        _embedder = Embedder()
    return _embedder