
    NgB                        d Z ddlmZ ddlmZmZmZmZ ddlZ	ddl
mZmZmZ ddlmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZmZ ddlmZ defdZ G d dee          Z G d de          Z G d dee          Z  G d dee          Z!dS )z@A chain for comparing the output of two models using embeddings.    )Enum)AnyDictListOptionalN)AsyncCallbackManagerForChainRunCallbackManagerForChainRun	Callbacks)
Embeddings)pre_init)
ConfigDictField)Chain)PairwiseStringEvaluatorStringEvaluatorRUN_KEYreturnc                      	 ddl m}  n5# t          $ r( 	 ddlm}  n# t          $ r t          d          w xY wY nw xY w |             S )zaCreate an Embeddings object.
    Returns:
        Embeddings: The created Embeddings object.
    r   OpenAIEmbeddingstCould not import OpenAIEmbeddings. Please install the OpenAIEmbeddings package using `pip install langchain-openai`.)langchain_openair   ImportError%langchain_community.embeddings.openair   s    h/var/www/html/ai-engine/env/lib/python3.11/site-packages/langchain/evaluation/embedding_distance/base.py_embedding_factoryr      s    	5555555   	NNNNNNN 	 	 	Q  	 ON s   	 
;;5;;c                   &    e Zd ZdZdZdZdZdZdZdS )EmbeddingDistancea  Embedding Distance Metric.

    Attributes:
        COSINE: Cosine distance metric.
        EUCLIDEAN: Euclidean distance metric.
        MANHATTAN: Manhattan distance metric.
        CHEBYSHEV: Chebyshev distance metric.
        HAMMING: Hamming distance metric.
    cosine	euclidean	manhattan	chebyshevhammingN)	__name__
__module____qualname____doc__COSINE	EUCLIDEAN	MANHATTAN	CHEBYSHEVHAMMING     r   r   r   *   s3          FIIIGGGr/   r   c                   f   e Zd ZU dZ ee          Zeed<    ee	j
                  Ze	ed<   edeeef         deeef         fd            Z ed	
          Zedee         fd            ZdedefdZde	defdZedej        dej        dej        fd            Zedej        dej        dej        fd            Zedej        dej        dej        fd            Zedej        dej        dej        fd            Z edej        dej        dej        fd            Z!dej        de"fdZ#dS )_EmbeddingDistanceChainMixina0  Shared functionality for embedding distance evaluators.

    Attributes:
        embeddings (Embeddings): The embedding objects to vectorize the outputs.
        distance_metric (EmbeddingDistance): The distance metric to use
                                            for comparing the embeddings.
    )default_factory
embeddings)defaultdistance_metricvaluesr   c                    |                     d          }g }	 ddlm} |                    |           n# t          $ r Y nw xY w	 ddlm} |                    |           n# t          $ r Y nw xY w|st	          d          t          |t          |                    r#	 ddl}n# t          $ r t	          d          w xY w|S )zValidate that the TikTok library is installed.

        Args:
            values (Dict[str, Any]): The values to validate.

        Returns:
            Dict[str, Any]: The validated values.
        r3   r   r   r   NzThe tiktoken library is required to use the default OpenAI embeddings with embedding distance evaluators. Please either manually select a different Embeddings object or install tiktoken using `pip install tiktoken`.)	getr   r   appendr   r   
isinstancetupletiktoken)clsr6   r3   types_r   r<   s         r   _validate_tiktoken_installedz9_EmbeddingDistanceChainMixin._validate_tiktoken_installedH   s:    ZZ--
	999999MM*++++ 	 	 	D		NNNNNNMM*++++ 	 	 	D	  	Q  
 j%--00 		   !I   s-   5 
AAA" "
A/.A/!B& &C T)arbitrary_types_allowedc                     dgS )zgReturn the output keys of the chain.

        Returns:
            List[str]: The output keys.
        scorer.   selfs    r   output_keysz(_EmbeddingDistanceChainMixin.output_keysx   s     yr/   resultc                 V    d|d         i}t           |v r|t                    |t           <   |S )NrB   r   )rD   rF   parseds      r   _prepare_outputz,_EmbeddingDistanceChainMixin._prepare_output   s-    6'?+f$WoF7Or/   metricc           
          t           j        | j        t           j        | j        t           j        | j        t           j        | j        t           j	        | j
        i}||v r||         S t          d|           )zGet the metric function for the given metric name.

        Args:
            metric (EmbeddingDistance): The metric name.

        Returns:
            Any: The metric function.
        zInvalid metric: )r   r)   _cosine_distancer*   _euclidean_distancer+   _manhattan_distancer,   _chebyshev_distancer-   _hamming_distance
ValueError)rD   rJ   metricss      r   _get_metricz(_EmbeddingDistanceChainMixin._get_metric   sp     $d&;')A')A')A%t'=
 W6?"888999r/   abc                 j    	 ddl m} n# t          $ r t          d          w xY wd || |          z
  S )zCompute the cosine distance between two vectors.

        Args:
            a (np.ndarray): The first vector.
            b (np.ndarray): The second vector.

        Returns:
            np.ndarray: The cosine distance.
        r   )cosine_similarityzThe cosine_similarity function is required to compute cosine distance. Please install the langchain-community package using `pip install langchain-community`.g      ?)langchain_community.utils.mathrW   r   )rT   rU   rW   s      r   rL   z-_EmbeddingDistanceChainMixin._cosine_distance   si    	HHHHHHH 	 	 	6  	 &&q!,,,,s   	 #c                 F    t           j                            | |z
            S )zCompute the Euclidean distance between two vectors.

        Args:
            a (np.ndarray): The first vector.
            b (np.ndarray): The second vector.

        Returns:
            np.floating: The Euclidean distance.
        )nplinalgnormrT   rU   s     r   rM   z0_EmbeddingDistanceChainMixin._euclidean_distance   s     y~~a!e$$$r/   c                 T    t          j        t          j        | |z
                      S )zCompute the Manhattan distance between two vectors.

        Args:
            a (np.ndarray): The first vector.
            b (np.ndarray): The second vector.

        Returns:
            np.floating: The Manhattan distance.
        )rZ   sumabsr]   s     r   rN   z0_EmbeddingDistanceChainMixin._manhattan_distance         vbfQUmm$$$r/   c                 T    t          j        t          j        | |z
                      S )zCompute the Chebyshev distance between two vectors.

        Args:
            a (np.ndarray): The first vector.
            b (np.ndarray): The second vector.

        Returns:
            np.floating: The Chebyshev distance.
        )rZ   maxr`   r]   s     r   rO   z0_EmbeddingDistanceChainMixin._chebyshev_distance   ra   r/   c                 2    t          j        | |k              S )zCompute the Hamming distance between two vectors.

        Args:
            a (np.ndarray): The first vector.
            b (np.ndarray): The second vector.

        Returns:
            np.floating: The Hamming distance.
        )rZ   meanr]   s     r   rP   z._EmbeddingDistanceChainMixin._hamming_distance   s     wqAvr/   vectorsc                     |                      | j                  } ||d                             dd          |d                             dd                                                    }|S )zCompute the score based on the distance metric.

        Args:
            vectors (np.ndarray): The input vectors.

        Returns:
            float: The computed score.
        r      )rS   r5   reshapeitem)rD   rf   rJ   rB   s       r   _compute_scorez+_EmbeddingDistanceChainMixin._compute_score   sd     !!$"677wqz))!R00'!*2D2DQ2K2KLLQQSSr/   N)$r%   r&   r'   r(   r   r   r3   r   __annotations__r   r)   r5   r   r   strr   r?   r   model_configpropertyr   rE   dictrI   rS   staticmethodrZ   ndarrayrL   floatingrM   rN   rO   rP   floatrl   r.   r/   r   r1   r1   <   su          #U3EFFFJ
FFF).7H7O)P)P)PO&PPP)$sCx. )T#s(^ ) ) ) X)V : $  L T#Y    Xd t    :"3 : : : : :* -BJ -2: -"* - - - \-( 
%rz 
%bj 
%R[ 
% 
% 
% \
% 
%rz 
%bj 
%R[ 
% 
% 
% \
% 
%rz 
%bj 
%R[ 
% 
% 
% \
% 
RZ 
BJ 
2; 
 
 
 \
bj U      r/   r1   c                      e Zd ZdZedefd            Zedefd            Zede	e         fd            Z
	 ddeeef         dee         deeef         fd	Z	 ddeeef         dee         deeef         fd
Zdddddddedee         dedee	e                  deeeef                  dededefdZdddddddedee         dedee	e                  deeeef                  dededefdZdS )EmbeddingDistanceEvalChaina"  Use embedding distances to score semantic difference between
    a prediction and reference.

    Examples:
        >>> chain = EmbeddingDistanceEvalChain()
        >>> result = chain.evaluate_strings(prediction="Hello", reference="Hi")
        >>> print(result)
        {'score': 0.5}
    r   c                     dS )zReturn whether the chain requires a reference.

        Returns:
            bool: True if a reference is required, False otherwise.
        Tr.   rC   s    r   requires_referencez-EmbeddingDistanceEvalChain.requires_reference   s	     tr/   c                 "    d| j         j         dS )N
embedding_	_distancer5   valuerC   s    r   evaluation_namez*EmbeddingDistanceEvalChain.evaluation_name  s    AD06AAAAr/   c                 
    ddgS )eReturn the input keys of the chain.

        Returns:
            List[str]: The input keys.
        
prediction	referencer.   rC   s    r   
input_keysz%EmbeddingDistanceEvalChain.input_keys  s     k**r/   Ninputsrun_managerc                     t          j        | j                            |d         |d         g                    }|                     |          }d|iS )a0  Compute the score for a prediction and reference.

        Args:
            inputs (Dict[str, Any]): The input data.
            run_manager (Optional[CallbackManagerForChainRun], optional):
                The callback manager.

        Returns:
            Dict[str, Any]: The computed score.
        r   r   rB   rZ   arrayr3   embed_documentsrl   rD   r   r   rf   rB   s        r   _callz EmbeddingDistanceEvalChain._call  sW     (O++VL-A6+CV,WXX
 
 ##G,,r/   c                    K   | j                             |d         |d         g           d{V }t          j        |          }|                     |          }d|iS )a:  Asynchronously compute the score for a prediction and reference.

        Args:
            inputs (Dict[str, Any]): The input data.
            run_manager (AsyncCallbackManagerForChainRun, optional):
                The callback manager.

        Returns:
            Dict[str, Any]: The computed score.
        r   r   NrB   r3   aembed_documentsrZ   r   rl   rD   r   r   embeddedrf   rB   s         r   _acallz!EmbeddingDistanceEvalChain._acall)  s~       99L!6+#67
 
 
 
 
 
 
 
 (8$$##G,,r/   F)r   	callbackstagsmetadatainclude_run_infor   r   r   r   r   r   kwargsc                R     | ||d||||          }|                      |          S )a  Evaluate the embedding distance between a prediction and
        reference.

        Args:
            prediction (str): The output string from the first model.
            reference (str): The reference string (required)
            callbacks (Callbacks, optional): The callbacks to use.
            **kwargs (Any): Additional keyword arguments.

        Returns:
            dict: A dictionary containing:
                - score: The embedding distance between the two
                    predictions.
        r   r   r   r   r   r   r   rI   	rD   r   r   r   r   r   r   r   rF   s	            r   _evaluate_stringsz,EmbeddingDistanceEvalChain._evaluate_strings?  sG    2 ",9EE-
 
 
 ##F+++r/   c                v   K   |                      ||d||||           d{V }|                     |          S )a  Asynchronously evaluate the embedding distance between
        a prediction and reference.

        Args:
            prediction (str): The output string from the first model.
            reference (str): The output string from the second model.
            callbacks (Callbacks, optional): The callbacks to use.
            **kwargs (Any): Additional keyword arguments.

        Returns:
            dict: A dictionary containing:
                - score: The embedding distance between the two
                    predictions.
        r   r   NacallrI   r   s	            r   _aevaluate_stringsz-EmbeddingDistanceEvalChain._aevaluate_stringsa  sk      2 zz",9EE- " 
 
 
 
 
 
 
 
 ##F+++r/   N)r%   r&   r'   r(   rp   boolry   rn   r   r   r   r   r   r   r	   r   r   r   r
   rq   r   r   r.   r/   r   rw   rw      sr         D    X B B B B XB +DI + + + X+ =A   S#X  89  
c3h	       0 BF   S#X  =>  
c3h	       4 $(#$(-1!& ,  ,  ,  , C=	 ,
  , tCy! , 4S>* ,  ,  , 
 ,  ,  ,  ,L $(#$(-1!& ,  ,  ,  , C=	 ,
  , tCy! , 4S>* ,  ,  , 
 ,  ,  ,  ,  ,  ,r/   rw   c                      e Zd ZdZedee         fd            Zedefd            Z	 dde	ee
f         dee         de	ee
f         fdZ	 dde	ee
f         dee         de	ee
f         fd	Zdddd
ddedededeee                  dee	ee
f                  dede
defdZdddd
ddedededeee                  dee	ee
f                  dede
defdZdS )"PairwiseEmbeddingDistanceEvalChaina  Use embedding distances to score semantic difference between two predictions.

    Examples:
    >>> chain = PairwiseEmbeddingDistanceEvalChain()
    >>> result = chain.evaluate_string_pairs(prediction="Hello", prediction_b="Hi")
    >>> print(result)
    {'score': 0.5}
    r   c                 
    ddgS )r   r   prediction_br.   rC   s    r   r   z-PairwiseEmbeddingDistanceEvalChain.input_keys  s     n--r/   c                 "    d| j         j         dS )Npairwise_embedding_r|   r}   rC   s    r   r   z2PairwiseEmbeddingDistanceEvalChain.evaluation_name  s    JT%9%?JJJJr/   Nr   r   c                     t          j        | j                            |d         |d         g                    }|                     |          }d|iS )a  Compute the score for two predictions.

        Args:
            inputs (Dict[str, Any]): The input data.
            run_manager (CallbackManagerForChainRun, optional):
                The callback manager.

        Returns:
            Dict[str, Any]: The computed score.
        r   r   rB   r   r   s        r   r   z(PairwiseEmbeddingDistanceEvalChain._call  s\     (O++%vn'=> 
 

 ##G,,r/   c                    K   | j                             |d         |d         g           d{V }t          j        |          }|                     |          }d|iS )a/  Asynchronously compute the score for two predictions.

        Args:
            inputs (Dict[str, Any]): The input data.
            run_manager (AsyncCallbackManagerForChainRun, optional):
                The callback manager.

        Returns:
            Dict[str, Any]: The computed score.
        r   r   NrB   r   r   s         r   r   z)PairwiseEmbeddingDistanceEvalChain._acall  s~       99L!6.#9:
 
 
 
 
 
 
 
 (8$$##G,,r/   F)r   r   r   r   r   r   r   r   r   r   r   c                R     | ||d||||          }|                      |          S )a  Evaluate the embedding distance between two predictions.

        Args:
            prediction (str): The output string from the first model.
            prediction_b (str): The output string from the second model.
            callbacks (Callbacks, optional): The callbacks to use.
            tags (List[str], optional): Tags to apply to traces
            metadata (Dict[str, Any], optional): metadata to apply to
            **kwargs (Any): Additional keyword arguments.

        Returns:
            dict: A dictionary containing:
                - score: The embedding distance between the two
                    predictions.
        r   r   r   r   	rD   r   r   r   r   r   r   r   rF   s	            r   _evaluate_string_pairsz9PairwiseEmbeddingDistanceEvalChain._evaluate_string_pairs  sG    4 ",lKK-
 
 
 ##F+++r/   c                v   K   |                      ||d||||           d{V }|                     |          S )a  Asynchronously evaluate the embedding distance

        between two predictions.

        Args:
            prediction (str): The output string from the first model.
            prediction_b (str): The output string from the second model.
            callbacks (Callbacks, optional): The callbacks to use.
            tags (List[str], optional): Tags to apply to traces
            metadata (Dict[str, Any], optional): metadata to apply to traces
            **kwargs (Any): Additional keyword arguments.

        Returns:
            dict: A dictionary containing:
                - score: The embedding distance between the two
                    predictions.
        r   r   Nr   r   s	            r   _aevaluate_string_pairsz:PairwiseEmbeddingDistanceEvalChain._aevaluate_string_pairs  sk      8 zz",lKK- " 
 
 
 
 
 
 
 
 ##F+++r/   r   )r%   r&   r'   r(   rp   r   rn   r   r   r   r   r   r	   r   r   r   r
   r   rq   r   r   r.   r/   r   r   r     s=         .DI . . . X. K K K K XK =A   S#X  89  
c3h	       4 BF   S#X  =>  
c3h	       6  $$(-1!&!, !, !, !, 	!,
 !, tCy!!, 4S>*!, !, !, 
!, !, !, !,P  $$(-1!&#, #, #, #, 	#,
 #, tCy!#, 4S>*#, #, #, 
#, #, #, #, #, #,r/   r   )"r(   enumr   typingr   r   r   r   numpyrZ    langchain_core.callbacks.managerr   r	   r
   langchain_core.embeddingsr   langchain_core.utilsr   pydanticr   r   langchain.chains.baser   langchain.evaluation.schemar   r   langchain.schemar   r   rn   r   r1   rw   r   r.   r/   r   <module>r      s   F F       , , , , , , , , , , , ,             
 1 0 0 0 0 0 ) ) ) ) ) ) & & & & & & & & ' ' ' ' ' ' P P P P P P P P $ $ $ $ $ $J    *    T   $t t t t t5 t t tnN, N, N, N, N,!= N, N, N,bL, L, L, L, L, "9L, L, L, L, L,r/   