+
    *jg  c                      R t ^ RIHt ^ RIt^ RIHu Ht ^ RI	t	^ RI
t
^ RIt^ RIt^ RIHt ]P                  R 4       tR tR tR tR R	 ltR
 tR tR tR tR tR tR tR tR# )zBDD tests for runtime/api/chat.py.

Given: compiled test-persona fixture package (personas/examples/test-persona)
When:  user sends a message about a corpus topic
Then:  streamed SSE reply contains relevant persona content (via FakeProvider)
)annotationsN)
TestClientc                ~    VP                  RR4       VP                  R\        V 4      4       ^ RIHp \	        V4      # )z;TestClient with FakeProvider and examples/ as persona root.FAKE_PROVIDER1MENTORCORE_PERSONAS_ROOTapp)setenvstrruntime.api.appr   r   )examples_persona_rootmonkeypatchr   s   && D/Users/jameslopez/projects/MentorCore/tests/runtime/test_chat_api.pyclientr      s8     ,137L3MN#c?    c                4   V P                  R RR7       ^ RIHu Hp VP	                  4       pVP
                  pRqCV8H  qU'       g   \        P                  ! RV3RW434      RR\        P                  ! 4       9   g   \        P                  ! V4      '       d   \        P                  ! V4      MRR\        P                  ! V4      R\        P                  ! V4      /,          pR	R
V/,          p\        \        P                  ! V4      4      hR;p;rTVP                  q3P
                  pRqV8H  q'       g   \        P                  ! RV	3RWX34      RR\        P                  ! 4       9   g   \        P                  ! V4      '       d   \        P                  ! V4      MRR\        P                  ! V4      R\        P                  ! V4      R
\        P                  ! V4      /,          pRRV/,          p
\        \        P                  ! V
4      4      hR;p;p;rR# )r   F)raisingNpersonaspy0rootpy2py5assert %(py7)spy7
MentorCorepy4zassert %(py9)spy9==)z,%(py2)s
{%(py2)s = %(py0)s.name
} == %(py5)s)zH%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.parent
}.name
} == %(py7)s)delenvruntime.api.chatapichat_personas_rootname
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationparent)r   chat_moduler   @py_assert1@py_assert4@py_assert3@py_format6@py_format8@py_assert6@py_assert5@py_format10s   &          r   5test_default_personas_root_points_at_project_personasr7       s$   15A**%%'D99"
"
"""""9""""""4""""4"""9"""
"""""""";;++|+|+++++++++++4++++4+++;++++++|++++++++r   c           	        V P                  R4      pVP                  p^q2V8H  qD'       g   \        P                  ! RV3RW#34      RR\        P
                  ! 4       9   g   \        P                  ! V4      '       d   \        P                  ! V4      MRR\        P                  ! V4      R\        P                  ! V4      /,          pRRV/,          p\        \        P                  ! V4      4      hR;p;rCVP                  4        Uu. uF  qwR	,          NK  	  ppR
qV9   q'       g   \        P                  ! RV
3RW34      R\        P                  ! V	4      RR\        P
                  ! 4       9   g   \        P                  ! V4      '       d   \        P                  ! V4      MR/,          pRRV/,          p\        \        P                  ! V4      4      hR;rR# u upi )zVGiven: examples/ has test-persona. When: GET /api/personas. Then: test-persona listed./api/personasr   respr   r   r   r   Nslugtest-personapy1py3slugszassert %(py5)sr   z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)sin)z%(py1)s in %(py3)sgetstatus_coder%   r&   r'   r(   r)   r*   r+   r,   json)r   r:   r/   r0   r1   r2   r3   pr?   @py_assert0@py_assert2@py_format4s   &           r   'test_list_personas_returns_test_personarK   )   s   ::o&D"s"s"""""""""""4""""4""""""s"""""""" $		,1vYYE,"U""""">""">""""""U""""U"""""""" -s   Gc                   V P                  R 4      pVP                  4        Uu/ uF  q"R,          VbK  	  ppVR,          R,          pRqTV8H  qf'       gy   \        P                  ! R
V3RWE34      R\        P                  ! V4      R\        P                  ! V4      /,          pRRV/,          p\        \        P                  ! V4      4      hR	;p;reR	# u upi )r9   r;   r<   display_namezTest Personar=   r   assert %(py6)spy6Nr   z%(py1)s == %(py4)s)rD   rF   r%   r&   r*   r+   r,   )	r   r:   rG   r   rH   r1   rI   @py_format5@py_format7s	   &        r   #test_list_personas_has_display_namerS   1   s    ::o&D&*iik2k&	1kH2N#N3E~E~EEEEE3EEE3EEE~EEEEEEEE 3s   Cc                    V ^8  d   QhRRRR/# )   bodyr
   returnz
list[dict] )formats   "r   __annotate__rZ   :   s      S Z r   c                    . pV P                  4        FH  pVP                  R 4      '       g   K  VP                  \        P                  ! VR,          4      4       KJ  	  V# )zdata: :   NN)
splitlines
startswithappendrF   loads)rV   eventslines   &  r   
_parse_sserc   :   sG    F!??8$$MM$**T"X./ " Mr   c           	     0   V P                  RRR/R7      pVP                  p^q2V8H  qD'       g   \        P                  ! RV3RW#34      RR\        P
                  ! 4       9   g   \        P                  ! V4      '       d   \        P                  ! V4      MRR\        P                  ! V4      R\        P                  ! V4      /,          pR	R
V/,          p\        \        P                  ! V4      4      hR;p;rCRqqP                  R,          qGV9   q'       gy   \        P                  ! RV3RWt34      R\        P                  ! V4      R\        P                  ! V4      /,          p	RRV	/,          p
\        \        P                  ! V
4      4      hR;p;rR# )zRGiven: test-persona. When: POST /api/chat/test-persona. Then: SSE stream received./api/chat/test-personamessagezTell me about virtue.rF   r   r:   r   r   r   r   Nztext/event-streamzcontent-typer=   r   rN   rO   r   r@   rA   z%(py1)s in %(py4)s)postrE   r%   r&   r'   r(   r)   r*   r+   r,   headersr   r:   r/   r0   r1   r2   r3   rH   rI   rQ   rR   s   &          r   test_chat_streams_sserl   B   s    ;; 01  D "s"s"""""""""""4""""4""""""s"""""""">,,~">>">>>>>>>>>>>>">>>>>>>>>r   c                (   V P                  R RR/R7      p\        VP                  4      pV Uu. uF  q3P                  R4      R8X  g   K  VNK  	  pp\	        V4      p^ qeV8  qw'       Eg   \
        P                  ! RV3RWV34      RR\        P                  ! 4       9   g!   \
        P                  ! \        4      '       d   \
        P                  ! \        4      MRRR	\        P                  ! 4       9   g   \
        P                  ! V4      '       d   \
        P                  ! V4      MR	R
\
        P                  ! V4      R\
        P                  ! V4      /,          pRRV/,          p	\        \
        P                  ! V	4      4      hR;p;rvR# u upi )re   rf   zWhat do you say about virtue?rg   typetextr   lenr=   text_eventsr>   rO   assert %(py8)spy8N)>)z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)sri   rc   ro   rD   rp   r%   r&   r'   r(   r)   r*   r+   r,   )
r   r:   ra   erq   rI   r5   r0   rR   @py_format9s
   &         r   $test_chat_reply_contains_text_eventsrx   L   s    ;; 89  D 		"F$@ff(?11fK@{aa33{{a As   FFc                   V P                  R RR/R7      p\        VP                  4      pVR,          R,          pRqCV8H  qU'       gy   \        P                  ! RV3RW434      R\        P
                  ! V4      R\        P
                  ! V4      /,          pRR	V/,          p\        \        P                  ! V4      4      hR
;p;rTR
# )re   rf   Hellorg   rn   doner=   r   rN   rO   Nr   rP   )ri   rc   ro   r%   r&   r*   r+   r,   )r   r:   ra   rH   r1   rI   rQ   rR   s   &       r   test_chat_reply_ends_with_doner}   V   s    ;; !  D 		"F":f'''''''''''''''''''''r   c                L   V P                  R RR/R7      p\        VP                  4      pV Uu. uF  q3P                  R4      R8X  g   K  VNK  	  pp\	        V4      p^qeV8H  qw'       Eg   \
        P                  ! RV3RWV34      RR\        P                  ! 4       9   g!   \
        P                  ! \        4      '       d   \
        P                  ! \        4      MRRR	\        P                  ! 4       9   g   \
        P                  ! V4      '       d   \
        P                  ! V4      MR	R
\
        P                  ! V4      R\
        P                  ! V4      /,          pRRV/,          p	\        \
        P                  ! V	4      4      hR;p;rvRq^ ,          qV9   qU'       gy   \
        P                  ! RV3RW34      R\
        P                  ! V
4      R\
        P                  ! V4      /,          pRRV/,          p\        \
        P                  ! V4      4      hR;p
;r[R# u upi )re   rf   rz   rg   rn   sessionr   rp   r=   session_eventsr>   rO   rr   rs   N
session_idr   rN   r   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)srA   rh   ru   )r   r:   ra   rv   r   rI   r5   r0   rR   rw   rH   r1   rQ   s   &            r   test_chat_returns_session_idr   _   s<   ;;/y'6J;KD		"F!'FA55=I+EaaNF~#!#!###########3####3#######~####~######!########,!,,,,,,,,<,,,<,,,,,,,,,,,, Gs   H!H!c           	     .   V P                  RRR/R7      p\        VP                  4      p\        R V 4       4      pV P                  RRRRV/R7      pVP                  p^qeV8H  qw'       g   \
        P                  ! RV3RWV34      RR	\        P                  ! 4       9   g   \
        P                  ! V4      '       d   \
        P                  ! V4      MR	R
\
        P                  ! V4      R\
        P                  ! V4      /,          pRRV/,          p	\        \
        P                  ! V	4      4      hR;p;rv\        VP                  4      p
R V
 4       p\        V4      qw'       g   RRR\        P                  ! 4       9   g!   \
        P                  ! \        4      '       d   \
        P                  ! \        4      MRR
\
        P                  ! V4      R\
        P                  ! V4      /,          p\        \
        P                  ! V4      4      hR;rWR# )zRGiven: session_id from turn 1. When: turn 2 sends same session_id. Then: accepted.re   rf   rz   rg   c              3  b   "   T F%  qP                  R 4      R8X  g   K  VR,          x  K'  	  R# 5i)rn   r   r   NrD   .0rv   s   & r   	<genexpr>5test_chat_multiturn_reuses_session.<locals>.<genexpr>k   s%     Uw!%%-9:Toaoows   //z	Continue.r   r   resp2r   r   r   r   Nc              3  H   "   T F  qP                  R 4      R8H  x  K  	  R# 5i)rn   r{   Nr   r   s   & r   r   r   s   s     81uuV}&s    "z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyr   r   r@   )ri   rc   ro   nextrE   r%   r&   r'   r(   r)   r*   r+   r,   r   )r   resp1events1r   r   r/   r0   r1   r2   r3   events2rQ   s   &           r   "test_chat_multiturn_reuses_sessionr   g   sE   KK0	77KKLE$GUwUUJKK lJ?  E #############5####5##############$G8883888888888838888388888888888888r   c           	        V P                  R RR/R7      pVP                  pRq2V8H  qD'       g   \        P                  ! RV3RW#34      RR\        P
                  ! 4       9   g   \        P                  ! V4      '       d   \        P                  ! V4      MRR\        P                  ! V4      R\        P                  ! V4      /,          pR	R
V/,          p\        \        P                  ! V4      4      hR;p;rCR# )z/api/chat/nonexistentrf   Hirg   i  r   r:   r   r   r   r   Nr   r@   )
ri   rE   r%   r&   r'   r(   r)   r*   r+   r,   )r   r:   r/   r0   r1   r2   r3   s   &      r   %test_chat_unknown_persona_returns_404r   v   s    ;;.i5F;GD"s"s"""""""""""4""""4""""""s""""""""r   c           	        a VR ,          p\         P                  ! WR,          4       VR,          R,          p\        P                  ! VP	                  4       4      p^VR&   VP                  \        P                  ! V4      4       / oR^RR/V3R llpVP                  RR	4       VP                  R
\        V4      4       ^ RI	H
u Hp ^ RIHp VP                  VRV4       \        V4      p	V	P!                  RRR/R7      p
V
P"                  p^qV8H  q'       g   \$        P&                  ! RV3RW34      RR\(        P*                  ! 4       9   g   \$        P,                  ! V
4      '       d   \$        P.                  ! V
4      MRR\$        P.                  ! V4      R\$        P.                  ! V4      /,          pRRV/,          p\1        \$        P2                  ! V4      4      hR;p;rSR,          p^pVV8H  pV'       gz   \$        P&                  ! RV3RVV34      R\$        P.                  ! V4      R\$        P.                  ! V4      /,          pRRV/,          p\1        \$        P2                  ! V4      4      hR;p;ppR# )r   r<   zpersona.yamlretrieval_top_ktop_kembedderNc                  < VSR &   . # )r   rX   )query	index_dirr   r   observeds   &&$$r   fake_retrieve>test_chat_uses_manifest_retrieval_top_k.<locals>.fake_retrieve   s    !	r   r   r   r   r   retrievere   rf   rz   rg   r   r:   r   r   r   r   r=   r   rN   rO   r   r@   rP   )shutilcopytreeyaml	safe_load	read_text
write_textdumpr	   r
   r    r!   r"   r   r   setattrr   ri   rE   r%   r&   r'   r(   r)   r*   r+   r,   )test_persona_dirtmp_pathr   r   manifest_pathmanifestr   r.   r   r   r:   r/   r0   r1   r2   r3   rH   rI   rQ   rR   r   s   &&&                 @r   'test_chat_uses_manifest_retrieval_top_kr   {   s   j D
OO$^&;<>)N:M~~m5578H"#HTYYx01H T  ,13t9=**#Z?_F;;/y'6J;KD"s"s"""""""""""4""""4""""""s""""""""G!!!!!!!!!!!!!!!!!!!!!r   c           	     2   V P                  R 4      pVP                  p^q2V8H  qD'       g   \        P                  ! RV3RW#34      RR\        P
                  ! 4       9   g   \        P                  ! V4      '       d   \        P                  ! V4      MRR\        P                  ! V4      R\        P                  ! V4      /,          pRRV/,          p\        \        P                  ! V4      4      hR;p;rCVP                  4       R,          pR	qGV8H  q'       gy   \        P                  ! RV3RWt34      R
\        P                  ! V4      R\        P                  ! V4      /,          p	RRV	/,          p
\        \        P                  ! V
4      4      hR;p;rR# )z/healthr   r:   r   r   r   r   Nstatusokr=   r   rN   rO   r   r@   rP   rC   rk   s   &          r   test_health_endpointr      s    ::i D"s"s"""""""""""4""""4""""""s""""""""99;x (D(D((((( ((( (((D((((((((r   )__doc__
__future__r   builtinsr'   _pytest.assertion.rewrite	assertionrewriter%   rF   r   pytestr   fastapi.testclientr   fixturer   r7   rK   rS   rc   rl   rx   r}   r   r   r   r   r   rX   r   r   <module>r      sw    #       )  ,#F? (-9#
"8)r   