
    Pj                         d Z ddlZddlmc mZ ddlZddlZddl	Z	 G d dej                        Zd Zd Zd Zd Zd	 Zd
 Zd Z G d d      ZddZd Zd Zd Zd Zd Zd Zy)u   Two-lane router: fast-lane sentinel detection, history consistency across
lanes, and the FAST_CHAT=0 path. All LLM I/O is a scripted FakeAdapter — no
network, no real model, no TTS (tests run in chat mode).    Nc                       e Zd ZdZd Zd Zy)FakeAdapterzDReplays one scripted event list per stream() call and records usage.c                 N    t        |      | _        d| _        d | _        d| _        y )Nr   unset)list_eventscallslast_messages
last_tools)selfeventss     F/Users/ahmed/devFolder/Ultron/claude-voice/gateway/tests/test_lanes.py__init__zFakeAdapter.__init__   s#    F|
!!    c                   K   | xj                   dz  c_         |D cg c]  }t        |       c}| _        || _        | j                  D ]  }| 	 y c c}w w)N   )r	   dictr
   r   r   )r   messagestoolsmevs        r   streamzFakeAdapter.stream   sM     

a
/78x!d1gx8,,BH  9s   AA+AN)__name__
__module____qualname____doc__r   r    r   r   r   r   
   s    N"r   r   c                     d| dS )Ntext)typer   r   )ss    r   _textr"      s    A&&r   c                      dddS )Nfinishstop)r    reasonr   r   r   r   _finishr'      s    //r   c                  4  K   t        j                  t        t        t         j                        t               g      d      } | j                  g d      2 cg c3 d {   }|7 6 nc c}w }}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}}y w)
Nfast-syswhen is my meetinghandoffN==z%(py0)s == %(py3)soutpy0py3assert %(py5)spy5)brainFastLaner   r"   FAST_HANDOFFr'   run
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationlaneitemr0   @py_assert2@py_assert1@py_format4@py_format6s          r   %test_fastlane_bare_sentinel_hands_offrI   &   s     >>+uU-?-?'@')&LM$&D"&((2/C"D
E
E$4
E
E
EC
E$%%3%%%%%3%%%%%%%3%%%3%%%%%%%%%%%s7   ADA)A'A%
A'!A)%A''A)(B0Dc            	      @  K   t        j                  t        t        d      t        d      t        d      t	               g      d      } | j                  g d      2 cg c3 d {   }|7 6 nc c}w }}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}}y w)Nz<<ACTz>>r)   zrecall somethingr+   r-   r/   r0   r1   r4   r5   r6   r7   r   r"   r'   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   s          r   4test_fastlane_sentinel_split_across_deltas_hands_offrM   -   s     >>U4[%,dWYGHD #'((2/A"B
C
C$4
C
C
CC
C$%%3%%%%%3%%%%%%%3%%%3%%%%%%%%%%%s7   ADA/A-#A+
$A-'A/+A--A/.B0Dc                    K   t        j                  t        t        d      t	               g      d      } | j                  g d      2 cg c3 d {   }|7 6 nc c}w }}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}}y w)N   r)   hir+   r-   r/   r0   r1   r4   r5   rL   rB   s          r   #test_fastlane_empty_reply_hands_offrQ   5   s     >>+uU|WY&?@*MD"&((2t"4
5
5$4
5
5
5C
5$%%3%%%%%3%%%%%%%3%%%3%%%%%%%%%%%s7   AD
	AAA
AAAAB0D
c                  J
  K   t        j                  t        t        d      t        d      t	               g      d      } | j                  g d      2 cg c3 d {   }|7 6 nc c}w }}|D cg c]  \  }}|	 nc c}}w }}}|D cg c]  \  }}|dk(  s| nc c}}w }}}|D cg c]  \  }}|dk(  s| nc c}}w }}}|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}	|	|v}|st        j                  d|fd|	|f      t        j                  |	      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            d x}	}|d   }	|	j                  }d} ||      }|stdt        j                  |	      t        j                  |      t        j                  |      t        j                  |      dz  }t        t        j                  |            d x}	x}x}}d |D        }t        |      }
|
sddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      t        j                  |
      dz  }t        t        j                  |            d x}}
g }|}	|rd}|d   }||v }|}	|	sdddt        j                         v st        j                  |      rt        j                  |      ndi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}}t         j$                  }|d   }||v}
|
st        j                  d|
fd&||f      d't        j                         v st        j                  t               rt        j                  t               nd't        j                  |      t        j                  |      d(z  }d)d*|iz  }t        t        j                  |            d x}x}
}y w)+Nz[dry] Right away, sir. It is done.r)   zsort itsayfinalr-   z%(py1)s == %(py4)spy1py4assert %(py6)spy6r,   not in)z%(py1)s not in %(py3)skinds)rY   r3   r4   r5   r   z[dry] Right away, sir.zLassert %(py7)s
{%(py7)s = %(py3)s
{%(py3)s = %(py1)s.startswith
}(%(py5)s)
})rY   r3   r5   py7c              3   $   K   | ]  }d |v  
 yw)rS   Nr   ).0r!   s     r   	<genexpr>zDtest_fastlane_normal_reply_streams_then_finalises.<locals>.<genexpr>G   s     04a}!4   ,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}anyr2   py2rZ   z%(py2)srh   finalsin)z%(py5)s in %(py8)s)r5   py8z%(py10)spy10zassert %(py13)spy13z8%(py2)s
{%(py2)s = %(py0)s.FAST_HANDOFF
} not in %(py5)sr6   r2   rh   r5   assert %(py7)sr`   )r6   r7   r   r"   r'   r9   r:   r;   r?   r@   rA   r<   r=   r>   
startswithrf   append_format_boolopr8   )rC   rD   r0   k_r_   psaysri   @py_assert0@py_assert3rE   @py_format5@py_format7rG   rH   @py_assert4@py_assert6@py_format8rF   @py_assert7@py_format3@py_format9@py_format11@py_format12@py_format14s                             r   1test_fastlane_normal_reply_streams_then_finalisesr   ;   s<    >>U45=)796 	7D #'((2y"9
:
:$4
:
:
:C
:341aQ3E,#$!QeA#,D,0CDAq1<aC0F09999!9E!!!!9E!!!9!!!!!!E!!!E!!!!!!!7777676777777777777677777777770400300000000030003000000000000000606m0vay0my00000006000600006000my000m000y00000000000000.VAY.Y....Y......5...5......Y.......sg   AT#A%A#A!
A#A%!A##A%$T#1A>=T#BBT#-C ;C ?Q$T#c                  ,  K   ddddd ddddd	d
gddddddddg} t        j                  t        g       d      }|j                  | d      }|D cg c]  }|d   	 }}g 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        }	t        |	      }|sddt        j                         v st	        j                  t              rt	        j                  t              ndt	        j                  |	      t	        j                  |      dz  }t        t	        j                  |            d x}	}y c c}w w)NuserrP   rolecontent	assistantc1functionxz{})name	arguments)idr    r   )r   r   
tool_callstoolresult)r   tool_call_idr   zAnswer, sir.r)   nextr   systemr   r   r   r-   rW   rX   r[   r\   c              3   B   K   | ]  }t        |d    t                yw)r   N)
isinstancestr)rb   r   s     r   rc   zEtest_fastlane_history_view_strips_tool_scaffolding.<locals>.<genexpr>Y   s     ;dz!I,,d   re   allrg   )r6   r7   r   build_messagesr:   r;   r?   r@   rA   r   r<   r=   r>   )
histrC   msgsr   ry   rz   rE   r{   r|   rF   s
             r   2test_fastlane_history_view_strips_tool_scaffoldingr   M   s=    D)#Z.1%EG H	I (C8D >>+b/:6DtV,D#$t!AfItO$(OO$(OOOOO$(OOOO$OOO(OOOOOOOO;d;;3;;;;;;;;;3;;;3;;;;;;;;;;;;;; %s   AFF D4Fc                       e Zd Zd Zd Zd Zy)FakeWSc                      g | _         g | _        y N)sentbinary)r   s    r   r   zFakeWS.__init__`   s    	r   c                 B   K   | j                   j                  |       y wr   )r   rs   )r   frames     r   	send_jsonzFakeWS.send_jsond   s     		r   c                 B   K   | j                   j                  |       y wr   )r   rs   )r   datas     r   
send_byteszFakeWS.send_bytesg   s     4 r   N)r   r   r   r   r   r   r   r   r   r   r   _   s     !r   r   c                     t        j                  t                     }d|_        ddd|_        ddd|_        t        | xs g       |_        t        j                  t        |xs g       d d       |_        |S )N)wschatr   zfull-sysr   r)   )
tool_specs	tool_exec)
mainSessionr   mode
system_msgfast_system_msgr   fast_adapterr6   Brain)fast_eventsfull_eventssesss      r   _sessionr   k   sj    <<68$DDI'J?DO$,DD#K$526D[):;(,>DJKr   c                 L    d }| j                  t        j                  d|       y )Nc                     K   y wr   r   )_a_ks     r   _noopz_no_passive.<locals>._noopw   s	     s   passive_remember)setattrr   r   )monkeypatchr   s     r   _no_passiver   v   s    

$6>r   c                 \  K   | j                  dd       t        |        t        t        d      t	               g      }|j                  ddi       d {    t        j                  d       d {    |j                  j                  D cg c]  }|d   	 }}g }d	}||v }|}|r|d
   }d}	||	k(  }
|
}|s+t        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|i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}x}
}	|j(                  D cg c]  }|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   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}|j(                  d!   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*                  }|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                  |      t        j                  |      d%z  }d&d'|iz  }t%        t        j&                  |            d x}x}x}x}}|j0                  }|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 G7 -c c}w c c}w w),N	FAST_CHAT1zEvening, sir.r   r   eveningr   r    sentencerV   turn_endrj   )z%(py3)s in %(py5)stypes)r3   r5   z%(py7)sr`   r-   )z%(py10)s == %(py13)s)rm   rn   z%(py15)spy15zassert %(py18)spy18r   r   r   rW   rX   r[   r\   r   r   z%(py1)s in %(py4)sze%(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.brain
}.adapter
}.calls
} == %(py9)sr   r2   rh   rZ   r\   py9assert %(py11)spy11zO%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.fast_adapter
}.calls
} == %(py7)sr2   rh   rZ   r`   assert %(py9)sr   )setenvr   r   r"   r'   	_run_turnasynciosleepr   r   r:   r;   r?   r<   r=   r>   rs   rt   r@   rA   historyr6   adapterr	   r   )r   r   fr   rF   rE   r}   ry   @py_assert9@py_assert12@py_assert11rH   r   r   @py_format16@py_format17@py_format19r   rz   r{   r|   @py_assert5@py_assert8r   @py_format10r   r~   s                              r   0test_router_fast_lane_serves_and_commits_historyr   |   s    {C(!7 CDD
..&),
---
--
 $-1QvYE-:::::59:
:9
#::::::::::::::::::::::::::9
:::9:::
::::::::::::::#||,|!AfI|E,0EE,0EEEEE,0EEEE,EEE0EEEEEEEE<<?9%22%2222%222%22222222228dll1oi88?88888?8888?88888888888::(:(##(q(#q((((#q((((((4(((4(((:((((((#(((q((((((('""'a'"a''''"a''''''4'''4''''''"'''a''''''' .- -sD   AV,VV,2V3V,V"E&V,V'NV,V,"
V,c                 (  K   | j                  dd       t        |        t        t        t        j
                        t               gt        d      t               g      }|j                  ddi       d {    t        j                  d       d {    |j                  j                  D cg c]  }|d   d	k(  s|j                  d       }}d
 |D        }t        |      }|sddt        j                         v st!        j"                  t              rt!        j$                  t              ndt!        j$                  |      t!        j$                  |      dz  }t'        t!        j(                  |            d 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                  }|j0                  }|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$                  |      t!        j$                  |      dz  }
dd|
iz  }t'        t!        j(                  |            d x}x}x}x}}|j2                  D cg c]  }|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}}t        j
                  }|j2                  d   d    }||v}|st!        j.                  d!|fd"||f      d#t        j                         v st!        j"                  t              rt!        j$                  t              nd#t!        j$                  |      t!        j$                  |      d$z  }d%d&|iz  }	t'        t!        j(                  |	            d x}x}}d'}|j2                  d   d    }||v }|slt!        j.                  d(|fd)||f      t!        j$                  |      t!        j$                  |      dz  }dd|iz  }t'        t!        j(                  |            d x}x}}y 7 7 c c}w c c}w w)*Nr   r   zYour meeting is at nine, sir.r   r   r   r*   r   r    r   c              3   $   K   | ]  }d |v  
 yw)nineNr   )rb   ts     r   rc   zKtest_router_escalates_on_sentinel_then_full_brain_serves.<locals>.<genexpr>   s     *Eqv{Erd   re   rf   rg   r   r-   r   r   r   r   r   r   r   r   r   r   r   r   rW   rX   r[   r\   r   r]   ro   r6   rp   rq   r`   r   rj   r   )r   r   r   r"   r6   r8   r'   r   r   r   r   r   getrf   r<   r=   r:   r>   r?   r@   rA   r   r	   r;   r   r   )r   r   r   textsrF   rz   r{   r~   r   r   r   r   r   r   r   ry   rE   r|   r}   rH   s                       r   8test_router_escalates_on_sentinel_then_full_brain_servesr      s    {C(5--.	::;WYGID ..&"67
888
--
$(GGLLLLqAfI4KQUU6]LEL*E**3*********3***3**************'""'a'"a''''"a''''''4'''4''''''"'''a'''''''::(:(##(q(#q((((#q((((((4(((4(((:((((((#(((q(((((((#||,|!AfI|E,0EE,0EEEEE,0EEEE,EEE0EEEEEEEE?T\\!_Y%??%?????%???????5???5??????%????????/T\\!_Y//6/////6////6/////////// 9L -sJ   A5V7V8VVV1V?VJ5VVG0VV
Vc                 h  K   | j                  dd       t        |        t        t        d      t	               gt        d      t	               g      }|j                  ddi       d {    t        j                  d       d {    |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$                  }|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                  |      t        j                  |      dz  }dd|iz  }
t!        t        j"                  |
            d x}x}x}x}	}|j(                  D cg c]  }|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}}d}|j(                  d   d   }||v }|slt        j                  d|fd||f      t        j                  |      t        j                  |      dz  }dd|iz  }t!        t        j"                  |            d x}x}}y 7 >7 $c c}w w)Nr   0zmust not be usedzFull brain here, sir.r   r   hellor   r-   r   r   r   r   r   r   r   r   r   r   r   r   r   rW   rX   r[   r\   z
Full brainr   rj   r   )r   r   r   r"   r'   r   r   r   r   r	   r:   r;   r<   r=   r>   r?   r@   rA   r6   r   r   )r   r   rF   rz   r~   r   r   r   r   r   r   r   ry   rE   r{   r|   s                   r   .test_router_fast_chat_disabled_skips_fast_laner      sp    {C(-.	:23WY?AD ..&'*
+++
--
'""'a'"a''''"a''''''4'''4''''''"'''a'''''''::(:(##(q(#q((((#q((((((4(((4(((:((((((#(((q(((((((#||,|!AfI|E,0EE,0EEEEE,0EEEE,EEE0EEEEEEEE54<<?955<55555<5555<55555555555 , -s8   A'N2)N'*N2N*HN2N-DN2*N2-N2c                 r  K   | j                  dd       t        |        t        t        d      t	               g      }|j                  ddi       d {    t        j                  d       d {    t        t        d      t	               g      |_	        |j                  dd	i       d {    t        j                  d       d {    |j                  j                  }|D cg c]  }|d
   	 }}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   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}}
y 7 7 7 |7 bc c}w w)Nr   r   zNoted, sir.r   r   zmy car is a Suprar   zA Supra, sir.zwhat did I sayr   r   r-   r/   rolesr1   r4   r5   r   r   rW   rX   r[   r\   )r   r   r   r"   r'   r   r   r   r   r   r
   r:   r;   r<   r=   r>   r?   r@   rA   )r   r   seenr   r   rE   rF   rG   rH   ry   rz   r{   r|   s                r   9test_router_second_turn_sees_first_turn_in_shared_historyr      s    {C(}!5wy ABD
..&"56
777
--
#U?%;WY$GHD
..&"23
444
--
**D $%1QvYE%;;5;;;;;5;;;;;;;5;;;5;;;;;;;;;;;794!44!44444!4444444!44444444 8 5%s[   AH7H&H72H)3=H70H,1H7H/H7,H28D/H7)H7,H7/H72H7c                   K   t        |        t               }|j                  ddi       d {    |j                  j                  d   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}}|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                   }|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                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}x}x}}y 7 [w)Nr   rO   rV   r    r   r-   rW   rX   r[   r\   )z/%(py2)s
{%(py2)s = %(py0)s.history
} == %(py5)sr   rp   rq   r`   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r:   r;   r?   r@   rA   r   r<   r=   r>   r   r	   r6   r   )r   r   ry   rz   rE   r{   r|   rF   r}   rH   r   r~   r   r   r   r   r   s                    r   *test_router_empty_utterance_just_ends_turnr      s'    :D
..&%
)))77<<F#1z1#z1111#z111#111z1111111<<2<2<244<2'""'a'"a''''"a''''''4'''4''''''"'''a'''''''::(:(##(q(#q((((#q((((((4(((4(((:((((((#(((q((((((((	 *s   ,NN	MN)NN)r   builtinsr<   _pytest.assertion.rewrite	assertionrewriter:   r   r6   r   
LLMAdapterr   r"   r'   rI   rM   rQ   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>r     s{   <    %"" "'0&&&/$<$	! 	!?($0(65")r   