+
    ~j                        ^ RI Ht ^ RIHt ^ RIt^ RIHt ^RIH	t	 ^RI
Ht ]'       d   ^RIHt ^RIHtHtHt  ! R	 R
4      t ! R R4      tR# )    )annotations)TYPE_CHECKINGN)llm)logger)	Debounced)AgentSession)AgentStateChangedEventUserInputTranscribedEventUserStateChangedEventc                      ] tR t^tRR/R R lltR R lt]R R l4       tR	 R
 ltR R lt	R R lt
R R ltR R ltR R ltR R ltRtR# )IVRActivitymax_silence_durationg      @c               $    V ^8  d   QhRRRRRR/# )   sessionr   r   floatreturnNone )formats   "z/Users/mitch_tango/dev/rabbit-r1-livekit/agent/.venv/lib/python3.14/site-packages/livekit/agents/voice/ivr/ivr_activity.py__annotate__IVRActivity.__annotate__   s(     = == $	=
 
=    c               	    Wn         W n        \        4       V n        R V n        R V n        \        V P                  V4      V n        R V n	        R # N)
_session_max_silence_durationTfidfLoopDetector_loop_detector_current_user_state_current_agent_stater   _on_silence_detected_debounced_silence_last_should_schedule_check)selfr   r   s   &&$r   __init__IVRActivity.__init__   sH      %9"/1/3 04!"+D,E,EG["\8<(r   c                   V ^8  d   QhRR/# r   r   r   r   )r   s   "r   r   r   !   s     T TT Tr   c                	   "   V P                   P                  R V P                  4       V P                   P                  RV P                  4       V P                   P                  RV P                  4       R# 5iuser_state_changedagent_state_changeduser_input_transcribedN)r   on_on_user_state_changed_on_agent_state_changed_on_user_input_transcribedr&   s   &r   startIVRActivity.start!   sV     -t/J/JK.0L0LM143R3RSs   A5A7c                   V ^8  d   QhRR/# )r   r   z,list[llm.FunctionTool | llm.RawFunctionTool]r   )r   s   "r   r   r   '   s     " "C "r   c                	    ^RI Hp V.# )   )send_dtmf_events)beta.tools.send_dtmfr:   )r&   r:   s   & r   toolsIVRActivity.tools&   s    < !!r   c                    V ^8  d   QhRRRR/# )r   evr
   r   r   r   )r   s   "r   r   r   ,   s     
( 
(-F 
(4 
(r   c                	T   VP                   '       g   R # V P                  P                  VP                  4       V P                  P	                  4       '       dO   \
        P                  ! R4       V P                  P                  RR7       V P                  P                  4        R # R # )Nz7IVRActivity: speech loop detected; sending notificationF)allow_interruptions)
is_finalr    	add_chunk
transcriptcheck_loop_detectionr   debugr   generate_replyresetr&   r?   s   &&r   r3   &IVRActivity._on_user_input_transcribed,   st    {{{%%bmm43355LLRSMM((U(C%%'	 6r   c                    V ^8  d   QhRRRR/# )r   r?   r   r   r   r   )r   s   "r   r   r   8   s     ' ')> '4 'r   c                	H    VP                   V n        V P                  4        R # r   )	new_stater!   _schedule_silence_checkrI   s   &&r   r1   "IVRActivity._on_user_state_changed8   s    #%<< $$&r   c                    V ^8  d   QhRRRR/# )r   r?   r	   r   r   r   )r   s   "r   r   r   <   s     ' '*@ 'T 'r   c                	H    VP                   V n        V P                  4        R # r   )rM   r"   rN   rI   s   &&r   r2   #IVRActivity._on_agent_state_changed<   s    $&LL!$$&r   c                   V ^8  d   QhRR/# r*   r   )r   s   "r   r   r   @   s     
; 
; 
;r   c                	    V P                  4       pV'       d0   V P                  '       d   R # V P                  P                  4        MV P                  P	                  4        Wn        R # r   )_should_schedule_checkr%   r$   schedulecancel)r&   should_schedules   & r   rN   #IVRActivity._schedule_silence_check@   sL    557///##,,.##**,+:(r   c                   V ^8  d   QhRR/# r   r   boolr   )r   s   "r   r   r   L   s     2 2 2r   c                	V    V P                   R9   pV P                  R9   pT;'       d    T# )	listening)r^   away)idler^   )r!   r"   )r&   is_user_silentis_agent_silents   &  r   rU   "IVRActivity._should_schedule_checkL   s2    115JJ337LL11/1r   c                   V ^8  d   QhRR/# r*   r   )r   s   "r   r   r   Q   s     ' 'D 'r   c                	n   "   \         P                  ! R 4       V P                  P                  4        R# 5i)z3IVRActivity: silence detected; sending notificationN)r   rF   r   rG   r4   s   &r   r#    IVRActivity._on_silence_detectedQ   s"     JK$$&s   35c                   V ^8  d   QhRR/# r*   r   )r   s   "r   r   r   U   s     U Ud Ur   c                	&  "   V P                   P                  4        V P                  P                  R V P                  4       V P                  P                  RV P
                  4       V P                  P                  RV P                  4       R# 5ir,   )r$   rW   r   offr1   r2   r3   r4   s   &r   acloseIVRActivity.acloseU   sh     &&(.0K0KL/1M1MN2D4S4STs   BB)r"   r!   r$   r%   r    r   r   N)__name__
__module____qualname____firstlineno__r'   r5   propertyr<   r3   r1   r2   rN   rU   r#   rj   __static_attributes__r   r   r   r   r      sU    = '*	=T
 " "

(''
;2
'U Ur   r   c                  N    ] tR t^\tRtRR R lltR R ltR R ltR R	 ltR
t	R# )r   a  TF-IDF based loop detector.

This detector uses TF-IDF to detect loops in the user's input by comparing
the similarity of the last N - 1 chunks of transcribed text to the last chunk.

Args:
    window_size: The number of chunks to compare. Default ``20``.
    similarity_threshold: The similarity threshold for a chunk to be considered similar to the last chunk. Default ``0.85``.
    consecutive_threshold: The number of consecutive chunks that must be similar to trigger a loop detection. Default ``3``.
c               (    V ^8  d   QhRRRRRRRR/# )r   window_sizeintsimilarity_thresholdr   consecutive_thresholdr   r   r   )r   s   "r   r   TfidfLoopDetector.__annotate__h   s2     1 11 $1  #	1
 
1r   c                	    V^ 8:  d   \        R4      hVR8  g   VR8  d   \        R4      hV^ 8:  d   \        R4      hWn        W n        W0n        . V n        ^ V n        R# )r   z"window_size must be greater than 0g        g      ?z0similarity_threshold must be between 0.0 and 1.0z,consecutive_threshold must be greater than 0N)
ValueError_window_size_similarity_threshold_consecutive_threshold_transcribed_chunks_num_consecutive_similar_chunks)r&   rt   rv   rw   s   &&&&r   r'   TfidfLoopDetector.__init__h   sj     !ABB#%)=)COPP A%KLL'%9"&;#.0 /0,r   c                   V ^8  d   QhRR/# r*   r   )r   s   "r   r   rx   }   s     1 1t 1r   c                	"    . V n         ^ V n        R# )r   N)r~   r   r4   s   &r   rH   TfidfLoopDetector.reset}   s    #% /0,r   c                    V ^8  d   QhRRRR/# )r   chunkstrr   r   r   )r   s   "r   r   rx      s     V Vs Vt Vr   c                	    V P                   P                  V4       \        V P                   4      V P                  8  d"   V P                   V P                  ) R  V n         R # R # r   )r~   appendlenr{   )r&   r   s   &&r   rC   TfidfLoopDetector.add_chunk   sS      ''.t''(4+<+<<'+'?'?ARAR@R@T'UD$ =r   c                   V ^8  d   QhRR/# r[   r   )r   s   "r   r   rx      s     S Sd Sr   c                	    ^ RI Hp ^ RIHp T! 4       p\        T P                  4      ^8  d   R# TP                  T P                  4      pT! T4      pTR,          RR pTP                  ^ 8  d@   \        P                  ! T4      T P                  8  d   T ;P                  ^,          un        M^ T n        T P                  T P                  8  #   \         d    \
        P                  ! R4        R# i ; i)r   )TfidfVectorizer)cosine_similarityzTfidfLoopDetector: sklearn is not installed; loop detection is disabled. Please install the 'scikit-learn' package to enable loop detection.FN)sklearn.feature_extraction.textr   sklearn.metrics.pairwiser   ImportErrorr   warningr   r~   fit_transformsizenpmaxr|   r   r}   )r&   r   r   
vectorizer
doc_matrixdoc_similaritylast_chunk_similaritys   &      r   rE   &TfidfLoopDetector.check_loop_detection   s    	GB %&
 t''(1,  --d.F.FG
*:6 .r 23B 7 "&&*,-0J0JJ00A5034D033t7R7RRR5  	NN _ 		s   C !C54C5)r}   r   r|   r~   r{   N)   g333333?r9   )
rl   rm   rn   ro   __doc__r'   rH   rC   rE   rq   r   r   r   r   r   \   s#    	1*1V
S Sr   r   )
__future__r   typingr   numpyr   livekit.agentsr   logr   utils.aio.debouncer   agent_sessionr   eventsr	   r
   r   r   r   r   r   r   <module>r      s@    "      +,aaHU HUVHS HSr   