
    Jj                    F   d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
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 dd	lmZ  ee          j        j        d
z  Zej        j        d             Zej        j        d             Zej        j        d             Z ej        j        d             Z!d Z"d Z#ej        j        d             Z$ej        j        d             Z%ej        j        d             Z&ej        j        d             Z'ej        j        d             Z(dS )zTests for runtime/providers.    )annotationsN)Path)AnthropicProviderLMStudioProviderOllamaProvider)ChatProvider)FakeProvider)FallbackProvider)OpenAIProviderfixturesc                   K   t          g dg          } d |                     dg           2              d {V }g d}||k    }|st          j        d|fd||f          dt	          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }d	d
|iz  }t          t          j	        |                    d x}}d}|j
        } ||          }d}||k    }	|	st          j        d|	fd||f          t          j        |          t          j        |          dt	          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }
dd|
iz  }t          t          j	        |                    d x}x}x}x}	}d S )N)Helloz, world.c                "   K   g | 3 d {V }|
6 S N .0cs     E/Users/jameslopez/projects/MentorCore/tests/runtime/test_providers.py
<listcomp>z@test_fake_provider_streams_deterministically.<locals>.<listcomp>   .      MMMMMMMM!aMMMM   ssystemmessages==z%(py0)s == %(py3)schunkspy0py3assert %(py5)spy5 zHello, world.zJ%(py6)s
{%(py6)s = %(py3)s
{%(py3)s = %(py1)s.join
}(%(py4)s)
} == %(py9)spy1r%   py4py6py9assert %(py11)spy11)r	   stream_chat
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationjoin)providerr"   @py_assert2@py_assert1@py_format4@py_format6@py_assert0@py_assert5@py_assert8@py_assert7@py_format10@py_format12s               r   ,test_fake_provider_streams_deterministicallyrF      s=     :::;<<HMMx3333LLMMMMMMMMMF222262222222222262222222222222622222622222222222222222222222222222222-27-776??-o-?o----------?o-----2----7-----------6-----6------?----o---------------------------------    c                   K   t          dgdgg          } d |                     dg           2              d {V }d |                     dg           2              d {V }d}|j        } ||          }d}||k    }|st          j        d|fd	||f          t          j        |          t          j        |          d
t          j                    v st          j        |          rt          j        |          nd
t          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}x}x}}d}|j        } ||          }d}||k    }|st          j        d|fd	||f          t          j        |          t          j        |          dt          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }dd|iz  }	t          t          j
        |	                    d x}x}x}x}}d S )NzFirst.zSecond.c                "   K   g | 3 d {V }|
6 S r   r   r   s     r   r   z7test_fake_provider_cycles_responses.<locals>.<listcomp>"   .      LLLLLLLLQLLLLr   r   r   c                "   K   g | 3 d {V }|
6 S r   r   r   s     r   r   z7test_fake_provider_cycles_responses.<locals>.<listcomp>#   r   r   r(   r   r)   firstr*   r/   r0   secondr	   r1   r:   r2   r3   r7   r4   r5   r6   r8   r9   
r;   rL   rM   r@   r<   rA   rB   rC   rD   rE   s
             r   #test_fake_provider_cycles_responsesrP      s     hZ)566HLLh22#2KKLLLLLLLLLEMMx3333LLMMMMMMMMMF%27%775>>%X%>X%%%%%%%%%%>X%%%%%2%%%%7%%%%%%%%%%%5%%%%%5%%%%%%>%%%%X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'27'776??'i'?i''''''''''?i'''''2''''7'''''''''''6'''''6''''''?''''i'''''''''''''''''''''''''''''''''rG   c                   K   t          dgg          } d |                     dg           2              d {V }d |                     dg           2              d {V }d}|j        } ||          }d}||k    }|st          j        d|fd||f          t          j        |          t          j        |          d	t          j                    v st          j        |          rt          j        |          nd	t          j        |          t          j        |          d
z  }dd|iz  }	t          t          j
        |	                    d x}x}x}x}}d S )NzOnly.c                "   K   g | 3 d {V }|
6 S r   r   r   s     r   r   zBtest_fake_provider_repeats_last_when_exhausted.<locals>.<listcomp>+   s.      HHHHHHHHQHHHHr   r   r   c                "   K   g | 3 d {V }|
6 S r   r   r   s     r   r   zBtest_fake_provider_repeats_last_when_exhausted.<locals>.<listcomp>,   r   r   r(   r   r)   rM   r*   r/   r0   rN   )
r;   _rM   r@   r<   rA   rB   rC   rD   rE   s
             r   .test_fake_provider_repeats_last_when_exhaustedrU   (   s     gYK((HHH(..cB.GGHHHHHHHHHAMMx3333LLMMMMMMMMMF%27%776??%g%?g%%%%%%%%%%?g%%%%%2%%%%7%%%%%%%%%%%6%%%%%6%%%%%%?%%%%g%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%rG   c                   K   t          j        t          dz            } d |                     dg           2              d {V }d |                     dg           2              d {V }d}|j        } ||          }d}||k    }|st          j        d|fd	||f          t          j        |          t          j        |          d
t          j	                    v st          j
        |          rt          j        |          nd
t          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}x}x}}d}|j        } ||          }d}||k    }|st          j        d|fd	||f          t          j        |          t          j        |          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          t          j        |          dz  }dd|iz  }	t          t          j        |	                    d x}x}x}x}}d S )Nzresponses.jsonlc                "   K   g | 3 d {V }|
6 S r   r   r   s     r   r   z1test_fake_provider_from_jsonl.<locals>.<listcomp>3   rJ   r   r   r   c                "   K   g | 3 d {V }|
6 S r   r   r   s     r   r   z1test_fake_provider_from_jsonl.<locals>.<listcomp>4   r   r   r(   zYou ask about virtue.r   r)   rL   r*   r/   r0   z)The impediment to action advances action.rM   )r	   
from_jsonlFIXTURESr1   r:   r2   r3   r7   r4   r5   r6   r8   r9   rO   s
             r   test_fake_provider_from_jsonlr[   0   s     &x2C'CDDHLLh22#2KKLLLLLLLLLEMMx3333LLMMMMMMMMMF4274775>>444>44444444444>444444244447444444444445444445444444>444444444444444444444444444444444444I27I776??III?IIIIIIIIIII?IIIIII2IIII7IIIIIIIIIII6IIIII6IIIIII?IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIrG   c                     t          j        t                    5  t          g            d d d            d S # 1 swxY w Y   d S r   )pytestraises
ValueErrorr	   r   rG   r   "test_fake_provider_raises_on_emptyr`   9   s    	z	"	"  R                 s   7;;c                 r   t          j        d          } t          | t                    }|sddt	          j                    v st          j        t                    rt          j        t                    nddt	          j                    v st          j        |           rt          j        |           nddt	          j                    v st          j        t                    rt          j        t                    ndt          j        |          dz  }t          t          j
        |                    d }d S )Nhiz5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstancer;   r   )r$   r+   py2r,   )r	   singlerc   r   r4   r5   r2   r6   r7   r8   r9   )r;   @py_assert3@py_format5s      r   %test_fake_provider_satisfies_protocolrh   C   s   "4((Hh---------------:-----:-------------h-----h--------------------------------------------rG   c                   K   |                      dd           t          j        t          d          5  t	                       d d d            d S # 1 swxY w Y   d S )NANTHROPIC_API_KEYF)raising)match)delenvr]   r^   r_   r   )monkeypatchs    r   *test_anthropic_provider_raises_without_keyro   M   s      *E:::	z)<	=	=	=                   s   AAAc                <  K   |                      dd            G d d           G fdd          }t           |                      }d |                    d	g 
          2              d {V }ddg}||k    }|st          j        d|fd||f          dt          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }dd|iz  }t          t          j
        |                    d x}}d S )NOPENAI_API_KEYztest-keyc                      e Zd Zd ZdS )Atest_openai_provider_streams_response_text.<locals>.FakeResponsesc                  K   |d         }d}||u }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }dd|iz  }t          t          j        |                    d x}x}}|d         }|s:d	d
t          j        |          iz  }t          t          j        |                    d }d } |            S )NstreamT)is)z%(py1)s is %(py4)sr+   r,   assert %(py6)sr-   modelzassert %(py1)sr+   c                   K    t          ddddd                      W V   t          ddddd                      W V  d S )NEventr   zresponse.output_text.deltar   )typedelta world)r|   r   rG   r   eventszXtest_openai_provider_streams_response_text.<locals>.FakeResponses.create.<locals>.events]   sf      ad7B1MX_(`(`aaccccccbd7B1MX`(a(abbddddddddrG   )r2   r3   r7   r8   r9   )	selfkwargsr@   rf   r<   rg   @py_format7@py_format2r   s	            r   createzHtest_openai_provider_streams_response_text.<locals>.FakeResponses.createY   s     (#+t+#t++++++++++#t+++++#++++t+++++++++++++++++++++++++++'?"?"""""?""""""""""""""""e e e 688OrG   N)__name__
__module____qualname__r   r   rG   r   FakeResponsesrs   X   s#        	 	 	 	 	rG   r   c                  $    e Zd Z              ZdS )>test_openai_provider_streams_response_text.<locals>.FakeClientN)r   r   r   	responses)r   s   r   
FakeClientr   c   s        !MOO			rG   r   )clientc                "   K   g | 3 d {V }|
6 S r   r   r   chunks     r   r   z>test_openai_provider_streams_response_text.<locals>.<listcomp>g   .      UUUUUUUUeeUUUUr   r   r   r   r~   r   r!   r"   r#   r&   r'   )setenvr   r1   r2   r3   r4   r5   r6   r7   r8   r9   )	rn   r   r;   r"   r<   r=   r>   r?   r   s	           @r   *test_openai_provider_streams_response_textr   T   s     '444	 	 	 	 	 	 	 	$ $ $ $ $ $ $ $ $ $ ZZ\\222HUUx';';3QS';'T'TUUUUUUUUUFx((6(((((((((((6(((((((((((((6(((((6((((((((((((((((((((((((((((((((((rG   c                   K    G d d          }  G d d          }t           |              |                      }d |                    dg           2              d {V }dg}||k    }|st          j        d	|fd
||f          dt	          j                    v st          j        |          rt          j        |          ndt          j        |          dz  }dd|iz  }t          t          j	        |                    d x}}d S )Nc                      e Zd Zd ZdS )Ptest_fallback_provider_retries_only_before_first_output.<locals>.FailingProviderc               $   K   t          d          )Nzprimary unavailable)RuntimeErrorr   rT   s     r   r1   z\test_fallback_provider_retries_only_before_first_output.<locals>.FailingProvider.stream_chatn   s      4555rG   Nr   r   r   r1   r   rG   r   FailingProviderr   m   s#        	 	 	 	 	rG   r   c                      e Zd Zd ZdS )Ptest_fallback_provider_retries_only_before_first_output.<locals>.WorkingProviderc                  K   dW V  d S )Nfallbackr   r   s     r   r1   z\test_fallback_provider_retries_only_before_first_output.<locals>.WorkingProvider.stream_chats   s      rG   Nr   r   rG   r   WorkingProviderr   r   s#        	 	 	 	 	rG   r   c                "   K   g | 3 d {V }|
6 S r   r   r   s     r   r   zKtest_fallback_provider_retries_only_before_first_output.<locals>.<listcomp>w   r   r   r   r   r   r   r!   r"   r#   r&   r'   )
r
   r1   r2   r3   r4   r5   r6   r7   r8   r9   )r   r   r;   r"   r<   r=   r>   r?   s           r   7test_fallback_provider_retries_only_before_first_outputr   k   sz            
          1 1??3D3DEEHUUx';';3QS';'T'TUUUUUUUUUF \!6\!!!!!!!!!!6\!!!!!!!!!!!!6!!!!!6!!!!!!\!!!!!!!!!!!!!!!!!!!!!!!!!!!rG   c                   K   dd l dfd} t          dd                    |           	          }d
 |                    dg           2              d {V }ddg}||k    }|st	          j        d|fd||f          dt          j                    v st	          j        |          rt	          j	        |          ndt	          j	        |          dz  }dd|iz  }t          t	          j        |                    d x}}d S )Nr   requesthttpx.Requestreturnhttpx.Responsec           	       K   | j         }j        }d} ||          }||k    }|st          j        d|fd||f          dt	          j                    v st          j        |           rt          j        |           ndt          j        |          dt	          j                    v st          j                  rt          j                  ndt          j        |          t          j        |          t          j        |          dz  }dd|iz  }t          t          j	        |                    d x}x}x}x}}t          j        | j                  d	         }d
}||k    }	|	slt          j        d|	fd||f          t          j        |          t          j        |          dz  }
dd|
iz  }t          t          j	        |                    d x}x}	}                    dd          S )Nz#http://lm.local/v1/chat/completionsr   )zd%(py2)s
{%(py2)s = %(py0)s.url
} == %(py10)s
{%(py10)s = %(py6)s
{%(py6)s = %(py4)s.URL
}(%(py8)s)
}r   httpx)r$   rd   r,   r-   py8py10zassert %(py12)spy12ry   local-model)z%(py1)s == %(py4)srw   rx   r-      zudata: {"choices":[{"delta":{"content":"Hello"}}]}

data: {"choices":[{"delta":{"content":" world"}}]}

data: [DONE]

)content)urlURLr2   r3   r4   r5   r6   r7   r8   r9   jsonloadsr   Response)r   r=   rA   rC   @py_assert9rf   @py_format11@py_format13r@   r<   rg   r   r   s               r   handlerz:test_lmstudio_provider_streams_openai_sse.<locals>.handler   s:     {NeiN(MNii(MNNN{NNNNNNNNNNN{NNNNNNNNNNNNNwNNNNNwNNNNNN{NNNNNNNNNNNeNNNNNeNNNNNNiNNNN(MNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNz'/**73D}D3}DDDDDDDDDD3}DDDDD3DDDD}DDDDDDDDDDDDDDDDDDDDDDDDDDD~~#  
 
 	
rG   zhttp://lm.local/v1r   )base_urlry   	transportc                "   K   g | 3 d {V }|
6 S r   r   r   s     r   r   z=test_lmstudio_provider_streams_openai_sse.<locals>.<listcomp>   r   r   r   r   r   r~   r   r!   r"   r#   r&   r'   )r   r   r   r   )r   r   MockTransportr1   r2   r3   r4   r5   r6   r7   r8   r9   )r   r;   r"   r<   r=   r>   r?   r   s          @r   )test_lmstudio_provider_streams_openai_sser   {   sg     LLL

 

 

 

 

 

  %%%g..  H
 VUx';';3QS';'T'TUUUUUUUUUFx((6(((((((((((6(((((((((((((6(((((6((((((((((((((((((((((((((((((((((rG   c                    K   t                      } t          j        t                    5  |                     dg           2 3 d {V }6 	 d d d            d S # 1 swxY w Y   d S )Nr   r   )r   r]   r^   NotImplementedErrorr1   )r;   rT   s     r   +test_ollama_provider_raises_not_implementedr      s      H	*	+	+  ++3+DD 	 	 	 	 	 	 	! ED                 s   AA
AA A))__doc__
__future__r   builtinsr4   _pytest.assertion.rewrite	assertionrewriter2   r   pathlibr   r]   $runtime.providers.anthropic_providerr   r   r   runtime.providers.baser   runtime.providers.faker	   runtime.providers.fallbackr
   !runtime.providers.openai_providerr   __file__parentrZ   markasynciorF   rP   rU   r[   r`   rh   ro   r   r   r   r   r   rG   r   <module>r      s-   " " " " " " " "                      d d d d d d d d d d / / / / / / / / / / / / 7 7 7 7 7 7 < < < < < <4>> '*4 . . . ( ( ( & & & J J J  . . .    ) ) ), " " " ) ) ):     rG   