§
    ~Štj,;  ã                  ó  — d Z 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 ddlmZ ddlmZ ddlmZ ddlmZ erdd	lmZ dd
lmZ  G d„ d¦  «        Z e¦   «         Z G d„ d¦  «        Z G d„ d¦  «        Z e¦   «         ZdgZdS )a<  Make approximate assertions as "expectations" on test results.

This module is designed to be used within test cases decorated with the
`@pytest.mark.decorator` decorator

It allows you to log scores about a test case and optionally make assertions that log as
"expectation" feedback to LangSmith.

Example:
    ```python
    import pytest
    from langsmith import expect


    @pytest.mark.langsmith
    def test_output_semantically_close():
        response = oai_client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": "Say hello!"},
            ],
        )
        response_txt = response.choices[0].message.content
        # Intended usage
        expect.embedding_distance(
            prediction=response_txt,
            reference="Hello!",
        ).to_be_less_than(0.9)

        # Score the test case
        matcher = expect.edit_distance(
            prediction=response_txt,
            reference="Hello!",
        )
        # Apply an assertion and log 'expectation' feedback to LangSmith
        matcher.to_be_less_than(1)

        # You can also directly make assertions on values directly
        expect.value(response_txt).to_contain("Hello!")
        # Or using a custom check
        expect.value(response_txt).against(lambda x: "Hello" in x)

        # You can even use this for basic metric logging within tests

        expect.score(0.8)
        expect.score(0.7, key="similarity").to_be_greater_than(0.7)
    ```
é    )ÚannotationsN)ÚTYPE_CHECKINGÚAnyÚCallableÚLiteralÚOptionalÚUnionÚoverload©Úclient)Úrun_helpers)Ú	run_trees)Úutils)ÚEditDistanceConfig)ÚEmbeddingConfigc                  ó"   — e Zd ZdZdd„Zd	d„ZdS )
Ú_NULL_SENTRYzŸA sentinel singleton class used to distinguish omitted keyword arguments
    from those passed in with the value None (which may have different behavior).
    ÚreturnúLiteral[False]c                ó   — dS )NF© ©Úselfs    úO/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/langsmith/_expect.pyÚ__bool__z_NULL_SENTRY.__bool__Q   s   € Øˆuó    Ústrc                ó   — dS )NÚ	NOT_GIVENr   r   s    r   Ú__repr__z_NULL_SENTRY.__repr__T   s   € Øˆ{r   N)r   r   )r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r    r   r   r   r   r   L   sF   € € € € € ðð ðð ð ð ðð ð ð ð ð r   r   c                  ót   — e Zd ZdZ	 	 d'd(d„Zd)d*d„Zd+d„Zd,d„Zd,d„Zd-d„Z	d.d/d „Z
d,d!„Zd0d"„Zd1d#„Zd2d&„ZdS )3Ú_Matcherz4A class for making assertions on expectation values.Nr   úOptional[ls_client.Client]Úkeyr   Úvaluer   Ú	_executorú,Optional[ls_utils.ContextThreadPoolExecutor]Úrun_idúOptional[str]c                óÌ   — || _         || _        || _        |pt          j        d¬¦  «        | _        t          j        ¦   «         | _        | j        r| j        j	        n|| _
        d S )Né   ©Úmax_workers)Ú_clientr(   r)   Úls_utilsÚContextThreadPoolExecutorr*   ÚrhÚget_current_run_treeÚ_rtÚtrace_idÚ_run_id)r   r   r(   r)   r*   r,   s         r   Ú__init__z_Matcher.__init__^   s`   € ð ˆŒØˆŒØˆŒ
Ø"ÐW¥hÔ&HÐUVÐ&WÑ&WÔ&WˆŒÝÔ*Ñ,Ô,ˆŒØ,0¬HÐ@�t”xÔ(Ð(¸&ˆŒˆˆr   ÚscoreÚintÚmessager   ÚNonec           	     ó  — t          j        ¦   «         sw| j        st          j        ¦   «         | _        | j                             | j        j        | j        d||| j	        r| j	        j
        nd | j	        r| j	        j        nd ¬¦  «         d S d S )NÚexpectation)r,   r(   r;   ÚcommentÚ
session_idÚ
start_time)r3   Útest_tracking_is_disabledr2   ÚrtÚget_cached_clientr*   ÚsubmitÚcreate_feedbackr9   r7   rB   rC   )r   r;   r=   s      r   Ú_submit_feedbackz_Matcher._submit_feedbackm   sž   € ÝÔ1Ñ3Ô3ð 	Ø”<ð 6Ý!Ô3Ñ5Ô5�”ØŒN×!Ò!Ø”Ô,Ø”|Ø!ØØØ26´(ÐD˜4œ8Ô.Ð.ÀØ26´(ÐD˜4œ8Ô.Ð.Àð "ñ ô ð ð ð ð	ð 	r   Ú	conditionÚboolÚmethod_namec                óÔ   — 	 |s
J |¦   «         ‚|                       dd| j        › d|› �¬¦  «         d S # t          $ r+}|                       dt          |¦  «        ¦  «         |d ‚d }~ww xY w)Né   z	Success: ú.)r=   r   )rI   r(   ÚAssertionErrorÚrepr)r   rJ   r=   rL   Úes        r   Ú_assertz_Matcher._assert{   s�   € ð	ØÐ%Ð%˜gÑ%Ô%�9Ø×!Ò! !Ð-Q¸¼Ð-QÐ-QÀKÐ-QÐ-QÐ!ÑRÔRÐRÐRÐRøÝð 	ð 	ð 	Ø×!Ò! !¥T¨!¡W¤WÑ-Ô-Ð-Ø˜Ðøøøøð	øøøs   ‚.2 ²
A'¼&A"Á"A'Úfloatc           	     ól   — |                       | j        |k     d| j        › d|› d| j        › �d¦  «         dS )zðAssert that the expectation value is less than the given value.

        Args:
            value: The value to compare against.

        Raises:
            AssertionError: If the expectation value is not less than the given value.
        ú	Expected z to be less than ú
, but got Úto_be_less_thanN©rS   r)   r(   ©r   r)   s     r   rX   z_Matcher.to_be_less_thanƒ   sP   € ð 	�ŠØŒJ˜ÒØP˜œÐPÐP°5ÐPÐPÀDÄJÐPÐPØñ	
ô 	
ð 	
ð 	
ð 	
r   c           	     ól   — |                       | j        |k    d| j        › d|› d| j        › �d¦  «         dS )a  Assert that the expectation value is greater than the given value.

        Args:
            value: The value to compare against.

        Raises:
            AssertionError: If the expectation value is not
            greater than the given value.
        rV   z to be greater than rW   Úto_be_greater_thanNrY   rZ   s     r   r\   z_Matcher.to_be_greater_than’   sP   € ð 	�ŠØŒJ˜ÒØS˜œÐSÐS°eÐSÐSÀtÄzÐSÐSØ ñ	
ô 	
ð 	
ð 	
ð 	
r   Ú	min_valueÚ	max_valuec                ó†   — |                       || j        cxk     o|k     nc d| j        › d|› d|› d| j        › �d¦  «         dS )a4  Assert that the expectation value is between the given min and max values.

        Args:
            min_value: The minimum value (exclusive).
            max_value: The maximum value (exclusive).

        Raises:
            AssertionError: If the expectation value is not between the min and max.
        rV   z to be between z and rW   Úto_be_betweenNrY   )r   r]   r^   s      r   r`   z_Matcher.to_be_between¢   s‚   € ð 	�ŠØ˜œ
Ð.Ð.Ò.Ð. YÒ.Ð.Ð.Ð.ð%˜œð %ð %°ð %ð %Àð %ð %Øœ
ð%ð %àñ		
ô 	
ð 	
ð 	
ð 	
r   é   Ú	precisionc           	     ó¤   — |                       t          | j        |¦  «        t          ||¦  «        k    d| j        › d|› d| j        › �d¦  «         dS )ak  Assert that the expectation value is approximately equal to the given value.

        Args:
            value: The value to compare against.
            precision: The number of decimal places to round to for comparison.

        Raises:
            AssertionError: If the rounded expectation value
                does not equal the rounded given value.
        rV   z to be approximately rW   Úto_be_approximatelyN)rS   Úroundr)   r(   )r   r)   rb   s      r   rd   z_Matcher.to_be_approximately³   sd   € ð 	�ŠÝ�$”*˜iÑ(Ô(­E°%¸Ñ,CÔ,CÒCØT˜œÐTÐT°uÐTÐTÈÌ
ÐTÐTØ!ñ	
ô 	
ð 	
ð 	
ð 	
r   c           	     ól   — |                       | j        |k    d| j        › d|› d| j        › �d¦  «         dS )a   Assert that the expectation value equals the given value.

        Args:
            value: The value to compare against.

        Raises:
            AssertionError: If the expectation value does
                not exactly equal the given value.
        rV   z to be equal to rW   Úto_equalNrY   rZ   s     r   rg   z_Matcher.to_equalÄ   sP   € ð 	�ŠØŒJ˜%ÒØO˜œÐOÐO°%ÐOÐOÀ4Ä:ÐOÐOØñ	
ô 	
ð 	
ð 	
ð 	
r   c                ób   — |                       | j        du d| j        › d| j        › �d¦  «         dS )zŠAssert that the expectation value is `None`.

        Raises:
            AssertionError: If the expectation value is not `None`.
        NrV   z to be None, but got Ú
to_be_nonerY   r   s    r   ri   z_Matcher.to_be_noneÔ   sH   € ð 	�ŠØŒJ˜$ÐØC˜œÐCÐC°t´zÐCÐCØñ	
ô 	
ð 	
ð 	
ð 	
r   c                óZ   — |                       || j        v d| j        › d|› d�d¦  «         dS )zòAssert that the expectation value contains the given value.

        Args:
            value: The value to check for containment.

        Raises:
            AssertionError: If the expectation value does not contain the given value.
        rV   z to contain z, but it does notÚ
to_containNrY   rZ   s     r   rk   z_Matcher.to_containà   sI   € ð 	�ŠØ�T”ZÐØF˜œÐFÐF¨eÐFÐFÐFØñ	
ô 	
ð 	
ð 	
ð 	
r   Úfuncr   c               óŽ   — t          j        |¦  «        }|                       || j        ¦  «        d|› d| j        › �d¦  «         dS )zñAssert the expectation value against a custom function.

        Args:
            func: A custom function that takes the expectation value as input.

        Raises:
            AssertionError: If the custom function returns False.
        z
Assertion z failed for ÚagainstN)ÚinspectÚ	signaturerS   r)   r(   )r   rl   Úfunc_signatures      r   rn   z_Matcher.againstð   s[   € õ !Ô*¨4Ñ0Ô0ˆØ�ŠØˆD�”ÑÔØ?˜Ð?Ð?°T´XÐ?Ð?Øñ	
ô 	
ð 	
ð 	
ð 	
r   )NN)
r   r'   r(   r   r)   r   r*   r+   r,   r-   ©N)r;   r<   r=   r-   r   r>   )rJ   rK   r=   r   rL   r   r   r>   )r)   rT   r   r>   )r]   rT   r^   rT   r   r>   )ra   )r)   rT   rb   r<   r   r>   )r   r>   )r)   r   r   r>   )rl   r   r   r>   )r!   r"   r#   r$   r:   rI   rS   rX   r\   r`   rd   rg   ri   rk   rn   r   r   r   r&   r&   [   s  € € € € € Ø>Ð>ð CGØ $ðAð Að Að Að Aðð ð ð ð ðð ð ð ð
ð 
ð 
ð 
ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð"
ð 
ð 
ð 
ð 
ð"
ð 
ð 
ð 
ð 

ð 

ð 

ð 

ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
r   r&   c                  óœ   — e Zd ZdZddœd'd„Zddœd(d„Zddœd)d„Zd*d„Zddddœd+d„Ze	d*d„¦   «         Z
e	d,d „¦   «         Z
edfd-d#„Z
d.d&„ZdS )/Ú_Expectz1A class for setting expectations on test results.Nr   r   r'   c               óˆ   — || _         t          j        d¬¦  «        | _        t	          j        | j        j        d¬¦  «         d S )Nr/   r0   T)Úwait)r2   r3   r4   ÚexecutorÚatexitÚregisterÚshutdown©r   r   s     r   r:   z_Expect.__init__  s>   € ØˆŒÝ Ô:ÀqÐIÑIÔIˆŒÝŒ˜œÔ.°TÐ:Ñ:Ô:Ð:Ð:Ð:r   ©ÚconfigÚ
predictionr   Ú	referencer}   úOptional[EmbeddingConfig]r   r&   c          	     ó&  — ddl m} |pi }|                     d¦  «        rdnd} ||¬¦  «        }|                     ||¬¦  «        }||j        dœ}|                      d	||d
|› d|j        › �dœ¦  «         t          | j        d	|| j        ¬¦  «        S )aµ  Compute the embedding distance between the prediction and reference.

        This logs the embedding distance to LangSmith and returns a `_Matcher` instance
        for making assertions on the distance value.

        By default, this uses the OpenAI API for computing embeddings.

        Args:
            prediction: The predicted string to compare.
            reference: The reference string to compare against.
            config: Optional configuration for the embedding distance evaluator.

                Supported options:

                - `encoder`: A custom encoder function to encode the list of input
                    strings to embeddings.

                    Defaults to the OpenAI API.
                - `metric`: The distance metric to use for comparison.

                    Supported values: `'cosine'`, `'euclidean'`, `'manhattan'`,
                    `'chebyshev'`, `'hamming'`.

        Returns:
            A `_Matcher` instance for the embedding distance value.


        Example:
            ```python
            expect.embedding_distance(
                prediction="hello",
                reference="hi",
            ).to_be_less_than(1.0)
            ```
        r   )ÚEmbeddingDistanceÚencoderÚcustomÚopenair|   ©r~   r   )rƒ   ÚmetricÚembedding_distanceúUsing z
, Metric: ©r;   Úsource_inforA   ©r*   )	Ú'langsmith._internal._embedding_distancer‚   ÚgetÚevaluateÚdistancerI   r&   r2   rw   )	r   r~   r   r}   r‚   Úencoder_funcÚ	evaluatorr;   Úsrc_infos	            r   rˆ   z_Expect.embedding_distance	  sÞ   € ðT 	NÐMÐMÐMÐMÐMà�˜2ˆØ#)§:¢:¨iÑ#8Ô#8ÐF�x�x¸hˆØ%Ð%¨VÐ4Ñ4Ô4ˆ	Ø×"Ò"¨jÀIÐ"ÑNÔNˆØ+°yÔ7IÐJÐJˆØ×ÒØ àØ'ØP LÐPÐP¸IÔ<NÐPÐPðð ñ	
ô 	
ð 	
õ ØŒLÐ.°ÀÄð
ñ 
ô 
ð 	
r   úOptional[EditDistanceConfig]c          	     ó:  — ddl m} |pi }|                     d¦  «        pd}|                     dd¦  «        } ||¬¦  «        }|                     ||¬¦  «        }||d	œ}	|                      d
||	d|› d|› �dœ¦  «         t          | j        d
|| j        ¬¦  «        S )aB  Compute the string distance between the prediction and reference.

        This logs the string distance (Damerau-Levenshtein) to LangSmith and returns
        a `_Matcher` instance for making assertions on the distance value.

        This depends on the `rapidfuzz` package for string distance computation.

        Args:
            prediction: The predicted string to compare.
            reference: The reference string to compare against.
            config: Optional configuration for the string distance evaluator.

                Supported options:

                - `metric`: The distance metric to use for comparison.

                    Supported values: `'damerau_levenshtein'`, `'levenshtein'`,
                    `'jaro'`, `'jaro_winkler'`, `'hamming'`, `'indel'`.
                - `normalize_score`: Whether to normalize the score between `0` and `1`.

        Returns:
            A `_Matcher` instance for the string distance value.

        Examples:
            ```python
            expect.edit_distance("hello", "helo").to_be_less_than(1)
            ```
        r   )ÚEditDistancer‡   Údamerau_levenshteinÚnormalize_scoreTr|   r†   )r‡   Ú	normalizeÚedit_distancer‰   z, Normalize: rŠ   rŒ   )Ú"langsmith._internal._edit_distancer–   rŽ   r�   rI   r&   r2   rw   )
r   r~   r   r}   r–   r‡   r™   r’   r;   r“   s
             r   rš   z_Expect.edit_distanceF  sê   € ðF 	DÐCÐCÐCÐCÐCà�˜2ˆØ—’˜HÑ%Ô%Ð>Ð)>ˆØ—J’JÐ0°$Ñ7Ô7ˆ	Ø �L¨Ð/Ñ/Ô/ˆ	Ø×"Ò"¨jÀIÐ"ÑNÔNˆØ$°9Ð=Ð=ˆØ×ÒØàØ'ØD FÐDÐD¸ÐDÐDðð ñ	
ô 	
ð 	
õ ØŒLØØØ”mð	
ñ 
ô 
ð 	
r   r)   r   c                ó<   — t          | j        d|| j        ¬¦  «        S )aD  Create a `_Matcher` instance for making assertions on the given value.

        Args:
            value: The value to make assertions on.

        Returns:
            A `_Matcher` instance for the given value.

        Example:
            ```python
            expect.value(10).to_be_less_than(20)
            ```
        r)   rŒ   )r&   r2   rw   rZ   s     r   r)   z_Expect.value€  s   € õ ˜œ g¨uÀÄÐNÑNÔNÐNr   r;   )r(   Úsource_run_idrA   úUnion[float, int, bool]r(   r�   úOptional[ls_client.ID_TYPE]rA   r-   c               óv   — |                       ||ddi||dœ¦  «         t          | j        ||| j        ¬¦  «        S )až  Log a numeric score to LangSmith.

        Args:
            score: The score value to log.
            key: The key to use for logging the score. Defaults to `'score'`.

        Example:
            ```python
            expect.score(0.8)  # doctest: +ELLIPSIS
            <langsmith._expect._Matcher object at ...>

            expect.score(0.8, key="similarity").to_be_greater_than(0.7)
            ```
        Úmethodzexpect.score)r;   r‹   r�   rA   rŒ   )rI   r&   r2   rw   )r   r;   r(   r�   rA   s        r   r;   z_Expect.score�  sW   € ð, 	×ÒØàØ (¨.Ð9Ø!.Ø"ð	ð ñ	
ô 	
ð 	
õ ˜œ c¨5¸D¼MÐJÑJÔJÐJr   c               ó   — d S rr   r   rZ   s     r   Ú__call__z_Expect.__call__³  s   € Ø36°3r   úls_client.Clientc              ó   — d S rr   r   r{   s     r   r£   z_Expect.__call__¶  s   € ØCFÀ3r   úOptional[Any]úUnion[_Expect, _Matcher]c               ób   — t          |¬¦  «        }|t          ur|                     |¦  «        S |S )Nr   )rt   r   r)   )r   r)   r   Úexpecteds       r   r£   z_Expect.__call__¹  s6   € õ  &Ð)Ñ)Ô)ˆØ�	Ð!Ð!Ø—>’> %Ñ(Ô(Ð(Øˆr   ÚresultsÚdictc                óê   — t          j        ¦   «         }|r|j        nd }t          j        ¦   «         sA| j        st          j        ¦   «         | _         | j        j	        | j        j
        f||dœ|¤Ž d S d S )N)r,   r(   )r5   r6   r8   r3   rD   r2   rE   rF   rw   rG   rH   )r   r(   rª   Úcurrent_runr,   s        r   rI   z_Expect._submit_feedbackÄ  s™   € ÝÔ-Ñ/Ô/ˆØ)4Ð>�Ô%Ð%¸$ˆÝÔ1Ñ3Ô3ð 	Ø”<ð 6Ý!Ô3Ñ5Ô5�”Ø ˆDŒMÔ Ø”Ô,ðØ5;Àðð ØHOðð ð ð ð ð	ð 	r   )r   r'   )r~   r   r   r   r}   r€   r   r&   )r~   r   r   r   r}   r”   r   r&   )r)   r   r   r&   )
r;   rž   r(   r   r�   rŸ   rA   r-   r   r&   )r   r¤   r   rt   )r   r'   r)   r¦   r   r§   )r(   r   rª   r«   )r!   r"   r#   r$   r:   rˆ   rš   r)   r;   r
   r£   r   rI   r   r   r   rt   rt     s.  € € € € € Ø;Ð;à?Cð ;ð ;ð ;ð ;ð ;ð ;ð -1ð;
ð ;
ð ;
ð ;
ð ;
ð ;
ðD 04ð8
ð 8
ð 8
ð 8
ð 8
ð 8
ðtOð Oð Oð Oð( Ø59Ø!%ðKð Kð Kð Kð Kð KðF Ø6Ð6Ð6ñ „XØ6àØFÐFÐFñ „XØFð  )à-1ð		ð 	ð 	ð 	ð 	ðð ð ð ð ð r   rt   Úexpect) r$   Ú
__future__r   rx   ro   Útypingr   r   r   r   r   r	   r
   Ú	langsmithr   Ú	ls_clientr   r5   r   rE   r   r3   r›   r   r�   r   r   r   r&   rt   r®   Ú__all__r   r   r   ú<module>r´      s¶  ðð0ð 0ðd #Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð *Ð )Ð )Ð )Ð )Ð )Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø %Ð %Ð %Ð %Ð %Ð %Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'àð HØEÐEÐEÐEÐEÐEØGÐGÐGÐGÐGÐGð	ð 	ð 	ð 	ð 	ñ 	ô 	ð 	ð ˆL‰NŒN€	ðc
ð c
ð c
ð c
ð c
ñ c
ô c
ð c
ðLKð Kð Kð Kð Kñ Kô Kð Kð\ 
ˆ‰Œ€àˆ*€€€r   