
    Oj                    l    U d Z ddlmZ ddlZddlZdZdZdZdZ	ddZ
 G d	 d
      Zdaded<   daddZy)u  Semantic end-of-turn detection — Smart Turn v3 (pipecat-ai, BSD-2).

A fixed silence timeout is a bad proxy for "done talking": it cuts Ahmed off
mid-thought when he pauses to think, and wastes 400ms when he clearly
finished. Smart Turn listens to the ACTUAL speech (grammar, tone, pace — a
Whisper-Tiny encoder + classifier head, 8M params) and returns the
probability that the turn is complete. ~12ms per call on CPU.

main.py uses it like this: once a SHORT pause is detected, ask the model —
"did he finish the sentence?" If yes → respond immediately (snappier than
the old fixed wait). If no → keep listening through the pause, up to a hard
cap. SMART_TURN=0 disables (falls back to the fixed timeout).

Model: huggingface.co/pipecat-ai/smart-turn-v3 (auto-downloaded, ~30MB).
Preprocessing per the reference inference.py: last 8s of 16kHz audio,
front-padded, Whisper log-mel features, normalized.
    )annotationsNzpipecat-ai/smart-turn-v3zsmart-turn-v3.2-cpu.onnxi>     c                 H    t         j                  j                  dd      dk7  S )N
SMART_TURN10)osenvironget     8/Users/ahmed/devFolder/Ultron/claude-voice/voice/turn.pyenabledr      s    ::>>,,33r   c                      e Zd ZddZddZy)TurnDetectorc                r   dd l }ddlm} ddlm}  |t
        t              }|j                         }d|_        |j                  j                  |_        |j                  ||dg      | _         |t              | _        | j!                  t#        j$                  t&        t"        j(                               y )	Nr   )hf_hub_download)WhisperFeatureExtractor   CPUExecutionProvider)sess_options	providers)chunk_length)dtype)onnxruntimehuggingface_hubr   transformersr   _MODEL_REPO_MODEL_FILESessionOptionsinter_op_num_threadsGraphOptimizationLevelORT_ENABLE_ALLgraph_optimization_levelInferenceSession_session	_WINDOW_S_fxcompletion_probnpzeros_SAMPLE_RATEfloat32)selfortr   r   pathsos         r   __init__zTurnDetector.__init__$   s    !38{K8!"#&)&@&@&O&O#,,r.D-E - G*	BRXXl"**EFr   c           	        t         t        z  }t        |      |kD  r|| d }| j                  |t        dd|dd      j                  j                  d      j                  t        j                        d   }| j                  j                  dd|i      }t        t        j                  |d         j                  d	      d         S )
z@P(turn is complete) for 16kHz mono float32 audio (uses last 8s).Nr*   
max_lengthT)sampling_ratereturn_tensorspaddingr4   
truncationdo_normalizer   )N.input_features)r'   r,   lenr(   r:   squeezeastyper*   r-   r&   runfloatasarrayreshape)r.   audionfeatsouts        r   r)   zTurnDetector.completion_prob3   s    $u:>1"#JEd Q4  
 .FF2::$6y	B
 mm'7&?@RZZA'//3A677r   N)returnNone)rC   z
np.ndarrayrG   r@   )__name__
__module____qualname__r2   r)   r   r   r   r   r   #   s    G8r   r   TurnDetector | None	_detectorFc                     t               rt        ryt        	 t               at        S t        S # t        $ r } dat        d|  d       Y d} ~ t        S d} ~ ww xY w)zLazy singleton; None when disabled or unavailable (fixed timeout is
    the fallback, so a download/model failure can never break listening).NTz  smart-turn unavailable (u   ) — fixed-timeout turns)r   _failedrM   r   	Exceptionprint)es    r   get_detectorrS   F   sc     9	M$I 9  	MG.qc1JKLL	Ms   
/ 	AAA)rG   bool)rG   rL   )__doc__
__future__r   r	   numpyr*   r   r   r,   r'   r   r   rM   __annotations__rO   rS   r   r   r   <module>rY      sO   $ # 	 ((	48 8> "&	 %
r   