
    ;i{:                        S r SSKJr  SSKrSSKrSSKJrJrJrJ	r	J
r
JrJr  SSKJr  SSKJr  SSKJr  SSKJr  \(       a  SS	KJr  SS
KJr   " S S5      r\" 5       r " S S5      r " S S5      r\" 5       rS/rg)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 usage:
    .. code-block:: 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                  ,    \ rS rSrSrSS jrSS jrSrg)	_NULL_SENTRYK   zA sentinel singleton class used to distinguish omitted keyword arguments
from those passed in with the value None (which may have different behavior).
c                    g)NF selfs    a/home/dmtnaga/Documents/work/airagagent/rag_env/lib/python3.13/site-packages/langsmith/_expect.py__bool___NULL_SENTRY.__bool__P   s        c                    g)N	NOT_GIVENr   r   s    r   __repr___NULL_SENTRY.__repr__S   s    r   r   N)returnzLiteral[False])r!   str)__name__
__module____qualname____firstlineno____doc__r   r   __static_attributes__r   r   r   r   r   K   s    r   r   c                      \ rS rSrSr  S         SS jjrSSS jjrSS jrSS jrSS jr	SS	 jr
SSS
 jjrSS jrSS jrSS jrSS jrSrg)_MatcherZ   z4A class for making assertions on expectation values.Nc                    Xl         X l        X0l        U=(       d    [        R                  " SS9U l        [        R                  " 5       nU(       a  UR                  U l	        g UU l	        g )N   max_workers)
_clientkeyvaluels_utilsContextThreadPoolExecutor	_executorrhget_current_run_treetrace_id_run_id)r   r   r1   r2   r5   run_idrts          r   __init___Matcher.__init__]   sL     
"Wh&H&HUV&W$$&&(r{{fr   c                   [         R                  " 5       (       dg  U R                  (       d  [        R                  " 5       U l        U R
                  R                  U R                  R                  U R                  SUUS9  g g )Nexpectation)r:   r1   scorecomment)	r3   test_tracking_is_disabledr0   r;   get_cached_clientr5   submitcreate_feedbackr9   )r   r@   messages      r   _submit_feedback_Matcher._submit_feedbackl   sa    1133<<!335NN!!,,||! "  4r   c                     U(       d   U5       eU R                  SSU R                   SU 3S9  g ! [         a#  nU R                  S[        U5      5        US eS nAff = f)N   z	Success: .)rF   r   )rG   r1   AssertionErrorrepr)r   	conditionrF   method_namees        r   _assert_Matcher._assertx   sd    	%g%9!!!y
!K=-Q!R 	!!!T!W-	s   .1 
AAAc           	     ~    U R                  U R                  U:  SU R                   SU SU R                   3S5        g)zAssert 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rQ   r2   r1   r   r2   s     r   rV   _Matcher.to_be_less_than   s>     	JJz!25'DJJ<P	
r   c           	     ~    U R                  U R                  U:  SU R                   SU SU R                   3S5        g)zAssert 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.
rT   z to be greater than rU   to_be_greater_thanNrW   rX   s     r   r[   _Matcher.to_be_greater_than   s>     	JJz!5eWJtzzlS 	
r   c                    U R                  XR                  s=:  =(       a    U:  Os  SU R                   SU SU SU R                   3S5        g)a  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 given min and max.
rT   z to be between z and rU   to_be_betweenNrW   )r   	min_value	max_values      r   r^   _Matcher.to_be_between   sP     	

..Y.z5 L

|%		
r   c           	         U R                  [        U R                  U5      [        X5      :H  SU R                   SU SU R                   3S5        g)a3  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.
rT   z to be approximately rU   to_be_approximatelyN)rQ   roundr2   r1   )r   r2   	precisions      r   rc   _Matcher.to_be_approximately   sJ     	$**i(E%,CCz!6ugZ

|T!	
r   c           	     ~    U R                  U R                  U:H  SU R                   SU SU R                   3S5        g)zAssert 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.
rT   z to be equal to rU   to_equalNrW   rX   s     r   rh   _Matcher.to_equal   s>     	JJ%z!1%
4::,O	
r   c                v    U R                  U R                  SL SU R                   SU R                   3S5        g)znAssert that the expectation value is None.

Raises:
    AssertionError: If the expectation value is not None.
NrT   z to be None, but got 
to_be_nonerW   r   s    r   rk   _Matcher.to_be_none   s8     	JJ$z!6tzzlC	
r   c                d    U R                  XR                  ;   SU R                   SU S3S5        g)zAssert 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.
rT   z to contain z, but it does not
to_containNrW   rX   s     r   rn   _Matcher.to_contain   s4     	ZZzeW4EF	
r   c                   [         R                  " U5      nU R                  U" U R                  5      SU SU R                   3S5        g)zAssert 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	signaturerQ   r2   r1   )r   funcfunc_signatures      r   rq   _Matcher.against   sD     !**40(TXXJ?	
r   )r0   r5   r9   r1   r2   )NN)
r   Optional[ls_client.Client]r1   r"   r2   r   r5   z,Optional[ls_utils.ContextThreadPoolExecutor]r:   Optional[str]N)r@   intrF   rx   r!   None)rN   boolrF   r"   rO   r"   r!   r{   )r2   floatr!   r{   )r_   r}   r`   r}   r!   r{   )   )r2   r}   re   rz   r!   r{   )r!   r{   )r2   r   r!   r{   )rt   r   r!   r{   )r#   r$   r%   r&   r'   r<   rG   rQ   rV   r[   r^   rc   rh   rk   rn   rq   r(   r   r   r   r*   r*   Z   sw    > CG $5*5 5 	5
 @5 5


 
$
"
 


 
r   r*   c                      \ rS rSrSrSS.SS jjrSS.       SS jjrSS.       SS jjrSS	 jrS
SSS.         SS jjr	\
SS j5       r\
SS j5       r\S4     SS jjrSS jrSrg)_Expect   z1A class for setting expectations on test results.Nr   c                   Xl         [        R                  " SS9U l        [        R
                  " U R                  R                  SS9  g )Nr-   r.   T)wait)r0   r3   r4   executoratexitregistershutdownr   r   s     r   r<   _Expect.__init__  s1     ::qI..T:r   configc          	     (   SSK Jn  U=(       d    0 nUR                  S5      (       a  SOSnU" US9nUR                  XS9nXVR                  S.nU R                  S	UUS
U SUR                   3S.5        [        U R                  S	XpR                  S9$ )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.


Examples:
    >>> expect.embedding_distance(
    ...     prediction="hello",
    ...     reference="hi",
    ... ).to_be_less_than(1.0)
r   )EmbeddingDistanceencodercustomopenair   
prediction	reference)r   metricembedding_distanceUsing z
, Metric: r@   source_inforA   r5   )	'langsmith._internal._embedding_distancer   getevaluatedistancerG   r*   r0   r   )	r   r   r   r   r   encoder_func	evaluatorr@   src_infos	            r   r   _Expect.embedding_distance  s    F 	N2#)::i#8#8xh%V4	""j"N+7I7IJ '#L>I<N<N;OP	
 LL.
 	
r   c          	     &   SSK Jn  U=(       d    0 nUR                  S5      =(       d    SnUR                  SS5      nU" US9nUR                  XS9nXVS	.n	U R	                  S
UU	SU SU 3S.5        [        U R                  S
UU R                  S9$ )a  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:
    >>> 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   rG   r*   r0   r   )
r   r   r   r   r   r   r   r   r@   r   s
             r   r   _Expect.edit_distance=  s    < 	D2H%>)>JJ0$7	 /	""j"N$='#F8=D	
 LLmm	
 	
r   c                @    [        U R                  SXR                  S9$ )zCreate 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.

Examples:
   >>> expect.value(10).to_be_less_than(20)
r2   r   )r*   r0   r   rX   s     r   r2   _Expect.valuer  s     guNNr   r@   )r1   source_run_idrA   c               r    U R                  UUSS0UUS.5        [        U R                  X!U R                  S9$ )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".

Examples:
    >>> 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   )rG   r*   r0   r   )r   r@   r1   r   rA   s        r   r@   _Expect.score  sD    ( 	 (.9!."		
 cDMMJJr   c                   g ry   r   rX   s     r   __call___Expect.__call__  s    36r   c                  g ry   r   r   s     r   r   r     s    CFr   c               L    [        US9nU[        La  UR                  U5      $ U$ )Nr   )r   r   r2   )r   r2   r   expecteds       r   r   r     s*     &)	!>>%((r   c                J   [         R                  " 5       nU(       a  UR                  OS n[        R                  " 5       (       d_  U R
                  (       d  [        R                  " 5       U l        U R                  R                  " U R
                  R                  4XAS.UD6  g g )N)r:   r1   )r6   r7   r8   r3   rB   r0   r;   rC   r   rD   rE   )r   r1   resultscurrent_runr:   s        r   rG   _Expect._submit_feedback  sy    --/)4%%$1133<<!335MM  ,,5;HO 4r   )r0   r   )r   rw   )r   r"   r   r"   r   zOptional[EmbeddingConfig]r!   r*   )r   r"   r   r"   r   zOptional[EditDistanceConfig]r!   r*   )r2   r   r!   r*   )
r@   zUnion[float, int, bool]r1   r"   r   zOptional[ls_client.ID_TYPE]rA   rx   r!   r*   )r   zls_client.Clientr!   r   )r   rw   r2   zOptional[Any]r!   zUnion[_Expect, _Matcher])r1   r"   r   dict)r#   r$   r%   r&   r'   r<   r   r   r2   r@   r
   r   r   rG   r(   r   r   r   r   r      s   ;?C ; -14
4
 4

 *4
 
4
v 043
3
 3

 -3
 
3
jO$ 59!%K&K 	K
 3K K 
KB 6 6F F  )-1		 +			
 
"	r   r   expect) r'   
__future__r   r   rr   typingr   r   r   r   r   r	   r
   	langsmithr   	ls_clientr   r6   r   r;   r   r3   r   r   r   r   r   r   r*   r   r   __all__r   r   r   <module>r      sy   /b #     * ' % 'EG	 	 N	b
 b
J{ {| 
*r   