Ë
    ³Œj,;  ã                  óò   — 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y)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y)Ú_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).
    c                 ó   — y)NF© ©Úselfs    ú[/var/www/html/Fitness-lenito-AI-main/venv/lib/python3.12/site-packages/langsmith/_expect.pyÚ__bool__z_NULL_SENTRY.__bool__Q   s   € Øó    c                 ó   — y)NÚ	NOT_GIVENr   r   s    r   Ú__repr__z_NULL_SENTRY.__repr__T   s   € Ør   N)ÚreturnzLiteral[False])r   Ústr)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r   L   s   „ ñóôr   r   c                  ó„   — 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dd„Zdd„Zdd„Zy)Ú_Matcherz4A class for making assertions on expectation values.Nc                óü   — || _         || _        || _        |xs t        j                  d¬«      | _        t        j                  «       | _        | j                  r| j                  j                  | _
        y || _
        y )Né   ©Úmax_workers)Ú_clientÚkeyÚvalueÚls_utilsÚContextThreadPoolExecutorÚ	_executorÚrhÚget_current_run_treeÚ_rtÚtrace_idÚ_run_id)r   r   r+   r,   r/   Úrun_ids         r   Ú__init__z_Matcher.__init__^   s^   € ð ˆŒØˆŒØˆŒ
Ø"ÒW¤h×&HÑ&HÐUVÔ&WˆŒÜ×*Ñ*Ó,ˆŒØ,0¯HªH�t—x‘x×(Ñ(ˆ�¸&ˆ�r   c           	     ó€  — t        j                  «       sª| j                  st        j                  «       | _        | j
                  j                  | j                  j                  | j                  d||| j                  r| j                  j                  nd | j                  r| j                  j                  nd ¬«       y y )NÚexpectation)r5   r+   ÚscoreÚcommentÚ
session_idÚ
start_time)r-   Útest_tracking_is_disabledr*   ÚrtÚget_cached_clientr/   ÚsubmitÚcreate_feedbackr4   r2   r;   r<   )r   r9   Úmessages      r   Ú_submit_feedbackz_Matcher._submit_feedbackm   sˆ   € Ü×1Ñ1Ô3Ø—<’<Ü!×3Ñ3Ó5�”Ø�N‰N×!Ñ!Ø—‘×,Ñ,Ø—|‘|Ø!ØØØ26·(²(˜4Ÿ8™8×.Ò.ÀØ26·(²(˜4Ÿ8™8×.Ò.Àð "õ ð 4r   c                ó¼   — 	 |sJ |«       ‚| j                  dd| j                  › d|› �¬«       y # t        $ r#}| j                  dt        |«      «       |d ‚d }~ww xY w)Né   z	Success: Ú.)rB   r   )rC   r+   ÚAssertionErrorÚrepr)r   Ú	conditionrB   Úmethod_nameÚes        r   Ú_assertz_Matcher._assert{   sd   € ð	ÙÐ%˜gÓ%�9Ø×!Ñ! !¨y¸¿¹¸
À!ÀKÀ=Ð-QÐ!ÕRøÜò 	Ø×!Ñ! !¤T¨!£WÔ-Ø˜Ðûð	ús   ‚,/ ¯	A¸AÁAc           	     ó~   — | j                  | j                  |k  d| j                  › d|› d| j                  › �d«       y)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©rL   r,   r+   ©r   r,   s     r   rP   z_Matcher.to_be_less_thanƒ   s>   € ð 	�‰Ø�J‰J˜ÑØ˜Ÿ™�zÐ!2°5°'¸ÀDÇJÁJÀ<ÐPØõ	
r   c           	     ó~   — | j                  | j                  |kD  d| j                  › d|› d| j                  › �d«       y)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.
        rN   z to be greater than rO   Úto_be_greater_thanNrQ   rR   s     r   rT   z_Matcher.to_be_greater_than’   s>   € ð 	�‰Ø�J‰J˜ÑØ˜Ÿ™�zÐ!5°e°W¸JÀtÇzÁzÀlÐSØ õ	
r   c                óš   — | j                  || j                  cxk  xr |k  nc d| j                  › d|› d|› d| j                  › �d«       y)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.
        rN   z to be between z and rO   Úto_be_betweenNrQ   )r   Ú	min_valueÚ	max_values      r   rV   z_Matcher.to_be_between¢   sO   € ð 	�‰Ø˜Ÿ
™
Ö. YÔ.Ø˜Ÿ™�z °°¸5ÀÀð LØŸ
™
�|ð%àõ		
r   c           	     ó¦   — | j                  t        | j                  |«      t        ||«      k(  d| j                  › d|› d| j                  › �d«       y)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.
        rN   z to be approximately rO   Úto_be_approximatelyN)rL   Úroundr,   r+   )r   r,   Ú	precisions      r   rZ   z_Matcher.to_be_approximately³   sL   € ð 	�‰Ü�$—*‘*˜iÓ(¬E°%¸Ó,CÑCØ˜Ÿ™�zÐ!6°u°g¸ZÈÏ
É
À|ÐTØ!õ	
r   c           	     ó~   — | j                  | j                  |k(  d| j                  › d|› d| j                  › �d«       y)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.
        rN   z to be equal to rO   Úto_equalNrQ   rR   s     r   r^   z_Matcher.to_equalÄ   s>   € ð 	�‰Ø�J‰J˜%ÑØ˜Ÿ™�zÐ!1°%°¸
À4Ç:Á:À,ÐOØõ	
r   c                óv   — | j                  | j                  du d| j                  › d| j                  › �d«       y)zŠAssert that the expectation value is `None`.

        Raises:
            AssertionError: If the expectation value is not `None`.
        NrN   z to be None, but got Ú
to_be_nonerQ   r   s    r   r`   z_Matcher.to_be_noneÔ   s8   € ð 	�‰Ø�J‰J˜$ÐØ˜Ÿ™�zÐ!6°t·z±z°lÐCØõ	
r   c                ód   — | j                  || j                  v d| j                  › d|› d�d«       y)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.
        rN   z to contain z, but it does notÚ
to_containNrQ   rR   s     r   rb   z_Matcher.to_containà   s6   € ð 	�‰Ø�T—Z‘ZÐØ˜Ÿ™�z ¨e¨WÐ4EÐFØõ	
r   c               ó”   — t        j                  |«      }| j                   || j                  «      d|› d| j                  › �d«       y)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Ú	signaturerL   r,   r+   )r   ÚfuncÚfunc_signatures      r   rd   z_Matcher.againstð   sD   € ô !×*Ñ*¨4Ó0ˆØ�‰Ù�—‘ÓØ˜Ð(¨°T·X±X°JÐ?Øõ	
r   )NN)
r   úOptional[ls_client.Client]r+   r   r,   r   r/   z,Optional[ls_utils.ContextThreadPoolExecutor]r5   úOptional[str]©N)r9   ÚintrB   rj   r   ÚNone)rI   ÚboolrB   r   rJ   r   r   rm   )r,   Úfloatr   rm   )rW   ro   rX   ro   r   rm   )é   )r,   ro   r\   rl   r   rm   )r   rm   )r,   r   r   rm   )rg   r   r   rm   )r    r!   r"   r#   r6   rC   rL   rP   rT   rV   rZ   r^   r`   rb   rd   r   r   r   r%   r%   [   s}   „ Ù>ð CGØ $ðAà*ð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y)Ú_Expectz1A class for setting expectations on test results.Nr   c               óž   — || _         t        j                  d¬«      | _        t	        j
                  | j                  j                  d¬«       y )Nr'   r(   T)Úwait)r*   r-   r.   ÚexecutorÚatexitÚregisterÚshutdown©r   r   s     r   r6   z_Expect.__init__  s3   € ØˆŒÜ ×:Ñ:ÀqÔIˆŒÜ�‰˜Ÿ™×.Ñ.°TÖ:r   ©Úconfigc          	     ó,  — ddl m} |xs i }|j                  d«      rdnd} ||¬«      }|j                  ||¬«      }||j                  dœ}| j                  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Úopenairz   ©Ú
predictionÚ	reference)r~   ÚmetricÚembedding_distanceúUsing z
, Metric: ©r9   Úsource_infor:   ©r/   )	Ú'langsmith._internal._embedding_distancer}   ÚgetÚevaluateÚdistancerC   r%   r*   ru   )	r   r‚   rƒ   r{   r}   Úencoder_funcÚ	evaluatorr9   Úsrc_infos	            r   r…   z_Expect.embedding_distance	  s§   € õT 	Nà’˜2ˆØ#)§:¡:¨iÔ#8‘x¸hˆÙ%¨VÔ4ˆ	Ø×"Ñ"¨jÀIÐ"ÓNˆØ+°y×7IÑ7IÑJˆØ×ÑØ àØ'Ø# L >°¸I×<NÑ<NÐ;OÐPñô	
ô Ø�L‰LÐ.°ÀÇÁô
ð 	
r   c          	     ó(  — ddl m} |xs i }|j                  d«      xs d}|j                  dd«      } ||¬«      }|j                  ||¬«      }||d	œ}	| j	                  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_scoreTrz   r�   )r„   Ú	normalizeÚedit_distancer†   z, Normalize: r‡   r‰   )Ú"langsmith._internal._edit_distancer’   r‹   rŒ   rC   r%   r*   ru   )
r   r‚   rƒ   r{   r’   r„   r•   r�   r9   r�   s
             r   r–   z_Expect.edit_distanceF  s¯   € õF 	Dà’˜2ˆØ—‘˜HÓ%Ò>Ð)>ˆØ—J‘JÐ0°$Ó7ˆ	Ù ¨Ô/ˆ	Ø×"Ñ"¨jÀIÐ"ÓNˆØ$°9Ñ=ˆØ×ÑØàØ'Ø# F 8¨=¸¸ÐDñô	
ô Ø�L‰LØØØ—m‘mô	
ð 	
r   c                óH   — 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%   r*   ru   rR   s     r   r,   z_Expect.value€  s   € ô ˜Ÿ™ g¨uÀÇÁÔNÐNr   r9   )r+   Úsource_run_idr:   c               óz   — | j                  ||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)r9   rˆ   r™   r:   r‰   )rC   r%   r*   ru   )r   r9   r+   r™   r:   s        r   r9   z_Expect.score�  sF   € ð, 	×ÑØàØ (¨.Ð9Ø!.Ø"ñ	ô	
ô ˜Ÿ™ c¨5¸D¿M¹MÔJÐJr   c                ó   — y rk   r   rR   s     r   Ú__call__z_Expect.__call__³  s   € Ø36r   c               ó   — y rk   r   ry   s     r   r�   z_Expect.__call__¶  s   € ØCFr   c               óP   — t        |¬«      }|t        ur|j                  |«      S |S )Nr   )rr   r   r,   )r   r,   r   Úexpecteds       r   r�   z_Expect.__call__¹  s*   € ô  &Ô)ˆØœ	Ñ!Ø—>‘> %Ó(Ð(Øˆr   c                ó(  — t        j                  «       }|r|j                  nd }t        j                  «       sZ| j
                  st        j                  «       | _         | j                  j                  | j
                  j                  f||dœ|¤Ž y y )N)r5   r+   )r0   r1   r3   r-   r=   r*   r>   r?   ru   r@   rA   )r   r+   ÚresultsÚcurrent_runr5   s        r   rC   z_Expect._submit_feedbackÄ  sz   € Ü×-Ñ-Ó/ˆÙ)4�×%Ò%¸$ˆÜ×1Ñ1Ô3Ø—<’<Ü!×3Ñ3Ó5�”Ø ˆD�M‰M× Ñ Ø—‘×,Ñ,ðØ5;ÀñØHOóð 4r   )r   ri   )r‚   r   rƒ   r   r{   zOptional[EmbeddingConfig]r   r%   )r‚   r   rƒ   r   r{   zOptional[EditDistanceConfig]r   r%   )r,   r   r   r%   )
r9   zUnion[float, int, bool]r+   r   r™   zOptional[ls_client.ID_TYPE]r:   rj   r   r%   )r   zls_client.Clientr   rr   )r   ri   r,   zOptional[Any]r   zUnion[_Expect, _Matcher])r+   r   r¢   Údict)r    r!   r"   r#   r6   r…   r–   r,   r9   r
   r�   r   rC   r   r   r   rr   rr     s  „ Ù;à?Cõ ;ð -1ñ;
àð;
ð ð;
ð
 *ð;
ð 
ó;
ðD 04ñ8
àð8
ð ð8
ð
 -ð8
ð 
ó8
ótOð( Ø59Ø!%ñKà&ðKð ð	Kð
 3ðKð ðKð 
óKðF Ú6ó Ø6àÚFó ØFð  )à-1ð		ð +ð		àð	ð
 
"ó	ôr   rr   Úexpect) r#   Ú
__future__r   rv   re   Útypingr   r   r   r   r   r	   r
   Ú	langsmithr   Ú	ls_clientr   r0   r   r>   r   r-   r—   r   rŠ   r   r   r   r%   rr   r¥   Ú__all__r   r   r   Ú<module>r«      sy   ðñ0õd #ã Û ÷÷ ñ õ *Ý 'Ý %Ý 'áÝEÝG÷	ñ 	ñ ‹N€	÷c
ñ c
÷LKñ Kñ\ 
‹€àˆ*�r   