
    aXSj                       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
Z
ddlZde
j                  d<   e
j                  j                  dd       ddlZddlmZmZ  G d	 d
      Z G d d      Z G d d      Z G d d      ZddZd Zd Zd Zd Zd Zd Zedk(  rY e e        jC                               D ]2  \  Z"Z#e"jI                  d      s e%e#      s! e#         e&de"        4  e&d       yy)u  ASYNC_BRAIN routing tests — no audio, no models, no Claude session.

Verifies the chat-supervisor routing in VoiceApp.respond():
  handoff -> background dispatch (the floor is freed), chat-while-busy
  carries the task note to the fast lane, a second handoff queues, a
  voice-cancel kills the task + queue, finished replies land in _ready,
  and ASYNC_BRAIN=0 keeps the old blocking path.

Run:  .venv/bin/python -m pytest test_async_brain.py -q
    )annotationsN0RESUMEASYNC_BRAIN1)VoiceApp_CANCEL_TASK_REc                  &    e Zd ZddZddZdddZy)		FakeBrainc                >    g | _         d| _        d| _        dg| _        y )Nr   g?
Done, sir.)asked
interruptsdelayrepliesselfs    >/Users/ahmed/devFolder/Ultron/claude-voice/test_async_brain.py__init__zFakeBrain.__init__   s      "

$~    c                  K   | j                   j                  |       t        j                  | j                         d {    | j
                  D ]  }| 	 y 7 wN)r   appendasynciosleepr   r   )r   textss      r   replyzFakeBrain.reply    sF     

$mmDJJ'''AG  	(s   >A AAc                6   K   | xj                   dz  c_         y wN   )r   r   timeouts     r   	interruptzFakeBrain.interrupt&   s     1s   NreturnNoner   strg      ?r#   floatr&   r'   )__name__
__module____qualname__r   r   r$    r   r   r   r      s    &r   r   c                  &    e Zd ZddZddZdddZy)	FakeFastc                     d| _         g | _        y )Nhandoff)moder   r   s    r   r   zFakeFast.__init__+   s    	 "
r   c               v   K   | j                   j                  |       | j                  dk(  rd y d y w)Nr4   )r4   N)sayRight you are, sir.)r   r   r5   r   r   s     r   classify_and_replyzFakeFast.classify_and_reply/   s0     

$99	!##00s   79c                   K   y wr   r0   r"   s     r   r$   zFakeFast.interrupt6   s	     s   Nr%   r(   r*   r+   )r-   r.   r/   r   r:   r$   r0   r   r   r2   r2   *   s    #1r   r2   c                      e Zd ZdZddZy)FakeTTSTc                L    t        j                  dt         j                        S )N   )dtype)npzerosint16r9   s     r   synthzFakeTTS.synth=   s    xx**r   Nr(   )r-   r.   r/   accepts_tagsrD   r0   r   r   r=   r=   :   s    L+r   r=   c                  $    e Zd ZddZddZddZy)FakeSpeakerc                     d| _         d| _        y )Nr   F)playedspeakingr   s    r   r   zFakeSpeaker.__init__B   s    r   c                .    | xj                   dz  c_         y r    )rI   )r   pcms     r   playzFakeSpeaker.playF   s    qr   c                     y r   r0   r   s    r   cutzFakeSpeaker.cutI   s    r   Nr%   )r-   r.   r/   r   rM   rO   r0   r   r   rG   rG   A   s    r   rG   c                     t               t               _        t               _        t               _        t               _        g _	        dfd	} | _
        S )Nc                   K   g }| 2 3 d {   }|j                  |       7 6 j                  j                  ||f       y wr   )r   spoken_turns)sourcebrainoutr   apps       r   fake_sawz_app.<locals>.fake_sawU   sA      	!JJqM	ve-s   A%#%A%Ar   )r   r   rT   r2   fastr=   ttsrG   speakerrR   _speak_and_watch)rW   rV   s    @r   _appr\   M   sJ    
*CCIzCHiCG-CKC.
 $CJr   c                 >    d } t        j                   |               y )Nc                   K   t               } t        j                         j                         }| j	                  d       d {    t        j                         j                         |z
  }d}||k  }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d      dz   d	|iz  }t        t        j                  |            d x}}| j                  }d }||u}|st        j                  d
|fd||f      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}}| j                   d {    | j                  }dgg}||k(  }|st        j                  d|fd||f      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}}| j                   }|j"                  }dg}
||
k(  }|st        j                  d|fd||
f      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}}
y 7 w7 w)Nzfix the failing testsg      ?)<)z%(py0)s < %(py3)stook)py0py3z*respond() must not block on the brain turnz
>assert %(py5)spy5)is not)z7%(py2)s
{%(py2)s = %(py0)s._brain_task
} is not %(py5)srV   ra   py2rc   assert %(py7)spy7r   ==z.%(py2)s
{%(py2)s = %(py0)s._ready
} == %(py5)szH%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.brain
}.asked
} == %(py7)sra   rf   py4rh   assert %(py9)spy9)r\   r   get_event_looptimerespond
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanation_brain_task_readyrT   r   )rV   t0r`   @py_assert2@py_assert1@py_format4@py_format6@py_assert4@py_assert3@py_format8@py_assert6@py_assert5@py_format10s                r   goz.test_handoff_dispatches_background.<locals>.go_   s6    f##%**,kk1222%%',,.3GtczGGGtcGGGGGGtGGGtGGGcGGGGGGGGGG*d*d****d******s***s******d*******oozz-|n--z-----z-------s---s---z-----------yy;y;#:";;";;;;;";;;;;;;s;;;s;;;y;;;;;;";;;;;;;; 	3 	s&   AO N:F;O ?N= F;O =O r   runr   s    r   "test_handoff_dispatches_backgroundr   ^   s    	< KKr   c                 >    d } t        j                   |               y )Nc                   K   t               } d| j                  _        | j                  d       d {    d| j                  _        | j                  d       d {    d}| j                  j                  d   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            d x}x}}| j                  d   d   }dg}||k(  }|slt        j                  d|fd||f      t        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            d x}x}}| j                   d {    g }| j                  }|}|r| j                  d   }dg}||k(  }	|	}|sddt        j                          v st        j"                  |       rt        j                  |       ndt        j                  |      dz  }|j%                  |       |r_t        j                  d	fdf      t        j                  |      t        j                  |      dz  }
dd|
iz  }|j%                  |       t        j&                  |d      i z  }dd|iz  }t        t        j                  |            d x}x}x}x}x}	}y 7 7 7 Qw)Ng?zrebuild the dashboardr7   zhow is it going?zbackground task in flight)in)z%(py1)s in %(py4)s)py1rn   zassert %(py6)spy6r   r8   ri   )z%(py1)s == %(py4)sr   z#%(py4)s
{%(py4)s = %(py2)s._ready
}rV   )rf   rn   )z%(py7)s == %(py10)s)rh   py10z%(py12)spy12zassert %(py15)spy15)r\   rT   r   rs   rX   r5   r   rt   ru   ry   r{   r|   rR   r}   r~   rv   rw   rx   r   _format_boolop)rV   @py_assert0r   r   @py_format5@py_format7r   r   @py_assert9@py_assert8@py_format11@py_format13@py_format14@py_format16s                 r   r   z/test_chat_while_busy_gets_task_note.<locals>.gom   s    f		kk1222kk,---*@chhnnR.@@*.@@@@@*.@@@@*@@@.@@@@@@@@#A&A+@*AA&*AAAAA&*AAAA&AAA*AAAAAAAAoo=szz=z=zcjjm=~=m~=======s===s===z====z===m~===m===~============== 	3- 	s5   0K%K)K%KD4K%K"EK%K%"K%r   r   s    r   #test_chat_while_busy_gets_task_noter   l   s    	> KKr   c                 >    d } t        j                   |               y )Nc                   K   t               } d| j                  _        | j                  d       d {    | j                  d       d {    | j                  }dg}||k(  }|st        j                  d|fd||f      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}}| j                   d {    | j                  }|j                  }ddg}||k(  }|st        j                  d|fd
||f      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}}| j                  }	t!        |	      }d}
||
k(  }|s
t        j                  d|fd||
f      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t        j                  |	      t        j                  |      t        j                  |
      dz  }dd|iz  }t        t        j                  |            d x}	x}x}}
y 7 7 7 +w)Ng?ztask Aztask Bri   z4%(py2)s
{%(py2)s = %(py0)s._brain_queue
} == %(py5)srV   re   rg   rh   rl   rm   ro   rp      )zL%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s._ready
})
} == %(py8)slen)ra   r   rb   rc   py8zassert %(py10)sr   )r\   rT   r   rs   _brain_queuert   ru   rv   rw   rx   ry   r{   r|   r}   r   r~   r   )rV   r   r   r   r   r   r   r   r   r   @py_assert7@py_format9r   s                r   r   z&test_second_handoff_queues.<locals>.go{   s    f		kk(###kk(###-H:-:----:------s---s------:-------ooyy6y68X"66"66666"6666666s666s666y666666"66666666::#s:#!#!####!######s###s######3###3###:######!####### 	$#s5   0MMMMCM(M)H%MMMr   r   s    r   test_second_handoff_queuesr   z   s    $ KKr   c                 >    d } t        j                   |               y )Nc                 >	  K   t               } d| j                  _        | j                  d       d {    | j                  j                  d       | j                  d       d {    | j                  }d }||u }|st        j                  d|fd||f      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}}| j                  }g }||k(  }|st        j                  d|fd||f      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}}| j                  }|j                  }d}||k\  }|st        j                  d|fd||f      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}}| j                   }g }||k(  }|st        j                  d|fd||f      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}}| j"                  }|j$                  }d}||k\  }|st        j                  d|fd||f      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}}y 7 e7 4w)Ng      @zlong migration taskzqueued thingzcancel thatisz3%(py2)s
{%(py2)s = %(py0)s._brain_task
} is %(py5)srV   re   rg   rh   ri   r   r!   )>=)zM%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.brain
}.interrupts
} >= %(py7)srm   ro   rp   rk   )zK%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.speaker
}.played
} >= %(py7)s)r\   rT   r   rs   r   r   r}   rt   ru   rv   rw   rx   ry   r{   r|   r   r~   rZ   rI   )	rV   r   r   r   r   r   r   r   r   s	            r   r   z2test_voice_cancel_kills_task_and_queue.<locals>.go   s    f		kk/000/kk-(((&$&$&&&&$&&&&&&s&&&s&&&&&&$&&&&&&&%2%2%%%%2%%%%%%s%%%s%%%%%%2%%%%%%%yy(y##(q(#q((((#q((((((s(((s(((y(((#(((q(((((((zzRzRzRsszR{{&{!!&Q&!Q&&&&!Q&&&&&&s&&&s&&&{&&&!&&&Q&&&&&&& 	1(s"   0RR3R&R'P1RRr   r   s    r   &test_voice_cancel_kills_task_and_queuer      s    
' KKr   c                 >    d } t        j                   |               y )Nc                   K   t               } t        j                  }dt        _        	 | j                  d       d {    | j                  d   d   }| j
                  }||u }|st        j                  d|fd||f      t        j                  |      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}x}}| j                  }d }||u }|st        j                  d|fd||f      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}}|t        _        y 7 # |t        _        w xY ww)NFzdo the thingr   r!   r   )z-%(py1)s is %(py5)s
{%(py5)s = %(py3)s.brain
}rV   )r   rb   rc   rg   rh   r   re   )r\   appmodr   rs   rR   rT   rt   ru   ry   rv   rw   rx   r{   r|   r}   )	rV   oldr   r   r   r   r   r   r   s	            r   r   z-test_flag_off_keeps_blocking_path.<locals>.go   s<    f  "	%++n---##B'*7cii7*i7777*i777*777777c777c777i7777777??*d*?d****?d******3***3***?***d*******!$F .
 "%Fs-   &G?G/ G,F"G/  G?,G/ /G<<G?r   r   s    r   !test_flag_off_keeps_blocking_pathr      s    
% KKr   c                 v   g d} g d}| D ]  }t         j                  } ||      }|st        j                  d|      dz   dt	        j
                         v st        j                  t               rt        j                  t               ndt        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d x}} |D ]  }t         j                  } ||      }| }|st        j                  d|      d	z   dt	        j
                         v st        j                  t               rt        j                  t               ndt        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            d x}x}} y )
N)stopz	stop thatzcancel the taskz
Cancel it.z
never mindzjarvis, drop itz	forget itzabort the job)zstop the musiczcancel my subscriptionzstop when you finishz"forget what I said about the colorzdrop the database tablezshould match: zI
>assert %(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.match
}(%(py3)s)
}r	   t)ra   rf   rb   rc   zshould NOT match: zM
>assert not %(py5)s
{%(py5)s = %(py2)s
{%(py2)s = %(py0)s.match
}(%(py3)s)
})
r	   matchrt   rz   rv   rw   rx   ry   r{   r|   )yesnor   r   r   r   r   r   s           r   test_cancel_regex_matrixr      sR   JC
KB$$?$Q'?'??>!)?????????????$??????Q???Q???'?????? "((G(+G++G+GG/A!-GGGGGGG?GGG?GGG(GGGGGGGGGGGG+GGGGGG r   __main__test_z  ok  z	all green)r&   r   )'__doc__
__future__r   builtinsrv   _pytest.assertion.rewrite	assertionrewritert   r   osnumpyrA   environ
setdefaultmainr   r   r	   r   r2   r=   rG   r\   r   r   r   r   r   r   r-   sortedglobalsitemsnamefn
startswithcallableprintr0   r   r   <module>r      s   	 #    	 

8  

  mS )  * "  + +	 	"
H z79??,-b??7#DF4&/" . 
+ r   