
    $j                        d Z ddlZddlZddlZddlmZmZ ddlmZm	Z	m
Z
 ddlZddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"  ej#        e$          Z% G d de          Z& G d	 d
e&          Z' G d de&          Z( G d de&          Z) G d de&          Z* G d de&          Z+ G d de&          Z, G d de&          Z-de&fdZ.dS )an  
Embeddings abstraction for the memory system.

Provides an interface for generating embeddings with different backends.

The embedding dimension is auto-detected from the model at initialization.
The database schema is automatically adjusted to match the model's dimension.

Configuration via environment variables - see hindsight_api.config for all env var names.
    N)ABCabstractmethod)parse_qsurlparse
urlunparse   )DEFAULT_EMBEDDINGS_COHERE_MODELDEFAULT_EMBEDDINGS_GEMINI_MODEL DEFAULT_EMBEDDINGS_LITELLM_MODEL$DEFAULT_EMBEDDINGS_LITELLM_SDK_MODEL"DEFAULT_EMBEDDINGS_LOCAL_FORCE_CPUDEFAULT_EMBEDDINGS_LOCAL_MODEL*DEFAULT_EMBEDDINGS_LOCAL_TRUST_REMOTE_CODEDEFAULT_EMBEDDINGS_OPENAI_MODELDEFAULT_EMBEDDINGS_PROVIDERDEFAULT_LITELLM_API_BASEENV_EMBEDDINGS_COHERE_API_KEYENV_EMBEDDINGS_GEMINI_API_KEY"ENV_EMBEDDINGS_LITELLM_SDK_API_KEYENV_EMBEDDINGS_LOCAL_FORCE_CPUENV_EMBEDDINGS_LOCAL_MODEL&ENV_EMBEDDINGS_LOCAL_TRUST_REMOTE_CODEENV_EMBEDDINGS_OPENAI_API_KEYENV_EMBEDDINGS_OPENAI_BASE_URLENV_EMBEDDINGS_OPENAI_MODELENV_EMBEDDINGS_PROVIDERENV_EMBEDDINGS_TEI_URLENV_LLM_API_KEYc                       e Zd ZdZeedefd                        Zeedefd                        Z	ed	d            Z
edee         deee                  fd            ZdS )

Embeddingsz
    Abstract base class for embedding generation.

    The embedding dimension is determined by the model and detected at initialization.
    The database schema is automatically adjusted to match the model's dimension.
    returnc                     dS )zFReturn a human-readable name for this provider (e.g., 'local', 'tei').N selfs    g/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/hindsight_api/engine/embeddings.pyprovider_namezEmbeddings.provider_name8   	     	    c                     dS )z6Return the embedding dimension produced by this model.Nr#   r$   s    r&   	dimensionzEmbeddings.dimension>   r(   r)   Nc                 
   K   dS )z
        Initialize the embedding model asynchronously.

        This should be called during startup to load/connect to the model
        and avoid cold start latency on first encode() call.
        Nr#   r$   s    r&   
initializezEmbeddings.initializeD   s       	r)   textsc                     dS )z
        Generate embeddings for a list of texts.

        Args:
            texts: List of text strings to encode

        Returns:
            List of embedding vectors (each is a list of floats)
        Nr#   )r%   r.   s     r&   encodezEmbeddings.encodeN   s	     	r)   r!   N)__name__
__module____qualname____doc__propertyr   strr'   intr+   r-   listfloatr0   r#   r)   r&   r    r    0   s          s    ^ X 3    ^ X    ^ 
DI 
$tE{*; 
 
 
 ^
 
 
r)   r    c                       e Zd ZdZddedz  dedefdZedefd	            Zede	fd
            Z
ddZdee         deee                  fdZdS )LocalSTEmbeddingsz
    Local embeddings implementation using SentenceTransformers.

    Call initialize() during startup to load the model and avoid cold starts.
    The embedding dimension is auto-detected from the model.
    NF
model_name	force_cputrust_remote_codec                 Z    |pt           | _        || _        || _        d| _        d| _        dS )a  
        Initialize local SentenceTransformers embeddings.

        Args:
            model_name: Name of the SentenceTransformer model to use.
                       Default: BAAI/bge-small-en-v1.5
            force_cpu: Force CPU mode for local inference.
                      Default: False
            trust_remote_code: Allow loading models with custom code (security risk).
                              Required for some models with custom architectures.
                              Default: False (disabled for security)
        N)r   r=   r>   r?   _model
_dimension)r%   r=   r>   r?   s       r&   __init__zLocalSTEmbeddings.__init__d   s2     %F(F"!2&*r)   r!   c                     dS )Nlocalr#   r$   s    r&   r'   zLocalSTEmbeddings.provider_namew   s    wr)   c                 <    | j         t          d          | j         S N4Embeddings not initialized. Call initialize() first.rB   RuntimeErrorr$   s    r&   r+   zLocalSTEmbeddings.dimension{   !    ?"UVVVr)   c                   K   | j         dS 	 ddlm} n# t          $ r t          d          w xY wt                              d| j                    ddl}| j        rd}t                              d           nd}	 |j	        
                                p2t          |j        d          o|j        j        
                                }|rd}n4# t          $ r'}t                              d	|            Y d}~nd}~ww xY wt!          j                    5  t!          j        d
t&                     t!          j        d
d           t!          j        d
d           t)          j        d          }|j        }|                    t(          j                   	  || j        |ddi| j                  | _         |                    |           n# |                    |           w xY w	 ddd           n# 1 swxY w Y   | j                                         | _        t                              d| j         d           dS )zLoad the embedding model.Nr   )SentenceTransformerzksentence-transformers is required for LocalSTEmbeddings. Install it with: pip install sentence-transformersz3Embeddings: initializing local provider with model cpuzEmbeddings: forcing CPU modempsz/Failed to detect GPU/MPS, falling back to CPU: ignore)categoryz%.*was not found in model state dict.*)messagez.*UNEXPECTED.*transformerslow_cpu_mem_usageF)devicemodel_kwargsr?   z-Embeddings: local provider initialized (dim: ))rA   sentence_transformersrM   ImportErrorloggerinfor=   torchr>   cudais_availablehasattrbackendsrO   	Exceptionwarningwarningscatch_warningsfilterwarningsUserWarninglogging	getLoggerlevelsetLevelERRORr?    get_sentence_embedding_dimensionrB   )r%   rM   r\   rU   has_gpuetransformers_loggeroriginal_levels           r&   r-   zLocalSTEmbeddings.initialize   s     ;"F	AAAAAAA 	 	 	E  	 	[$/[[\\\
 	 > 	VFKK67777
 FV*1133 ENE22Xu~7I7V7V7X7X   "!F V V VTQRTTUUUUUUUUV $&& 	= 	=#H{CCCC#H6]^^^^#H6FGGGG #*"3N"C"C06N((777	=11O!"5u!=&*&<	   $,,^<<<<#,,^<<<<<'	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	=* +FFHHVDOVVVWWWWWsL    .>AC 
D C;;D BG6 G9G6G&&G66G:=G:r.   c                     | j         t          d          | j                             |dd          }d |D             S )z
        Generate embeddings for a list of texts.

        Args:
            texts: List of text strings to encode

        Returns:
            List of embedding vectors
        NrH   TF)convert_to_numpyshow_progress_barc                 6    g | ]}|                                 S r#   )tolist.0embs     r&   
<listcomp>z,LocalSTEmbeddings.encode.<locals>.<listcomp>   s     333

333r)   )rA   rJ   r0   )r%   r.   
embeddingss      r&   r0   zLocalSTEmbeddings.encode   sL     ;UVVV[''X]'^^
33
3333r)   )NFFr1   )r2   r3   r4   r5   r7   boolrC   r6   r'   r8   r+   r-   r9   r:   r0   r#   r)   r&   r<   r<   \   s         + +3: + +bf + + + +& s    X 3    X
?X ?X ?X ?XB4DI 4$tE{*; 4 4 4 4 4 4r)   r<   c                       e Zd ZdZ	 	 	 	 ddededed	ed
ef
dZedefd            Z	edefd            Z
dededej        fdZddZdee         deee                  fdZdS )RemoteTEIEmbeddingsaE  
    Remote embeddings implementation using HuggingFace Text Embeddings Inference (TEI) HTTP API.

    TEI provides a high-performance inference server for embedding models.
    See: https://github.com/huggingface/text-embeddings-inference

    The embedding dimension is auto-detected from the server at initialization.
          >@             ?base_urltimeout
batch_sizemax_retriesretry_delayc                     |                     d          | _        || _        || _        || _        || _        d| _        d| _        d| _        dS )a  
        Initialize remote TEI embeddings client.

        Args:
            base_url: Base URL of the TEI server (e.g., "http://localhost:8080")
            timeout: Request timeout in seconds (default: 30.0)
            batch_size: Maximum batch size for embedding requests (default: 32)
            max_retries: Maximum number of retries for failed requests (default: 3)
            retry_delay: Initial delay between retries in seconds, doubles each retry (default: 0.5)
        /N)	rstripr   r   r   r   r   _client	_model_idrB   )r%   r   r   r   r   r   s         r&   rC   zRemoteTEIEmbeddings.__init__   sN    $ !,,$&&,0%)&*r)   r!   c                     dS )Nteir#   r$   s    r&   r'   z!RemoteTEIEmbeddings.provider_name   s    ur)   c                 <    | j         t          d          | j         S rG   rI   r$   s    r&   r+   zRemoteTEIEmbeddings.dimension   rK   r)   methodurlc                    ddl }d}| j        }t          | j        dz             D ]V}	 |dk    r | j        j        |fi |}n | j        j        |fi |}|                                 |c S # t          j	        t          j
        t          j        f$ rc}	|	}|| j        k     rLt                              d|dz    d| j        dz    d|	 d| d		           |                    |           |d
z  }Y d}	~	d}	~	wt          j        $ rv}	|	j        j        dk    rZ|| j        k     rO|	}t                              d|dz    d| j        dz    d|	 d| d		           |                    |           |d
z  }n Y d}	~	Pd}	~	ww xY w|)z@Make an HTTP request with automatic retries on transient errors.r   N   GETzTEI request failed (attempt r   z): z. Retrying in zs...r   i  zTEI server error (attempt )timer   ranger   r   getpostraise_for_statushttpxConnectErrorReadTimeoutWriteTimeoutrZ   rb   sleepHTTPStatusErrorresponsestatus_code)
r%   r   r   kwargsr   
last_errordelayattemptr   rn   s
             r&   _request_with_retryz'RemoteTEIEmbeddings._request_with_retry  s   
 T-122 	 	GU??/t|/>>v>>HH0t|0????H))+++&(95;MN   
T---NNzw{zzTEUXYEYzz^_zzotzzz   JJu%%%QJE( 
 
 
:)S00Wt?O5O5O!"JNNxWq[xx4CSVWCWxx\]xxmrxxx   JJu%%%QJEE EEEE
 s&   AA..&E:AC22E:A+E55E:Nc                   K   | j         dS t                              d| j                    t	          j        | j                  | _         	 |                     d| j         d          }|                                }|	                    dd          | _
        d|v rd	|v r	 |                     d
| j         dddgi          }|                                }|r-t          |          dk    rt          |d                   | _        t                              d| j
         d| j         d           dS # t          j        $ r}t          d| j         d|           d}~ww xY w)z:Initialize the HTTP client and verify server connectivity.Nz)Embeddings: initializing TEI provider at )r   r   z/infomodel_idunknownmax_input_lengthmodel_dtypePOST/embedinputstestjsonr   z-Embeddings: TEI provider initialized (model: , dim: rW   z#Failed to connect to TEI server at : )r   rZ   r[   r   r   Clientr   r   r   r   r   lenrB   	HTTPErrorrJ   )r%   r   r[   test_responsetest_embeddingsrn   s         r&   r-   zRemoteTEIEmbeddings.initialize'  s     <#FOOOPPP|DL999	[//$-7N7N7NOOH==??D!XXj)<<DN "T))mt.C.C  !44=((() 5  M
 ,0022O :3#7#7!#;#;"%oa&8"9"9KKqqq_c_nqqqrrrrr 	[ 	[ 	[YT]YYVWYYZZZ	[s   C'D7 7E%E  E%r.   c                    | j         t          d          |sg S g }t          dt          |          | j                  D ]}|||| j        z            }	 |                     d| j         dd|i          }|                                }|                    |           a# t          j
        $ r}t          d|           d}~ww xY w|S )	z
        Generate embeddings using the remote TEI server.

        Args:
            texts: List of text strings to encode

        Returns:
            List of embedding vectors
        NrH   r   r   r   r   r   zTEI embedding request failed: )r   rJ   r   r   r   r   r   r   extendr   r   )r%   r.   all_embeddingsibatchr   batch_embeddingsrn   s           r&   r0   zRemoteTEIEmbeddings.encodeI  s    <UVVV 	I q#e**do66 	I 	IA!a$/112E	I33},,,"E* 4  
 $,==?? %%&67777? I I I"#GA#G#GHHHI s   AB!!C0CC)r~   r   r   r   r1   )r2   r3   r4   r5   r7   r:   r8   rC   r6   r'   r+   r   Responser   r-   r9   r0   r#   r)   r&   r}   r}      s7          + ++ + 	+
 + + + + +6 s    X 3    X
## #C #en # # # #J [  [  [  [D!DI !$tE{*; ! ! ! ! ! !r)   r}   c                       e Zd ZdZddddZedddfded	ed
edz  dedef
dZe	defd            Z
e	defd            ZddZdee         deee                  fdZdS )OpenAIEmbeddingsa  
    OpenAI embeddings implementation using the OpenAI API.

    Supports text-embedding-3-small (1536 dims), text-embedding-3-large (3072 dims),
    and text-embedding-ada-002 (1536 dims, legacy).

    The embedding dimension is auto-detected from the model at initialization.
    i   i   )ztext-embedding-3-smallztext-embedding-3-largeztext-embedding-ada-002Nd   r   api_keymodelr   r   r   c                 h    || _         || _        || _        || _        || _        d| _        d| _        dS )a  
        Initialize OpenAI embeddings client.

        Args:
            api_key: OpenAI API key
            model: OpenAI embedding model name (default: text-embedding-3-small)
            base_url: Custom base URL for OpenAI-compatible API (e.g., Azure OpenAI endpoint)
            batch_size: Maximum batch size for embedding requests (default: 100)
            max_retries: Maximum number of retries for failed requests (default: 3)
        N)r   r   r   r   r   r   rB   )r%   r   r   r   r   r   s         r&   rC   zOpenAIEmbeddings.__init__~  s:    $ 
 $&&*r)   r!   c                     dS )Nopenair#   r$   s    r&   r'   zOpenAIEmbeddings.provider_name      xr)   c                 <    | j         t          d          | j         S rG   rI   r$   s    r&   r+   zOpenAIEmbeddings.dimension  rK   r)   c                 t  K   | j         dS 	 ddlm} n# t          $ r t          d          w xY w| j        r
d| j         nd}t
                              d| j         |            | j        | j	        d}| j        rt          | j                  }|j        ret          |                    d	                    }||d
<   d t          |j                                                  D             }||d<   || _        n
| j        |d
<    |di || _         | j        | j        v r| j        | j                 | _        nR| j         j                            | j        dg          }|j        r$t+          |j        d         j                  | _        t
                              d| j         d| j         d           dS )z2Initialize the OpenAI client and detect dimension.Nr   )OpenAIzLopenai is required for OpenAIEmbeddings. Install it with: pip install openai at  z4Embeddings: initializing OpenAI provider with model )r   r   )queryr   c                 &    i | ]\  }}||d          S )r   r#   )rw   kvs      r&   
<dictcomp>z/OpenAIEmbeddings.initialize.<locals>.<dictcomp>  s"     T T TTQAaD T T Tr)   default_queryr   r   inputz0Embeddings: OpenAI provider initialized (model: r   rW   r#   )r   r   r   rY   r   rZ   r[   r   r   r   r   r   r   _replacer   itemsMODEL_DIMENSIONSrB   rz   createdatar   	embedding)r%   r   base_url_msgclient_kwargsparsed	clean_urlr   r   s           r&   r-   zOpenAIEmbeddings.initialize  s      <#F	n%%%%%%% 	n 	n 	nlmmm	n 26F-dm---Be4:eWceefff
 %)LAQRR= 		:dm,,F| :&vR'@'@AA	,5j) T TXfl5K5K5Q5Q5S5S T T T1>o. ),0Mj)v.... :..."3DJ?DOO |.55jh 6  H } B"%hmA&6&@"A"AltzllZ^Zilllmmmmms    .r.   c                 f   | j         t          d          |sg S g }t          dt          |          | j                  D ]p}|||| j        z            }| j         j                            | j        |          }t          |j	        d           }|
                    d |D                        q|S )z
        Generate embeddings using the OpenAI API.

        Args:
            texts: List of text strings to encode

        Returns:
            List of embedding vectors
        NrH   r   r   c                     | j         S )N)indexxs    r&   <lambda>z)OpenAIEmbeddings.encode.<locals>.<lambda>  s    17 r)   keyc                     g | ]	}|j         
S r#   r   rw   rn   s     r&   ry   z+OpenAIEmbeddings.encode.<locals>.<listcomp>  s    "I"I"I11;"I"I"Ir)   )r   rJ   r   r   r   rz   r   r   sortedr   r   )r%   r.   r   r   r   r   r   s          r&   r0   zOpenAIEmbeddings.encode  s     <UVVV 	I q#e**do66 
	K 
	KA!a$/112E|.55j 6  H  &hm9J9JKKK!!"I"I8H"I"I"IJJJJr)   r1   )r2   r3   r4   r5   r   r   r7   r8   rC   r6   r'   r+   r-   r9   r:   r0   r#   r)   r&   r   r   m  s'         #'"&"&  5#+ ++ + *	+
 + + + + +4 s    X 3    X
)n )n )n )nVDI $tE{*;      r)   r   c                       e Zd ZdZdddddddZedddd	d
fdedededz  dedz  dededefdZ	e
defd            Ze
defd            ZddZdee         deee                  fdZdS )CohereEmbeddingsz
    Cohere embeddings implementation using the Cohere API.

    Supports embed-english-v3.0 (1024 dims) and embed-multilingual-v3.0 (1024 dims).

    The embedding dimension is auto-detected from the model at initialization.
    i   i  i   i   )zembed-english-v3.0zembed-multilingual-v3.0zembed-english-light-v3.0zembed-multilingual-light-v3.0zembed-english-v2.0zembed-multilingual-v2.0N`         N@search_documentr   r   r   output_dimensionsr   r   
input_typec                     || _         || _        || _        || _        || _        || _        || _        d| _        d| _        dS )a  
        Initialize Cohere embeddings client.

        Args:
            api_key: Cohere API key
            model: Cohere embedding model name (default: embed-english-v3.0)
            base_url: Custom base URL for Cohere-compatible API (e.g., Azure-hosted endpoint)
            output_dimensions: Optional output embedding dimensions (for Matryoshka-capable models)
            batch_size: Maximum batch size for embedding requests (default: 96, Cohere's limit)
            timeout: Request timeout in seconds (default: 60.0)
            input_type: Input type for embeddings (default: search_document).
                       Options: search_document, search_query, classification, clustering
        N)	r   r   r   r   r   r   r   r   rB   )r%   r   r   r   r   r   r   r   s           r&   rC   zCohereEmbeddings.__init__  sH    . 
 !2$$&*r)   r!   c                     dS )Ncoherer#   r$   s    r&   r'   zCohereEmbeddings.provider_name#  r   r)   c                 <    | j         t          d          | j         S rG   rI   r$   s    r&   r+   zCohereEmbeddings.dimension'  rK   r)   c                   K   | j         dS 	 ddl}n# t          $ r t          d          w xY w| j        r
d| j         nd}t                              d| j         |            | j        | j        d}| j        r
| j        |d<    |j	        di || _         | j
        | j
        | _        n| j        | j        v r| j        | j                 | _        nh| j                             d	g| j        | j        
          }|j        r9t!          |j        t"                    rt%          |j        d                   | _        t                              d| j         d| j         d           dS )z2Initialize the Cohere client and detect dimension.Nr   zLcohere is required for CohereEmbeddings. Install it with: pip install coherer   r   z4Embeddings: initializing Cohere provider with model )r   r   r   r   r.   r   r   z0Embeddings: Cohere provider initialized (model: r   rW   r#   )r   r   rY   r   rZ   r[   r   r   r   r   r   rB   r   embedr   rz   
isinstancer9   r   )r%   r   r   r   r   s        r&   r-   zCohereEmbeddings.initialize-  s     <#F	nMMMM 	n 	n 	nlmmm	n 26F-dm---Be4:eWceefff %)LT\JJ= 	6(,M*%$v}55}55 !-"4DOOZ4000"3DJ?DOO |))hj? *  H
 " >z(2Et'L'L >"%h&9!&<"="=ltzllZ^Zilllmmmmms    ,r.   c                    | j         t          d          |sg S g }t          dt          |          | j                  D ]}|||| j        z            }| j        T| j         j                            || j        | j	        | j        dg          }|
                    |j        j                   o| j                             || j        | j	                  }|
                    |j                   |S )z
        Generate embeddings using the Cohere API.

        Args:
            texts: List of text strings to encode

        Returns:
            List of embedding vectors
        NrH   r   r:   )r.   r   r   output_dimensionembedding_typesr   )r   rJ   r   r   r   r   v2r   r   r   r   rz   float_)r%   r.   r   r   r   r   s         r&   r0   zCohereEmbeddings.encodeQ  s    <UVVV 	I q#e**do66 	; 	;A!a$/112E%1<?00*#%)%;%,I 1   %%h&9&@AAAA<--*# .  
 %%h&9::::r)   r1   )r2   r3   r4   r5   r   r	   r7   r8   r:   rC   r6   r'   r+   r-   r9   r0   r#   r)   r&   r   r     sO         ##'$'),"#&  5#(,++ ++ + *	+
 :+ + + + + + +B s    X 3    X
"n "n "n "nH(DI ($tE{*; ( ( ( ( ( (r)   r   c                       e Zd ZdZededdfdededz  deded	ef
d
Z	e
defd            Ze
defd            ZddZdee         deee                  fdZdS )LiteLLMEmbeddingsa  
    LiteLLM embeddings implementation using LiteLLM proxy's /embeddings endpoint.

    LiteLLM provides a unified interface for multiple embedding providers.
    The proxy exposes an OpenAI-compatible /embeddings endpoint.
    See: https://docs.litellm.ai/docs/embedding/supported_embedding

    Supported providers via LiteLLM:
    - OpenAI (text-embedding-3-small, text-embedding-ada-002, etc.)
    - Cohere (embed-english-v3.0, etc.) - prefix with cohere/
    - Vertex AI (textembedding-gecko, etc.) - prefix with vertex_ai/
    - HuggingFace, Mistral, Voyage AI, etc.

    The embedding dimension is auto-detected from the model at initialization.
    Nr   r   api_baser   r   r   r   c                     |                     d          | _        || _        || _        || _        || _        d| _        d| _        dS )a,  
        Initialize LiteLLM embeddings client.

        Args:
            api_base: Base URL of the LiteLLM proxy (default: http://localhost:4000)
            api_key: API key for the LiteLLM proxy (optional, depends on proxy config)
            model: Embedding model name (default: text-embedding-3-small)
                   Use provider prefix for non-OpenAI models (e.g., cohere/embed-english-v3.0)
            batch_size: Maximum batch size for embedding requests (default: 100)
            timeout: Request timeout in seconds (default: 60.0)
        r   N)r   r  r   r   r   r   r   rB   )r%   r  r   r   r   r   s         r&   rC   zLiteLLMEmbeddings.__init__  sE    & !,,
$,0&*r)   r!   c                     dS )Nlitellmr#   r$   s    r&   r'   zLiteLLMEmbeddings.provider_name  s    yr)   c                 <    | j         t          d          | j         S rG   rI   r$   s    r&   r+   zLiteLLMEmbeddings.dimension  rK   r)   c                   K   | j         dS t                              d| j         d| j                    ddi}| j        rd| j         |d<   t          j        | j        |          | _         	 | j         	                    | j         d	| j        d
gd          }|
                                 |                                }|                    d          r?t          |d                   dk    r&t          |d         d         d                   | _        t                              d| j         d| j         d           dS # t          j        $ r}t!          d| j         d|           d}~ww xY w)z:Initialize the HTTP client and detect embedding dimension.Nz-Embeddings: initializing LiteLLM provider at z with model zContent-Typezapplication/jsonzBearer Authorization)r   headers/embeddingsr   r   r   r   r   r   z1Embeddings: LiteLLM provider initialized (model: r   rW   z&Failed to connect to LiteLLM proxy at r   )r   rZ   r[   r  r   r   r   r   r   r   r   r   r   r   rB   r   rJ   )r%   r  r   resultrn   s        r&   r-   zLiteLLMEmbeddings.initialize  s     <#FkDMkk_c_ikklll!#56< 	@'?'?'?GO$|DL'JJJ	^|((=---#zVH== )  H %%''']]__Fzz&!! Fc&.&9&9A&=&="%fVnQ&7&D"E"EKKqDJqq_c_nqqqrrrrr 	^ 	^ 	^\\\YZ\\]]]	^s   /CE E3E..E3r.   c                    | j         t          d          |sg S g }t          dt          |          | j                  D ]}|||| j        z            }| j                             | j         d| j        |d          }|                                 |	                                }t          |d         d 	          }|                    d
 |D                        |S )z
        Generate embeddings using the LiteLLM proxy.

        Args:
            texts: List of text strings to encode

        Returns:
            List of embedding vectors
        NrH   r   r	  r   r   r   c                     | d         S )Nr   r#   r   s    r&   r   z*LiteLLMEmbeddings.encode.<locals>.<lambda>  s
    AgJ r)   r   c                     g | ]
}|d          S r   r#   r   s     r&   ry   z,LiteLLMEmbeddings.encode.<locals>.<listcomp>  s    "L"L"La1[>"L"L"Lr)   )r   rJ   r   r   r   r   r  r   r   r   r   r   )r%   r.   r   r   r   r   r
  r   s           r&   r0   zLiteLLMEmbeddings.encode  s    <UVVV 	I q#e**do66 	N 	NA!a$/112E|((=---#zE:: )  H %%''']]__F  &fVn:N:NOOO!!"L"L;K"L"L"LMMMMr)   r1   )r2   r3   r4   r5   r   r   r7   r8   r:   rC   r6   r'   r+   r-   r9   r0   r#   r)   r&   r   r   |  s        $ 1"5+ ++ t+ 	+
 + + + + +6 s    X 3    X
^ ^ ^ ^6!DI !$tE{*; ! ! ! ! ! !r)   r   c                       e Zd ZdZedddddfdedededz  d	edz  d
edededz  fdZe	defd            Z
e	defd            ZddZdee         deee                  fdZdS )LiteLLMSDKEmbeddingsa  
    LiteLLM SDK embeddings for direct API integration.

    Supports embeddings via LiteLLM SDK without requiring a proxy server.
    Supported providers: Cohere, OpenAI, Azure OpenAI, HuggingFace, Voyage AI, Together AI, etc.

    Example model names:
    - cohere/embed-english-v3.0
    - openai/text-embedding-3-small
    - together_ai/togethercomputer/m2-bert-80M-8k-retrieval
    - voyage/voyage-2
    Nr   r   r:   r   r   r  r   r   r   encoding_formatc                     || _         || _        || _        || _        || _        || _        |pd| _        d| _        d| _        dS )a  
        Initialize LiteLLM SDK embeddings client.

        Args:
            api_key: API key for the embedding provider
            model: Model name with provider prefix (e.g., "cohere/embed-english-v3.0")
            api_base: Custom base URL for API (optional)
            output_dimensions: Optional output embedding dimensions (provider-dependent)
            batch_size: Maximum batch size for embedding requests (default: 100)
            timeout: Request timeout in seconds (default: 60.0)
            encoding_format: Encoding format for embeddings (default: "float").
                Set to None or empty string to omit (needed for Voyage AI, Gemini).
        N)	r   r   r  r   r   r   r  _litellmrB   )r%   r   r   r  r   r   r   r  s           r&   rC   zLiteLLMSDKEmbeddings.__init__  sN    . 
 !2$.6$&*r)   r!   c                     dS )Nlitellm-sdkr#   r$   s    r&   r'   z"LiteLLMSDKEmbeddings.provider_name   s    }r)   c                 <    | j         t          d          | j         S rG   rI   r$   s    r&   r+   zLiteLLMSDKEmbeddings.dimension$  rK   r)   c                 0  K   | j         dS 	 ddl}|| _         n# t          $ r t          d          w xY w| j        r
d| j         nd}t                              d| j         |            	 | j        dg| j        d}| j        r
| j        |d	<   | j        r
| j        |d
<   | j	        *| j	        |d<   | j        
                    d          rdg|d<    | j         j        di | d{V }|j        r>t          |j                  dk    r&t          |j        d         d                   | _        nt          d| j                   n$# t           $ r}t          d|           d}~ww xY wt                              d| j         d| j         d           dS )z7Initialize the LiteLLM SDK client and detect dimension.Nr   zRlitellm is required for LiteLLMSDKEmbeddings. Install it with: pip install litellmr   r   z9Embeddings: initializing LiteLLM SDK provider with model r   r   r   r   r  r  
dimensionsopenai/allowed_openai_paramsr   z/Unable to detect embedding dimension for model z-Failed to initialize LiteLLM SDK embeddings: z5Embeddings: LiteLLM SDK provider initialized (model: r   rW   r#   )r  r  rY   r  rZ   r[   r   r   r  r   
startswith
aembeddingr   r   rB   rJ   ra   )r%   r  api_base_msgembed_kwargsr   rn   s         r&   r-   zLiteLLMSDKEmbeddings.initialize*  s)     =$F	tNNN#DMM 	t 	t 	trsss	t 26F-dm---BjPTPZj\hjjkkk	T  < L
 # G262F./} 9+/=Z(%1-1-C\*:((33 K=INL!89 6T]5EEEEEEEEEEH } cX]!3!3a!7!7"%hmA&6{&C"D"D"#aUYU_#a#abbb    	T 	T 	TRqRRSSS	T 	qDJqq_c_nqqqrrrrrs!    3.CE 
E(E##E(r.   c                    | j         t          d          |sg S g }t          dt          |          | j                  D ]}|||| j        z            }	 | j        || j        d}| j        r
| j        |d<   | j        r
| j        |d<   | j	        *| j	        |d<   | j        
                    d          rdg|d	<    | j         j        di |}t          |j        d
           }|                    d |D                        # t          $ r?}ddl}	t"                              d| d| d|	                                             d}~ww xY w|S )z
        Generate embeddings using the LiteLLM SDK.

        Args:
            texts: List of text strings to encode

        Returns:
            List of embedding vectors (one per input text)
        NrH   r   r  r  r  r  r  r  c                 .    |                      dd          S )Nr   r   )r   r   s    r&   r   z-LiteLLMSDKEmbeddings.encode.<locals>.<lambda>  s    quuWVWGXGX r)   r   c                     g | ]
}|d          S r   r#   r   s     r&   ry   z/LiteLLMSDKEmbeddings.encode.<locals>.<listcomp>  s    &P&P&P!q~&P&P&Pr)   z7Error in LiteLLM embedding for batch starting at index r   z
Traceback: r#   )r  rJ   r   r   r   r   r   r  r  r   r  r   r   r   r   ra   	tracebackrZ   error
format_exc)
r%   r.   r   r   r   r  r   r   rn   r"  s
             r&   r0   zLiteLLMSDKEmbeddings.encodeX  s    = UVVV 	I q#e**do66 "	 "	A!a$/112E "Z"#|   
 ' K6:6JL!23= =/3}L,)5151GL.z,,Y77 OAM%<= 34=2BB\BB $*(-=X=X#Y#Y#Y %%&P&P?O&P&P&PQQQQ       ;a ; ;ST ; ;"+"6"6"8"8; ;    s   B+D
E:EEr1   )r2   r3   r4   r5   r   r7   r8   r:   rC   r6   r'   r+   r-   r9   r0   r#   r)   r&   r  r    s2          :#(,&-+ ++ + *	+
 :+ + + t+ + + +B s    X 3    X
,s ,s ,s ,s\7DI 7$tE{*; 7 7 7 7 7 7r)   r  c                       e Zd ZdZedddddddfdededz  dedz  dedz  d	edz  d
edz  dedefdZe	defd            Z
e	defd            ZddZddZddZdee         deee                  fdZdS )GeminiEmbeddingsa2  
    Google embeddings via the google.genai SDK.

    Supports both:
    1. Gemini API (api.generativeai.google.com) with API key authentication
    2. Vertex AI with service account or Application Default Credentials (ADC)

    Uses the embed_content API: client.models.embed_content(model, contents)
    Nr   Fr   r   vertexai_project_idvertexai_regionvertexai_service_account_keyoutput_dimensionalityr   
force_ipv4c	                     || _         || _        || _        |pd| _        || _        || _        || _        || _        d | _        d | _	        d | _
        |d u| _        d | _        d S )Nzus-central1)r   r   r'  r(  r)  r*  r   r+  r   _httpx_clientrB   _is_vertexai_embed_config)	r%   r   r   r'  r(  r)  r*  r   r+  s	            r&   rC   zGeminiEmbeddings.__init__  sv     
#6 .?-,H)%:"$$!&*/t;!r)   r!   c                     dS )Ngoogler#   r$   s    r&   r'   zGeminiEmbeddings.provider_name  r   r)   c                 <    | j         t          d          | j         S rG   rI   r$   s    r&   r+   zGeminiEmbeddings.dimension  rK   r)   c           	      F  K   | j         dS ddlm} ddlm} | j        r|                     |           n|                     ||           | j         |	                    | j                  | _
        | j        dgd}| j
        
| j
        |d<    | j         j        j        di |}|j        r<t          |j                  dk    r$t          |j        d         j                  | _        | j        rd	nd
}t$                              d| d| j         d| j         d           dS )zBInitialize the Google genai client and detect embedding dimension.Nr   )genai)types)r*  r   r   contentsconfig	vertex_air   z/Embeddings: google provider initialized (auth: z	, model: r   rW   r#   )r   r1  r4  google.genair5  r.  _init_vertexai_init_geminir*  EmbedContentConfigr/  r   modelsembed_contentrz   r   valuesrB   rZ   r[   )r%   r4  genai_typesr  r
  	auth_modes         r&   r-   zGeminiEmbeddings.initialize  su     <#F      555555 	2&&&&e[111 %1!,!?!?&*&@ "@ " "D
 "&&BB)%)%7L"2$2BB\BB 	?V%6!7!7!!;!;!&"3A"6"=>>DO#'#4CKK)	wiwwRVR\wweietwww	
 	
 	
 	
 	
r)   c                 L   | j         st          d          d| j         i}| j        rIddl} |j        d |j        d                    | _        |                    d	| j        
          |d<    |j        di || _        t          
                    d| j                    dS )z*Initialize Gemini API client with API key.z.Gemini embeddings provider requires an API keyr   r   N
   z0.0.0.0)local_address)r   	transporti'  )r   httpxClienthttp_optionsz4Embeddings: initializing Gemini provider with model r#   )r   
ValueErrorr+  r   r   HTTPTransportr-  HttpOptionsr   rZ   r[   r   )r%   r4  rA  r   r   s        r&   r<  zGeminiEmbeddings._init_gemini  s    | 	OMNNN"DL1? 
	LLL!--%-IFFF" " "D -8,C,C . -D - -M.)
 $u|44m44W4:WWXXXXXr)   c                 R   | j         st          d          d}d}| j        rk	 ddlm} n# t
          $ r t          d          w xY w|j                            | j        dg          }d	}t          	                    d
| j                    | j
                            d          r!| j
        t          d          d         | _
        d| j         | j        d}|||d<    |j        di || _        t          	                    d| j          d| j         d| j
         d| d	           dS )zBInitialize Vertex AI client with project, region, and credentials.zHINDSIGHT_API_EMBEDDINGS_VERTEXAI_PROJECT_ID (or HINDSIGHT_API_LLM_VERTEXAI_PROJECT_ID) is required for Vertex AI embeddings provider.ADCNr   )service_accountzdVertex AI service account auth requires 'google-auth' package. Install with: pip install google-authz.https://www.googleapis.com/auth/cloud-platform)scopesrN  z1Embeddings: Vertex AI using service account key: zgoogle/T)vertexaiprojectlocationcredentialsz5Embeddings: initializing Vertex AI provider (project=z	, region=z, model=z, auth=rW   r#   )r'  rI  r)  google.oauth2rN  rY   Credentialsfrom_service_account_filerZ   r[   r   r  r   r(  r   r   )r%   r4  auth_methodrS  rN  r   s         r&   r;  zGeminiEmbeddings._init_vertexai  s   ' 	A  
 , 	q9999999   !<  
 *5OO1HI P  K ,KKKoDLmooppp :  ++ 	6C	NN$4$45DJ /,
 

 "+6M-(#u|44m44707 7;?;O7 7Z7 7(37 7 7	
 	
 	
 	
 	
s	   * Ar.   c                    | j         t          d          |sg S g }t          dt          |          | j                  D ]j}|||| j        z            }| j        |d}| j        
| j        |d<    | j         j        j        d
i |}|	                    d |j
        D                        k| j        Vddl}|                    |          }|j                            |dd	          }	d|	|	dk    <   ||	z                                  }|S )z
        Generate embeddings using the Google genai SDK.

        Args:
            texts: List of text strings to encode

        Returns:
            List of embedding vectors
        NrH   r   r6  r8  c                     g | ]	}|j         
S r#   )r@  rv   s     r&   ry   z+GeminiEmbeddings.encode.<locals>.<listcomp>?  s    "K"K"K#3:"K"K"Kr)   r   T)axiskeepdimsr#   )r   rJ   r   r   r   r   r/  r>  r?  r   rz   r*  numpyarraylinalgnormru   )
r%   r.   r   r   r   r  r
  nparrnormss
             r&   r0   zGeminiEmbeddings.encode#  s?    <UVVV 	I q#e**do66 		M 		MA!a$/112E%)ZUCCL!-)-);X&6T\(6FFFFF!!"K"K9J"K"K"KLLLL
 %1((>**CINN3QN>>E !E%1*!Ek1133Nr)   r1   )r2   r3   r4   r5   r
   r7   r8   r{   rC   r6   r'   r+   r-   r<  r;  r9   r:   r0   r#   r)   r&   r&  r&    sr         5"*.&*37,0 " "" t" !4Z	"
 t" '*Dj"  #Tz" " " " " "2 s    X 3    X

 
 
 
BY Y Y Y*+
 +
 +
 +
Z)DI )$tE{*; ) ) ) ) ) )r)   r&  r!   c            	         ddl m}   |             }|j                                        }|dk    r8|j        }|st          t           dt           d          t          |          S |dk    r!t          |j
        |j        |j                  S |d	k    rt          j                            t                     p#t          j                            t"                    }|s't          t            d
t"           dt           d          t          j                            t$          t&                    }t          j                            t(                    pd}t+          ||||j                  S |dk    rF|j        }|s t          dt"           dt           d          t+          ||j        d|j                  S |dk    rJ|j        }|st          t4           dt           d          t7          ||j        |j        |j                  S |dk    r!t?          |j         |j!        |j"                  S |dk    rP|j#        }|st          tH           dt           d          tK          ||j&        |j'        |j(        |j)                  S |dk    rk|j*        }|rd}n0|j+        }|s't          tX           d
t"           dt           d          t[          |j.        |||j/        |j0        |j1        |j2                  S t          d| d          )z
    Create an Embeddings instance based on configuration.

    Reads configuration via get_config() to ensure consistency across the codebase.

    Returns:
        Configured Embeddings instance
    r   )
get_configr   z is required when z	 is 'tei')r   rE   )r=   r>   r?   r   z or z is 'openai'N)r   r   r   r   
openrouterzRHINDSIGHT_API_EMBEDDINGS_OPENROUTER_API_KEY, HINDSIGHT_API_OPENROUTER_API_KEY, or z is 'openrouter'zhttps://openrouter.ai/api/v1r   z is 'cohere')r   r   r   r   r  )r  r   r   r  z is 'litellm-sdk')r   r   r  r   r  r1  zA is 'google' (set VERTEXAI_PROJECT_ID for Vertex AI auth instead))r   r   r'  r(  r)  r*  r+  zUnknown embeddings provider: zS. Supported: 'local', 'tei', 'openai', 'cohere', 'google', 'litellm', 'litellm-sdk')3r8  rd  embeddings_providerlowerembeddings_tei_urlrI  r   r   r}   r<   embeddings_local_modelembeddings_local_force_cpu"embeddings_local_trust_remote_codeosenvironr   r   r   r   r   r   r   embeddings_openai_batch_sizeembeddings_openrouter_api_keyembeddings_openrouter_modelembeddings_cohere_api_keyr   r   embeddings_cohere_modelembeddings_cohere_base_url#embeddings_cohere_output_dimensionsr   embeddings_litellm_api_baseembeddings_litellm_api_keyembeddings_litellm_modelembeddings_litellm_sdk_api_keyr   r  embeddings_litellm_sdk_modelembeddings_litellm_sdk_api_base(embeddings_litellm_sdk_output_dimensions&embeddings_litellm_sdk_encoding_formatembeddings_vertexai_project_idembeddings_gemini_api_keyr   r&  embeddings_gemini_modelembeddings_vertexai_region'embeddings_vertexai_service_account_key'embeddings_gemini_output_dimensionalityembeddings_gemini_force_ipv4)rd  r8  providerr   r   r   r   r'  s           r&   create_embeddings_from_envr  O  s
    $#####Z\\F)//11H5' 	n 6llJalllmmm"C0000	W		 47$G
 
 
 	

 
X		*..!>??b2:>>RaCbCb 	0 > >o > >/> > >   
:<[\\:>>"@AAIT:	
 
 
 	
 
\	!	!6 	c%c c9Pc c c    43:	
 
 
 	
 
X		2 	x =vvQhvvvwww06$H	
 
 
 	
 
Y		 751
 
 
 	

 
]	"	"7 	5ssI`sss   $5;$M"I
 
 
 	
 
X		$C 	GG6G  4 w w/ w w3w w w    0 3"=)/)W"("P:
 
 
 	
 aH a a a
 
 	
r)   )/r5   rg   rl  rc   abcr   r   urllib.parser   r   r   r   r8  r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rh   r2   rZ   r    r<   r}   r   r   r   r  r&  r  r#   r)   r&   <module>r     s+  	 	  				  # # # # # # # # 7 7 7 7 7 7 7 7 7 7                                                2 
	8	$	$) ) ) ) ) ) ) )Xt4 t4 t4 t4 t4
 t4 t4 t4nW W W W W* W W Wt    z   DJ J J J Jz J J JZr r r r r
 r r rj^ ^ ^ ^ ^: ^ ^ ^Bz z z z zz z z zzk
J k
 k
 k
 k
 k
 k
r)   