o
    ZhX1                     @  s   d dl mZ d dl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 d dlmZ d dlmZmZmZ d dlmZmZmZmZ d dlmZmZmZmZmZm Z  e!e"Z#dddZ$dddZ%dddZ&dddZ'dddZ(G dd	 d	eeZ)dS )    )annotationsN)
AnyCallableDictListLiteralOptionalSequenceSetTupleUnion)
Embeddings)get_from_dict_or_envget_pydantic_field_namespre_init)	BaseModel
ConfigDictFieldmodel_validator)AsyncRetryingbefore_sleep_logretryretry_if_exception_typestop_after_attemptwait_exponential
embeddingsLocalAIEmbeddingsreturnCallable[[Any], Any]c                 C  sr   dd l }d}d}tdt| jtd||dt|jjt|jjB t|jj	B t|jj
B t|jjB tttjdS )Nr      
   T   
multiplierminmaxreraisestopwaitr   before_sleep)openair   r   max_retriesr   r   errorTimeoutAPIErrorAPIConnectionErrorRateLimitErrorServiceUnavailableErrorr   loggerloggingWARNING)r   r+   min_secondsmax_seconds r8   ]/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/embeddings/localai.py_create_retry_decorator%   s$   





r:   r   c                   s   dd l }d}d}tdt| jtd||dt|jjt|jjB t|jj	B t|jj
B t|jjB tttjd d fdd}|S )Nr   r   r    Tr!   r"   r&   funcr   r   c                   s   d fdd}|S )	Nargsr   kwargsr   r   c                    s4    2 z3 d H W }| i |I d H   S 6 t d)Nzthis is unreachable)AssertionError)r<   r=   _)async_retryingr;   r8   r9   	wrapped_fQ   s
   z7_async_retry_decorator.<locals>.wrap.<locals>.wrapped_f)r<   r   r=   r   r   r   r8   )r;   rA   r@   )r;   r9   wrapP   s   z$_async_retry_decorator.<locals>.wrap)r;   r   r   r   )r+   r   r   r,   r   r   r-   r.   r/   r0   r1   r2   r   r3   r4   r5   )r   r+   r6   r7   rC   r8   rB   r9   _async_retry_decorator;   s(   





rD   responsedictc                 C  s.   t dd | d D rdd l}|jd| S )Nc                 s  s     | ]}t |d  dkV  qdS )	embeddingr!   N)len).0dr8   r8   r9   	<genexpr>]   s    z"_check_response.<locals>.<genexpr>datar   z'LocalAI API returned an empty embedding)anyr+   r-   r/   )rE   r+   r8   r8   r9   _check_response\   s   rN   r=   c                   s(   t  }|d fdd}|di |S )	)Use tenacity to retry the embedding call.r=   r   r   c                    s    j jdi | }t|S Nr8   )clientcreaterN   r=   rE   r   r8   r9   _embed_with_retryh   s   z+embed_with_retry.<locals>._embed_with_retryNr=   r   r   r   r8   )r:   )r   r=   Zretry_decoratorrU   r8   rT   r9   embed_with_retryd   s   rW   c                   s,   t  d fdd}|di |I dH S )	rO   r=   r   r   c                    s"    j jdi | I d H }t|S rP   )rQ   ZacreaterN   rS   rT   r8   r9   _async_embed_with_retrys   s   z7async_embed_with_retry.<locals>._async_embed_with_retryNrV   r8   )rD   )r   r=   rX   r8   rT   r9   async_embed_with_retryp   s   rY   c                   @  sv  e Zd ZU dZdZded< dZded< eZded< dZd	ed
< dZ	d	ed< dZ
d	ed< dZded< 	 dZd	ed< dZd	ed< e Zded< dZded< dZded< 	 dZded< 	 dZded< 	 dZded< dZded < 	 eed!Zd"ed#< 	 ed$d%d&Zed'd(edFd+d,ZedGd.d/Ze dHd0d1Z!dId5d6Z"dId7d8Z#	9dJdKd>d?Z$	9dJdKd@dAZ%dLdBdCZ&dLdDdEZ'dS )Mr   a  LocalAI embedding models.

    Since LocalAI and OpenAI have 1:1 compatibility between APIs, this class
    uses the ``openai`` Python package's ``openai.Embedding`` as its client.
    Thus, you should have the ``openai`` python package installed, and defeat
    the environment variable ``OPENAI_API_KEY`` by setting to a random string.
    You also need to specify ``OPENAI_API_BASE`` to point to your LocalAI
    service endpoint.

    Example:
        .. code-block:: python

            from langchain_community.embeddings import LocalAIEmbeddings
            openai = LocalAIEmbeddings(
                openai_api_key="random-string",
                openai_api_base="http://localhost:8080"
            )

    Nr   rQ   ztext-embedding-ada-002strmodel
deploymentzOptional[str]openai_api_versionopenai_api_baseopenai_proxyi  intembedding_ctx_lengthopenai_api_keyopenai_organizationzUnion[Literal['all'], Set[str]]allowed_specialallz.Union[Literal['all'], Set[str], Sequence[str]]disallowed_speciali  
chunk_size   r,   z+Optional[Union[float, Tuple[float, float]]]request_timeoutheadersFboolshow_progress_bar)default_factoryDict[str, Any]model_kwargsZforbidr8   )extraZprotected_namespacesbefore)modevaluesr   c              
   C  s   t | }|di }t|D ](}||v rtd| d||vr6td| d| d| d ||||< q|| }|rHtd| d	||d< |S )
z>Build extra kwargs from additional params that were passed in.ro   zFound z supplied twice.z	WARNING! z/ is not default parameter.
                    zJ was transferred to model_kwargs.
                    Please confirm that z is what you intended.zParameters za should be specified explicitly. Instead they were passed in as part of `model_kwargs` parameter.)	r   getlist
ValueErrorwarningswarnpopintersectionkeys)clsrs   Zall_required_field_namesrp   
field_nameZinvalid_model_kwargsr8   r8   r9   build_extra   s,   
zLocalAIEmbeddings.build_extrar   c                 C  s   t |dd|d< t |dddd|d< t |dddd|d< d}t |d	d
|d|d	< t |dddd|d< zddl}|j|d< W |S  tyI   tdw )z?Validate that api key and python package exists in environment.rb   ZOPENAI_API_KEYr^   ZOPENAI_API_BASE )defaultr_   ZOPENAI_PROXYr]   ZOPENAI_API_VERSIONrc   ZOPENAI_ORGANIZATIONr   NrQ   zTCould not import openai python package. Please install it with `pip install openai`.)r   r+   Z	EmbeddingImportError)r|   rs   Zdefault_api_versionr+   r8   r8   r9   validate_environment   sJ   



z&LocalAIEmbeddings.validate_environmentc                 C  sJ   | j | j| j| j| j| j| jd| j}| jr#dd l	}| j| jd|_
|S )N)r[   ri   rj   Zapi_keyZorganizationZapi_baseapi_versionr   )httphttps)r[   ri   rj   rb   rc   r^   r]   ro   r_   r+   proxy)selfZopenai_argsr+   r8   r8   r9   _invocation_params   s    
z$LocalAIEmbeddings._invocation_paramstextengineList[float]c                C  s<   | j dr|dd}t| fd|gi| jd d d S ))Call out to LocalAI's embedding endpoint.001
 inputrL   r   rG   )r[   endswithreplacerW   r   r   r   r   r8   r8   r9   _embedding_func  s   z!LocalAIEmbeddings._embedding_funcc                  sD   | j dr|dd}t| fd|gi| jI dH d d d S )	r   r   r   r   r   NrL   r   rG   )r[   r   r   rY   r   r   r8   r8   r9   _aembedding_func  s    
z"LocalAIEmbeddings._aembedding_funcr   texts	List[str]Optional[int]List[List[float]]c                   s    fdd|D S )aN  Call out to LocalAI's embedding endpoint for embedding search docs.

        Args:
            texts: The list of texts to embed.
            chunk_size: The chunk size of embeddings. If None, will use the chunk size
                specified by the class.

        Returns:
            List of embeddings, one for each text.
        c                   s   g | ]
} j | jd qS )r   r   r\   )rI   r   r   r8   r9   
<listcomp>0  s    z5LocalAIEmbeddings.embed_documents.<locals>.<listcomp>r8   )r   r   rg   r8   r   r9   embed_documents"  s   z!LocalAIEmbeddings.embed_documentsc                   s4   g }|D ]}| j || jdI dH }|| q|S )aT  Call out to LocalAI's embedding endpoint async for embedding search docs.

        Args:
            texts: The list of texts to embed.
            chunk_size: The chunk size of embeddings. If None, will use the chunk size
                specified by the class.

        Returns:
            List of embeddings, one for each text.
        r   N)r   r\   append)r   r   rg   r   r   rE   r8   r8   r9   aembed_documents2  s   z"LocalAIEmbeddings.aembed_documentsc                 C  s   | j || jd}|S )zCall out to LocalAI's embedding endpoint for embedding query text.

        Args:
            text: The text to embed.

        Returns:
            Embedding for the text.
        r   r   r   r   rG   r8   r8   r9   embed_queryE  s   	zLocalAIEmbeddings.embed_queryc                   s   | j || jdI dH }|S )zCall out to LocalAI's embedding endpoint async for embedding query text.

        Args:
            text: The text to embed.

        Returns:
            Embedding for the text.
        r   N)r   r\   r   r8   r8   r9   aembed_queryQ  s   	zLocalAIEmbeddings.aembed_query)rs   rn   r   r   )rs   r   r   r   )r   r   )r   rZ   r   rZ   r   r   )r   )r   r   rg   r   r   r   )r   rZ   r   r   )(__name__
__module____qualname____doc__rQ   __annotations__r[   r\   r]   r^   r_   ra   rb   rc   setrd   rf   rg   r,   ri   rj   rl   r   rF   ro   r   Zmodel_configr   classmethodr~   r   r   propertyr   r   r   r   r   r   r   r8   r8   r8   r9   r   {   sR   
 *


)r   r   r   r   )r   r   r   r   )rE   rF   r   rF   )r   r   r=   r   r   r   )*
__future__r   r4   rw   typingr   r   r   r   r   r   r	   r
   r   r   Zlangchain_core.embeddingsr   Zlangchain_core.utilsr   r   r   Zpydanticr   r   r   r   tenacityr   r   r   r   r   r   	getLoggerr   r3   r:   rD   rN   rW   rY   r   r8   r8   r8   r9   <module>   s    0 
	


!

