
    IgB                        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!y)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}   |        S # t        $ r) 	 ddlm}  n# t        $ r t        d      w xY wY  |        S w xY w)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    i/var/www/html/answerous/venv/lib/python3.12/site-packages/langchain/evaluation/embedding_distance/base.py_embedding_factoryr      sa    	5   	N 	Q 	 O s!    	A A5A Ac                   $    e Zd ZdZdZdZdZdZdZy)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   *   s"     FIIIGr/   r   c                      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j6                  dej6                  dej6                  fd       Zedej6                  dej6                  dej:                  fd       Zedej6                  dej6                  dej:                  fd       Zedej6                  dej6                  dej:                  fd       Z edej6                  dej6                  dej:                  fd       Z!dej6                  de"fdZ#y)_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                 J   |j                  d      }g }	 ddlm} |j                  |       	 ddlm} |j                  |       |st	        d      t        |t        |            r	 ddl}|S |S # t        $ r Y Nw xY w# t        $ r Y Ew xY w# t        $ r t	        d      w xY w)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MM*+	NMM*+ Q 
 j%-0 v5  		  		  !I s.   A/ A> 'B /	A;:A;>	B
	B
B"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                 D    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           
      8   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   s     $$d&;&;'')A)A'')A)A'')A)A%%t'='=
 W6?"/x899r/   abc                 X    	 ddl m} d || |      z
  S # t        $ r t        d      w xY w)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   sB    	H &q!,,,  	6 	s    )c                 F    t         j                  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     yy~~a!e$$r/   c                 X    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        vvbffQUm$$r/   c                 X    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                  | |k7        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     wwqAvr/   vectorsc                     | j                  | j                        } ||d   j                  dd      |d   j                  dd            j                         }|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   sV     !!$"6"67wqz))!R0'!*2D2DQ2KLQQ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   <   s    #3EFJ
F).7H7O7O)PO&P)$sCx. )T#s(^ ) )V  $L T#Y  d t :"3 : :* -BJJ -2:: -"** - -( 
%rzz 
%bjj 
%R[[ 
% 
% 
%rzz 
%bjj 
%R[[ 
% 
% 
%rzz 
%bjj 
%R[[ 
% 
% 
RZZ 
BJJ 
2;; 
 
bjj U r/   r1   c                   l   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y)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                      y)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     r/   c                 6    d| j                   j                   dS )N
embedding_	_distancer5   valuerC   s    r   evaluation_namez*EmbeddingDistanceEvalChain.evaluation_name  s    D00667y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                  j                  |d   |d   g            }| j	                  |      }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  sP     ((OO++VL-A6+CV,WX
 ##G,r/   c                    K   | j                   j                  |d   |d   g       d{   }t        j                  |      }| j	                  |      }d|iS 7 .w)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)  sc      99L!6+#67
 
 ((8$##G,
   'AA/AF)r   	callbackstagsmetadatainclude_run_infor   r   r   r   r   r   kwargsc                D     | ||d||||      }| j                  |      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?  s5    2 ",9E-
 ##F++r/   c                r   K   | j                  ||d||||       d{   }| j                  |      S 7 w)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  sL     2 zz",9E- " 
 
 ##F++
   757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      s    D   B B B +DI + + =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                   F   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y)"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                 6    d| j                   j                   dS )Npairwise_embedding_r|   r}   rC   s    r   r   z2PairwiseEmbeddingDistanceEvalChain.evaluation_name  s    $T%9%9%?%?$@	JJr/   Nr   r   c                     t        j                  | j                  j                  |d   |d   g            }| j	                  |      }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  sS     ((OO++%vn'=>

 ##G,r/   c                    K   | j                   j                  |d   |d   g       d{   }t        j                  |      }| j	                  |      }d|iS 7 .w)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  sc      99L!6.#9:
 
 ((8$##G,
r   F)r   r   r   r   r   r   r   r   r   r   r   c                D     | ||d||||      }| j                  |      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  s5    4 ",lK-
 ##F++r/   c                r   K   | j                  ||d||||       d{   }| j                  |      S 7 w)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  sL     8 zz",l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 . . K K 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  , ,  
 1 ) & ' P $J *T $t5 tnN,!= N,bL, "9L,r/   