+
    bcjR                    Z
   R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt	^ RI
H
t
 ^ RIt^ RIt^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHtHtHtHtHtHtHtHtHtHt ^ RIH t H!t!H"t#  ^ RI$t$^ RI&H't'H(t( ^ RI)H*t*H+t+ ^ RI,H-t-H.t. ^ RI/t/]/P`                  ! ]/Pb                  Pd                  4        ^ R	I3H4t4 ]4! 4       t5]5'       d   ]6! R
]5 R24        ^ RI8t8 ^ RI:H;t;  ^ RI<H=t=H>t> ^ RI?t? ^ RI@HAtAH>tBHCtC Rt"]#t"R tD]D! 4        ]P                  ! RR4      tF]F'       g#   ]6! R4       ]6! R4       ]Pr                  ! ^4       ]F]?nG        ]P                  ! RR4      tH]I! ]P                  ! RR4      4      tJ]I! ]P                  ! RR4      4      tK]P                  ! RR 4      tLR!tMR"tNR#tOR$tPR%tQR&tRR'tSR(tTR)tU]P                  P                  ]P                  P                  ]P                  P                  ]Z4      4      R*4      t[R+t\R t]R+R,R-R.R/R0R1/R2R,R3R.R4R0R5//t^]_! 0 R|m4      t`]_! 0 R}m4      ta/ tbR6^ R7^R8^R9^R:^R;^R<^/tcR= td/ R>R?bR@RAbRBRCbRDREbRFRGbRHRIbRJRKbRLRMbRNRObRPRQbRRRSbRTRUbRVRWbRXRYbRZR[bR\R]bR^R_bte ^ RIftf]fP                  ! ]P                  P                  ]P                  P                  ]P                  P                  ]Z4      4      R`4      Ra7      th]hP                  RbRc7      tj]hP                  RdRc7      tk]jP                  4       tm]kP                  4       tn]6! Re]m Rf]n Rg24       Rk tpRl tq]p! 4       sr\        '       d   ]6! Rm]s! \        4       Rn24       ]t! 4       tuRo tv ! Rp Rq4      twRr txRs ty]P                  P                  ]P                  P                  ]Z4      4      tz]P                  P                  ]zRt4      t{]P                  ! ]{RRu7       Rv t}Rw t~]Rx8X  d_   ]6! R~4       ]6! Ry4       ]6! Rz4       ]6! R~4       ]EP                   ! ]}RR{7      EP                  4        ]EP                  ! ]~! 4       4       R# R#   ]% d    Rt$ ELi ; i  ]7 d     ELi ; i  ]7 d    ]6! R4       ]Pr                  ! ^4        ELi ; i  ]7 d    ]6! R4       ]Pr                  ! ^4        ELi ; i  ]7 d    ]6! R4       ]Pr                  ! ^4        ELi ; i  ]7 d    Rt"]6! R4        ELi ; i  ]7 d    ]6! Rh4       RtjRtk EL]% d   to]6! Ri]o Rj24       RtjRtk RtoAoELRtoAoii ; i)u"  
Qwen Pipeline Test — STT -> LLM -> TTS (3 separate models)
With call transfer demo: Agent A (receptionist) can transfer to Agent B.

  STT:  qwen3-asr-flash-realtime       (WebSocket, server VAD)
  LLM:  qwen3.5-flash                  (OpenAI-compatible REST, streaming + function calling)
  TTS:  qwen3-tts-flash-realtime       (DashScope SDK, PCM 24kHz)

Usage:
  pip install websockets openai dashscope>=1.23.9 chromadb
  set DASHSCOPE_API_KEY=sk-xxx
  python qwen_pipeline_server_v2.py
  Open http://localhost:5555/qwen_pipeline_test.html
N)datetime)
HTTPServer)
CUSTOM_HANDLERSexecute_tool_endpointhandle_transfer_callhandle_transfer_backhandle_end_callhandle_call_backhandle_select_languagehandle_change_languagehandle_switch_languagehandle_dial)TtsCallbackOmniCallbackOMNI_SDK_AVAILABLE)profile_to_configload_profile_config)dispatch_to_acrsdispatch_callback_to_acrs)PipelineHTTPHandlerinit_http_routes)load_generated_handlersz[Startup] Loaded z generated handler(s)zMissing: pip install websockets)OpenAIzMissing: pip install openai)QwenTtsRealtimeAudioFormatz&Missing: pip install dashscope>=1.23.9)MultiModalityr   OmniRealtimeConversationTFzKNOTE: dashscope.audio.qwen_omni not available. Omni Realtime mode disabled.c            	      f   \         P                  P                  \         P                  P                  \         P                  P	                  \
        4      4      R 4      \         P                  P                  \         P                  P                  \         P                  P	                  \
        4      4      RR 4      3 F  p \         P                  P                  V 4      '       g   K*  \        V 4      ;_uu_ 4       pV F  pVP                  4       pV'       g   K  VP                  R4      '       d   K6  RV9   g   K?  VP                  R4      w  r4p\         P                  P                  VP                  4       VP                  4       4       K  	  RRR4       K  	  R#   + '       g   i     K  ; i)z.envzasterisk-bridge#=N)ospathjoindirnameabspath__file__existsopenstrip
startswith	partitionenviron
setdefault)pflinek_vs         qwen_pipeline_server.pyload_envr4   [   s    
RWW__RWW__X%>?H
RWW__RWW__X%>?ARTZ[ 77>>!aAD::<DtDOOC$8$8SD["&.."5a

--aggiC	  
 s   ;FF4F=AFF0DASHSCOPE_API_KEY z"
ERROR: DASHSCOPE_API_KEY not set.z9Set via env var or .env file:
  DASHSCOPE_API_KEY=sk-xxx
GOOGLE_API_KEYPIPELINE_WS_PORT8767PIPELINE_HTTP_PORT5555ASR_ENDPOINT4wss://dashscope-intl.aliyuncs.com/api-ws/v1/realtimezqwen3-asr-flash-realtimez7https://generativelanguage.googleapis.com/v1beta/modelszgemini-2.5-flashz6https://dashscope-intl.aliyuncs.com/compatible-mode/v1zqwen3.5-flashz#qwen3-tts-flash-realtime-2025-11-27z qwen3-tts-vc-realtime-2026-01-15zqwen-voice-enrollmentzKhttps://dashscope-intl.aliyuncs.com/api/v1/services/audio/tts/customizationzcloned_voices.jsonzqwen3.5-omni-plus-realtime
input_textg @input_audiog     0@output_audiog      O@zqwen3.5-omni-flash-realtimeg?g      @g333331@montuewedthufrisatsunc                   V P                  R4      pV'       g   R#  ^ RIpVP                  VP                  RR4      4      p\        P                  ! V4      pVP                  R4      pV'       dS   VP                  R	4      P                  4       R
,          pY U	u. uF  qP                  4       R
,          NK  	  up	9  d   R# VP                  R4      p
VP                  R4      pV
'       d.   V'       d&   VP                  R4      pYu;8:  d
   V8  g    R#  R# R#   \         d    ^ RIHpHp T! T! ^R7      4      p Li ; iu up	i )zCheck if a tool is currently available based on its x_schedule field.
Returns True if no schedule is defined or if current time is within schedule.
x_scheduleTNtimezoneAsia/Kuala_LumpurrJ   	timedeltahoursdaysz%a:N   NFstartendz%H:%M)
getzoneinfoZoneInfo	Exceptionr   rJ   rM   nowstrftimelower)toolschedrU   tzrJ   rM   rX   allowed_daystodaydrR   rS   curs   &            r3   _is_tool_availablerb      s    HH\"E*uyy5HIJ ,,r
C99V$LT"((*2.=12==IIgE
))E
Cll7#"s" ##  *0ia()* >s   %D E"E EenEnglishzhChinesemsMalayjaJapanesekoKoreanid
IndonesianthThaivi
Vietnameseyue	CantoneseesSpanishfrFrenchdeGermanruRussianpt
PortugueseitItalianarArabichiHindi	chroma_db)r!   pipeline_profiles)nameconversation_logsu   [ChromaDB] Ready — z profiles, z conversationszJWARNING: chromadb not installed (pip install chromadb). Profiles disabled.zWARNING: ChromaDB init failed: z. Profiles disabled.c                  8   \         P                  P                  \        4      '       d;    \	        \        R 4      ;_uu_ 4       p \
        P                  ! V 4      uuRRR4       # . #   + '       g   i     . # ; i  \
        P                  \        3 d     . # i ; i)rN)	r    r!   r&   CLONED_VOICES_FILEr'   jsonloadJSONDecodeErrorIOError)r.   s    r3   _load_cloned_voicesr      sx    	ww~~())	(#..!yy| /. I	 /. I $$g. 	I	s/   A: A&
A: &A7	1A: 7A: :BBc                     \        \        R 4      ;_uu_ 4       p\        P                  ! W^R7       RRR4       R#   + '       g   i     R# ; i)w)indentN)r'   r   r   dump)voicesr.   s   & r3   _save_cloned_voicesr      s/    	 #	&	&!		&A& 
'	&	&	&s	   <A	z[VoiceClone] Loaded z cloned voice(s)c                     \        \        4      p RRRV /p\        \        4       F  p VP                  P	                  V4       K!  	  R#   \
         d     K3  i ; i)zsPush active session count to every connected dashboard.
Safe to call from the asyncio event loop (uses put_nowait).typedebug_statsactive_sessionsN)lenACTIVE_SESSIONSlistqueue
put_nowaitrW   )countmsgss      r3   broadcast_debug_statsr     sW      E="3U
;C/"	GGs# #  		s   A

AAc                     a  ] tR tRt o RtR t]R 4       t]R 4       t	]R`R l4       t
]R 4       tR tRaR
 ltR tR tR tR tR tR tR tR tR tR tR t]R 4       t]R 4       t]R 4       tR tR tR tR tR t R t!RbR lt"RbR  lt#R! t$R" t%R# t&R$ t'R% t(R& t)R' t*R( t+R) t,R* t-R+ t.R, t/R- t0R. t1R/ t2R0 t3R1 t4R2 t5R3 t6R4 t7R5 t8R6 t9R7 t:R8 t;R9 t<R: t=R; t>RcR< lt?RdR= lt@RaR> ltAR? tBR@ tCRA tDRB tERC tFRD tGRaRE ltHRF tIRG tJRH tKRI tLRJ tMRK tNRL tORM tPRN tQRO tRRP tS]RQ 4       tTRR tURS tVRT tWRU tXRV tYRW tZRX t[RY t\RaRZ lt]RaR[ lt^RcR\ lt_RaR] lt`RcR^ ltaR_tbV tcR	# )ePipelineSessioni  z
State machine:  LISTENING -> THINKING -> SPEAKING -> LISTENING
Supports two agents: Agent A (receptionist) can transfer to Agent B.
c                ,   Wn         W n        \        P                  ! 4       V n        VP                  R 4      '       d/   VP                  R4      '       d   VP                  R4      V n        MVP                  RRRRRRR/4      V n        VP                  R4      pV'       d.   \        V\        4      '       d   \        V4      ^ 8  d   W@n
        M)V P                   Uu. uF  qUR8w  g   K  VNK  	  upV n
        VP                  R	R
4      V n        VP                  RR
4      V n        VP                  R^24      V n        \        VP                  R R4      4      V n        V P                  '       d   \         '       g   \#        R4       RV n        VP                  RR4      ;'       g    \$        V n        VP                  RR4      ;'       g    RV n        VP                  RR4      ;'       g    RV n        VP                  RR4      ;'       g    RV n        VP                  RR4      V n        RV n        RV n        RV n        ^ V n        RV n        RV n        ^ V n        RV n        ^ V n         RV n!        RV n"        RV n#        RV n$        RV n%        RV n&        RV n'        . V n(        RV n)        RV n*        . V n+        ^ V n,        RV n-        RV n.        VP                  RR4      V n/        \        P`                  ! 4       V n1        R^ R^ R^ R^ R^ /V n2        VP                  R 4      ;'       g    R!Pg                  4       V n4        VP                  R"4      ;'       g    \j        V n6        VP                  R#4      ;'       g    RV n7        VP                  R$R%4      V n8        VP                  R&R'4      V n9        VP                  R(R4      V n:        VP                  R)^
4      V n;        \y        4       V n=        RV n>        RV n?        RV n@        VP                  R*R4      ;'       g    \        V nB        VP                  R+R4      V nC        VP                  R,R4      V nD        VP                  R-R4      ;'       g    ^V nE        VP                  R.R4      V nF        VP                  R/4      ;'       g    R0Pg                  4       pVR9   d   TMR0V nG        VP                  R14      ;'       g    R2Pg                  4       pVR9   d   TMR2V nH        VP                  R3R4      V nI        VP                  R4. 4      V nJ        V P                  '       g;   V P                  '       d)   V P                  V P                  4      w  V nJ        V nI        / V nL        V P                  '       d   V P                  P                  R54       F  pVP                  R64      '       d7   VP                  R7^4      ^,          P                  4       V P                  R8&   KP  VP                  R94      '       g   Ki  VP                  R7^4      ^,          P                  4       V P                  R:&   K  	   ^ RIPp	V	P                  R;4      p
\        P                  ! V
4      pV P                  P                  R:VP                  R>4      4       VP                  R?4      V P                  R@&   V P                  V P                  RA&   VP                  RB/ 4      p\        V\        4      '       d   VP                  RC4      MRp\        V\        4      '       d   VP                  RD4      MRpVP                  R4. 4      pV'       d   \        V\        4      '       d   . pV F  p\        V\        4      '       g   K  T;'       g     VP                  4        Uu. uF  qUNK  	  uppV Uu. uF.  pVP                  V4      '       g   K  \        VV,          4      NK0  	  ppVP                  REP                  V4      4       K  	  V'       d   R5P                  V4      MRV P                  RC&   MRV P                  RC&   \#        RF\        V\        4      '       d   \        V4      M^  RG24       \        V\        4      '       d   V F  p\#        RHV 24       K  	  \#        RIV P                  RC,          ;'       g    RJ 24       VP                  RK. 4      pV'       d   \        V\        4      '       d   \        V4      ^ 8  d   . pV F  p\        V\        4      '       g   K  T;'       g     VP                  4        Uu. uF  qUNK  	  uppV Uu. uF*  pVP                  V4      '       g   K  V RLVV,           2NK,  	  ppV'       g   K  VP                  RMP                  V4      4       K  	  V'       d   R5P                  V4      MRV P                  RD&   MRV P                  RD&   VP                  RN4      ;'       g    .  F  pVP                  ROR4      pVP                  RPR4      P                  4       P                  4       pVP                  RQR4      pV'       g   K_  V'       g   Ki  VP                  VR4      pV'       d   \        V4      MTV P                  V&   K  	  \        VP                  RR. 4      4      V n`        VP                  RS. 4      V na        V P                  VP                  RTR4      4      V nc        V P                  V P                  R4      V ne        VP                  RUR4      V nf        VP                  RVRW4      V ng        RV nh        RV ni        RV nj        VP                  RXRY4      V nk        VP                  RZ. 4      pV'       g@   VP                  R[R4      '       d(   R\VP                  R]R^4      R_VP                  R`Ra4      /.pRbR\VP                  RcRd4      R_RRe. //V nl        Rfp\        VRg,          ^Rh7       EFb  w  p p!RiV  2p"VP                  R 4      '       d*   V!P                  R4      '       d   V!P                  R4      p#MV!P                  R4      ;'       g    Rp#R\V!P                  R\RjV  24      RkV P                  V!P                  R_V4      4      Re. RT#R	V!P                  R	4      RV!P                  R4      RV!P                  R4      R3V!P                  R3R4      RSV!P                  RS4      ;'       g    RRl\        V!P                  RlR4      4      RmV!P                  Rm4      ;'       g    RP                  4       Pg                  4       /V P                  V"&   EKe  	  \        V P                  4      ^8  V nn        V P                  Rb,          P                  R\Rd4      p$ ^ RIPp	V	P                  R;4      p%\        P                  ! V%4      p&V&P                  R>4      p'V&P                  R?4      p(V P                  P                  4        FT  w  p"p)V"Rb8X  d   K  RnV' RoV( 2p*V)P                  R34      '       d   V*RpV)R3,           Rq2,          p*V*RrV$ Rs2,          p*V*V)Rt&   KV  	  Rup+V P                  VP                  R_V+4      4      V P                  Rb,          Rk&   Rp,V P                  '       d   V,RpV P                   Rq2,          p,V P                  '       dd   V P                  P                  4        U"U-u. uF  w  p"p-V"Rb8w  g   K  V-R\,          NK  	  p.p"p-R5P                  Rv V. 4       4      p/V,RwV/ Rx2,          p,V P                  '       d
   V,Ry,          p,V,V P                  Rb,          Rt&   \        VP                  RzR4      4      V np        VP                  R{4      ;'       g    RP                  4       V nq        VP                  R|4      ;'       g    RP                  4       V nr        V P                  VP                  R}R4      4      V ns        V P                  V P                  R4      V nt        RV nu        \        V P                  4      p0V P                  '       dw   V0'       do   RMP                  R~ V0 4       4      p1RV1 R2p2R\RR_V P                  ;'       g    T2Re. /V P                  R&   V P                  Rb,          Rt;;,          R,          uu&   MRV np        V P                  '       d   RV P                  9   d   RMRbV nv        RV nw        RV nx        RV ny        RV nz        RV n{        \        P                  ! 4       P                  R4      V n|        . V n}        . V n~        \y        4       V n        ^ V n        ^ V n        VP                  RR4      V n        VP                  RR4      ;'       g    RV n        RV n        \        V EP                  4      Pg                  4       R9  dv    ^ RIp3V3EP                  \        V EP                  4      Pg                  4       R7      V n        \#        RV EP                   RV EP                  EP                  4        24       VP                  R/ 4      p4RV n        V4P                  RR4      V n        V4P                  RR4      V n        V4P                  RR4      V n        V4P                  RR4      V n        V4P                  R. 4      V n        V4P                  R. 4      V n        V4P                  R. 4      V n        V4P                  R. 4      V n        V4P                  R/ 4      V n        V4P                  R/ 4      p5V5P                  R4      V n        V5P                  R4      V n        V5P                  R4      V n        VP                  R/ 4      p6V6P                  RR4      V n        V6P                  RR4      V n        V6P                  RR4      V n        VP                  R/ 4      p7\        V7\        4      '       g   R\        V74      /p7V7P                  RR4      V n        V7P                  R/ 4      p8\        V8\        4      '       g   R\        V84      /p8V8P                  RR4      V n        V8P                  RR4      V n        V8P                  R4      ;'       g    RV n        RV n        . V n        VP                  R/ 4      p9V9P                  RR4      V n        V9P                  RR4      V n        RV n        RV n        RV n        RV n        E\G        E\H        E\J        R7      V n        R# u upi   \         d    ^ R<ISHTpHUp T! T! ^R=7      4      p
 EL(i ; iu upi u upi u upi u upi   \         d    ^ R<ISHTpHUp T! T! ^R=7      4      p% ELi ; iu up-p"i   \         d"   p\#        RT R24       RT n         Rp?ELRp?ii ; i)enable_omniomni_voice_map	voice_maprc   Ethanre   Cherrydefaultallowed_languagesspeech_rate      ?
pitch_rate
tts_volumeFz<[WARN] Omni SDK not available, falling back to pipeline mode
omni_modelr6   
omni_voiceTinaomni_speech_styleomni_barge_in_rmsQ?omni_smooth_barge_inTNomni_audio_buffer_delay333333?input_text_tokensinput_audio_tokensoutput_text_tokensoutput_audio_tokensturnsstt_providerqwengemini_modelgemini_lang_hintvad_thresholdg?silence_duration_msi   idle_timeout_enabledidle_timeout_s	llm_modelenable_thinkingtemperature
max_tokenstop_ptts_mode	streamingtool_routingfull
agent_data
extensions
zCALLER PHONE::CALLERPHONEzCURRENT TIME:CURRENTTIMErK   rL   rN   z%A %H:%Mz%Y-%m-%dCURRENTDATE	AGENTDATAplaceholder_fields
EXTENSIONSOUTGOING | z$[DEBUG EXTENSIONS] raw from bridge (z
 entries):z  z6[DEBUG EXTENSIONS] rendered [EXTENSIONS] placeholder:
z(empty)Outgoing: , variable_mappings	configKeyplaceholderfallbackdisabled_builtin_toolscustom_toolsfixed_greetingbarge_in_enabledbarge_in_min_duration_ms,  transfer_delayg      @transfer_agentsagent_b_enabledr   agent_b_namezSales Departmentinstructionsagent_b_instructionszYou are a sales representative. Help the caller with product information, pricing, and purchases. Be friendly and professional. Keep responses brief (2-3 sentences). This is a live phone call.aagent_a_nameReceptionisthistoryzYYou are a helpful agent. Keep responses brief (2-3 sentences). This is a live phone call.:N
   N)rR   tzDepartment instructions_raw_maphiddenkeywordz

CURRENT TIME: z
CURRENT DATE: z

REFERENCE DATA:
Below is reference information you should use when answering questions. Use this data to provide accurate answers.
---
z
---u  

TRANSFER BACK:
When the caller asks to be transferred back, go back, or speak to someone else, you MUST call the transfer_back function. Do NOT just say you will transfer them — you must actually invoke the transfer_back tool in the same response. Never announce a transfer without calling the function.
Use transfer_back if the caller wants to go back, asks for a different department, asks to speak to a specific person, or when you have finished helping them.
When transferring back because the caller wants a person or another department, say something like "I don't have access to transfer calls directly, let me pass you back to z."instructions_decorationszYou are a professional AI receptionist. Greet callers warmly and understand their needs. Keep responses brief (2-3 sentences). This is a live phone call.c              3   .   "   T F  pR V R2x  K  	  R# 5i)z  - ""N ).0r   s   & r3   	<genexpr>+PipelineSession.__init__.<locals>.<genexpr>T  s     $NuTF!_s   z

TRANSFER CAPABILITY:
You can transfer callers to the following departments using the transfer_call function with the department parameter:
z
If the caller asks to speak with any of these departments, use the transfer_call function with the matching department name. Before transferring, briefly confirm with the caller.u  

EXTENSION DIRECTORY:
A company directory is available via the search_extension tool. When the caller asks for a specific person, call search_extension with their name. When the caller asks for a department, call search_extension with the department name. NEVER guess extension numbers or statuses — always search first. After getting results, confirm with the caller before dialing. If searching by department, look for the entry marked LEADER and offer to connect to that person.enable_language_agentlanguage_agent_greetinglanguage_agent_instructionsagent_a_returned_greetingc              3   X   "   T F   p\         P                  W4       R V R2x  K"  	  R# 5i) ()N
LANG_NAMESrT   r   cs   & r3   r   r   {  s*      &9DA:>>!'(1#Q/s   (*ziYou are a language selection agent for a phone call. The caller can choose from the following languages: aE  . Listen to the caller and determine which language they want to use. As soon as their choice is clear, call the select_language function with the matching language code. If their answer is unclear, ask them once more to pick one of the available languages. Keep every reply to 1-2 short sentences. This is a live phone call.zLanguage Selectorlangz

LANGUAGE CHANGE:
If the caller asks to change the language, switch languages, or speak in a different language, call the change_language function. This will route them back to the language selection agent.IDLE%Y-%m-%d %H:%M:%S_profile_namenoise_suppressionoff)enginez[NoiseSuppress] engine=z	, active=z[NoiseSuppress] init failed (z); pass-through.acrsenabledapi_urlapi_key
sp_accountdepartmentstypessubcategoriesratingscustom_fieldscallback_defaultsdepartment_idtype_id	rating_idconversation_validatorfaithfulness_checkjudgemodelzqwen3.7-pluscriteriaemotion
engine_urlws://localhost:8769)r  base_url)r   batch)r   two-tier	meta-tool)r  r6   nonefalse)wsloopasyncioQueuer   rT   r   
isinstancer   r   supported_languagesr   r   r   bool	omni_moder   print
OMNI_MODELr   r   r   r   r   
_omni_conv_omni_responding_omni_barge_in_omni_audio_gen_omni_suppress_flush_omni_barge_in_speech_start_idle_prompt_count_last_activity_time_omni_response_audio_bytes_omni_response_start_time_omni_response_text_omni_user_transcript_omni_tool_name_omni_tool_args_omni_tool_call_id_omni_tool_call_audio_mute_omni_muted_audio_buffer_omni_swallow_next_response_omni_swallowing_omni_pre_emit_buffer_omni_pre_emit_gen_omni_pre_emit_timer_omni_pre_emit_buffering_omni_audio_buffer_delayEvent_omni_response_done_event_omni_usage_totalsrZ   r   GEMINI_ASR_MODELr   r   r   r   r   r   	bytearray_gemini_speech_buffer_gemini_is_speaking_gemini_silence_start_gemini_transcribing	LLM_MODELr   r   r   r   r   r   r   r   extensions_directory_parse_legacy_extensions_variable_mapsplitr)   r(   rU   rV   rW   r   rJ   rM   rX   r,   rY   dictkeysstrappendr"   uppersetr   r   _norm_lang_mapfixed_greeting_map
_pick_langr   r   r   _speech_end_time_barge_in_pending_current_tts_callbackr   agents	enumeratetransfer_agents_enableditemslanguage_agent_enabledr  "language_agent_instructions_customagent_a_returned_greeting_mapr  _main_agent_visitedactive_agentstateasr_wsactivesession_language_pipeline_task
session_idconversation_log
prompt_logaudio_buffer_rec_caller_samples_rec_ai_cursorsession_profiler  _noise_suppressorNoiseSuppressor	is_activeacrs_dispatchedacrs_enabledacrs_api_urlacrs_api_keyacrs_sp_accountacrs_departments
acrs_typesacrs_subcategoriesacrs_ratingsacrs_custom_fieldsacrs_callback_dept_idacrs_callback_type_idacrs_callback_rating_id
cv_enabled
cv_api_url
cv_api_keyfaithfulness_enabledfaithfulness_judge_enabledfaithfulness_judge_modelfaithfulness_judge_criteria_faithfulness_result_tool_eventsemotion_enabledemotion_engine_url_emotion_ws_emotion_state_emotion_prev_primary_emotion_taskr   API_KEYLLM_BASEllm):self
browser_wsr/  configallowedr0   r   r   _linerU   _myt_tzrJ   rM   _now_var_pf_ext_fields_out_fields_exts
_ext_lines_e_keys_parts	_outgoing
_out_lines_o_mapping_ck_ph_fb_valtransfer_agents_config_default_ta_instritakey	_agent_vm	main_name_myt_now_myt_current_time_str_current_date_stragentdeco_default_agent_a_instragent_a_decor   target_namestargets_list_lang_codes_lang_displaydefault_lang_instructions_ns_modr  cb_defaultscv_fa_judgeemotion_cfgs:   &&&&                                                      r3   __init__PipelineSession.__init__  s   	]]_
 ::m$$4D)E)E#ZZ(89DN#ZZdGT8U^`g5hiDN**01z'400S\A5E'.$37>>'T>a)^>'TD$ "::mS9 **\37 **\26 fjj>?>>>"4"4PQ"DN **\26DD* **\26@@&!',?!D!J!J!',?!F!N!N$ %+JJ/Et$L! %# $)!+/("##' *+')-&#% %'"!!"$*/'(*%
 ,1( %%'""#$(!(-%(.

3Lc(R%)0& ! !!1Q#
 $ZZ7AA6HHJ"JJ~6JJ:J &

+= > D D"#ZZ=#)::.CS#I $*JJ/Eu$M!$jj)92>%.["#( %)"$)!  K4AA	%zz*;UC!::mT: **\48??CZZ.

 JJz*99k@@B$,0F$FK
 

>2<<fCCE,8 =- --L28 	 !**\26 %+JJ|R$@!(((T___9=9V9V:!6D%t  ???..t4##O448=C8KA8N8T8T8VD&&}5%%o668=C8KA8N8T8T8VD&&}5	 5
	3''(;<G <<(%%mX5F5Fz5RS,4,=,=j,I=)*.//;'jj-r2/9#t/D/Dcggl+$-7T-B-Bcggj) 

<,Zt,,Jb$'''AArwwy+Ay!Ay+AE27E%Q266!9jc"Q%j%FE%%ejj&89	 
 IStyy/DXZD|,/1D|,4:eUYCZCZSZ`a4bblmneT""2$i  G##L1>>Y?A 	B JJz2.	It44Y!9KJb$'''AArwwy+Ay!Ay+AE7<Ju!q	o2beWouFJv"))$))F*;<   GQTYYz-BVXDz*-/Dz*$78>>B>H,,{B/C,,}b1779??AC,,z2.Cssszz#r*7;#d)""3' ? '*&**5Mr*R&S# #JJ~r: #'"5"5fjjAQSU6V"W"ood.E.EtL !'

+=u E(.

3Ms(S% $ "'%)" %jj)93? "(,=r!B &&**5F*N*N

>3EF

+AW!X' &" 

>>B2
) 	 5c:!DDEAraS'Czz-((RVV4D-E-EFF#34	FF;/774	vQC'89&(;(;FF>+<=)?2Yrvvm4bff\2bff\2bff\26~ 6 > >$$rvvh67BFF9-33::<BBD DKK E. (+4;;'7!';$ KK$((@		0$$%89D <<%$--j9$--j9++++-JCcz'(9'::JK\J]^Dyy&& \*+ ,	 
+ ,5+R
9D 15E,-5 .<O 	 483F3FJJ~'=>4@C/0
 ??? ??# $	L '''48KK4E4E4GV4G&#q3RU:IAfII4GLV99$N$NNLJ  . !HIL $$$tL 8DC34 '+6::6Mu+U&V#(.

3L(M(S(SQS'Z'Z'\$JJ45;;UUW 	/
 .2-@-@JJ2B7.9*)-..*6&#(  4334&&&; II &9D& MGGTo V-- & +!H!H "> ">$=2	#DKK KK78M8 +0D' (,'B'B'BvQUQ\Q\G\Fcf 
 $" #,,.112EF "%K $% %zz/2>
 #)**-@%"H"Q"QE!%t%%&,,.6RR.3)0)@)@t556<<> *A *@&/0F0F/G H  $ 6 6 @ @ BCE F zz&"%$ HHY6 HHY3 HHY3#xxb9 $ ;((7B/"&((?B"? HHY3"&((?B"?hh2B7%0___%E"%0__Y%?"'2{'C$ ZZ0"5&&E2&&B/&&B/ jj-r2#t$$d3i(C$'GGIt$<! "%&$''f.F*0**Y*E'(.

7N(K%+1::j+A+I+IT($(!  jjB/*y%@"-//,@U"V"%)"! 'H=e (U`  	34yq12G	3$ ,BE$ ,BJB  	04IA./D	0p WR  .5bT9IJK)-&&.s   AU!*AU!AU& *
AV;AVAV
AVAV=AVAV# AW"AWHA4AW U&"AVVAVV#"AW	WAW	WAW>WAW9W9AW>c                <    V P                   V P                  ,          # N)rj  rr  r  s   &r3   _agentPipelineSession._agent  s    {{4,,--    c                    \        V \        4      '       d4   V P                  4        UUu/ uF  w  rYe   \        V4      MRbK  	  upp# V f   / # \        V 4      pV'       d   RV/# / # u uppi )zqNormalize a value into a {lang_code: str} dict.
Accepts a string (becomes {'en': string}), a dict, or None/empty.r6   rc   )r2  r^  rm  r`  )valr0   r2   r   s   &   r3   rd  PipelineSession._norm_lang_map  se     c4  EHYY[Q[TQA-AR7[QQ;IHay%2%	 Rs   A)c                   V '       g   R# V P                  V4      pV'       d+   \        V4      P                  4       '       d   \        V4      # V'       dJ   W!8w  dD   V P                  V4      pV'       d+   \        V4      P                  4       '       d   \        V4      # V P                  4        F9  pV'       g   K  \        V4      P                  4       '       g   K.  \        V4      u # 	  R# )z~Pick text for ``lang`` from a lang-map, falling back to English,
then the first non-empty value. Returns '' if nothing usable.r6   )rT   r`  r(   values)lang_mapr  r   r2   s   &&& r3   rf  PipelineSession._pick_lang  s     LLQq6M(X&ASV\\^^1v"AqSV\\^^1v # r  c                   ^ RI p. p/ pVP                  ! RV 4      pV'       d   VP                  ^4      P                  4       P	                  R4       F  pVP
                  ! RVP                  4       4      pV'       g   K.  RVP                  ^4      P                  4       RVP                  ^4      P                  4       P                  RR4      /W6P                  ^4      &   K  	  VP                  ! R	V 4      pV'       Ed   VP                  ^4      P                  4       P	                  R4       EF  pVP                  4       pVP                  R
4      '       g   K-  VR,          P                  4       pVP
                  ! RV4      pV'       g   Ka  VP                  ^4      P                  4       pVP                  ^4      P                  4       p	VP                  ^4      ;'       g    Rp
RVRV	/pVP                  ! RV
4      pV'       d`   VP                  ^4      VR&   VP                  VR,          / 4      pV'       d+   VP                  RR4      VR&   VP                  RR4      VR&   VP                  ! RWP                  4      pV'       d&   VP                  ^4      P                  4       R8H  VR&   VP                  V4       EK  	  V'       g   . V 3# T pVP                  ! RRV4      pVP                  ! RRV4      pVP                  ! RRV4      pVP                  ! RRV4      P                  4       p\        R\        V4       R24       W/3# )zParse extension directory from legacy agent_data text format.

Returns (extensions_list, cleaned_agent_data) where extensions_list is
a list of dicts and cleaned_agent_data has the directory/status sections
stripped out.
Nz)EXTENSION STATUS[^:]*:\s*\n((?:- .+\n?)*)r   zC-\s*ext\s+(\d+):\s*\[(\w[\w\s]*)\]\s*hours?\s*([\d:]+\s*-\s*[\d:]+)statusrO    r6   z0EXTENSIONS?\s+DIRECTORY[^:]*:\s*\n((?:- .+\n?)*)-:   NNz!(.+?)\s*\((.+)\)(?:\s*:\s*(.*))?$r   
departmentzext\s+(\d+)extzautoAnswer\s*=\s*(yes|no)yes
autoAnswerz1EXTENSIONS?\s+DIRECTORY[^:]*:\s*\n(?:- .+\n?)*\n?z*EXTENSION STATUS[^:]*:\s*\n(?:- .+\n?)*\n?z#STATUS KEY:\s*\n(?:\[.+\].+\n?)*\n?z\n{3,}

z[Extensions] Parsed z entries from legacy agent_data)researchgroupr(   r]  matchreplacer)   rT   IrZ   ra  subr6  r   )r   r  r   statusesstatus_matchr/   m	dir_matchr   deptextrasentryext_mstaa_mcleaneds   &               r3   r[  (PipelineSession._parse_legacy_extensions  s    	
 yy8*F$**1-335;;DAHHZJJL" 1 !''!*"2"2"4!1!1!3!;!;C!D,HWWQZ( B II?M	9!*00288>zz|s++Bx~~'HH8$@wwqz'')wwqz'')))r|T:		.&9#(;;q>E%L!eElB7B*,&&2*>h)+)<gyy!=vttL*.**Q-*=*=*?5*HE,'!!%(7 ?: z>! &&@"gO &&92wH &&2BA &&FG4::<$S_$55TUV""r  c                    V'       d   RV9  d   V# V P                   P                  4        F  w  r#VP                  RV R2V4      pK  	  V# )z<Replace [VARNAME] placeholders with session variable values.[])r\  rm  r  )r  textr  r  s   &&  r3   _replace_variables"PipelineSession._replace_variablesi  sH    s$K**002HC<<!C5
C0D 3r  Nc                   Vf   V P                   pV P                  P                  V/ 4      pVR8X  d"   V P                  VP                  RR4      4      # VP                  R4      pVf"   V P                  VP                  RR4      4      # V P                  ;'       g    RpV P                  W44      pVP                  RR4      pV P                  WV,           4      # )zReturn the decorated system prompt for the given agent, resolved
against ``self.session_language`` (fallback: English, then first
non-empty). Applies per-agent decorations uniformly across languages.r  r   r6   r   rc   r   )rr  rj  rT   r  rv  rf  )r  	agent_keyr  raw_mapr  baser  s   &&     r3   _get_agent_instructions'PipelineSession._get_agent_instructionsq  s     ))I	2.**599^R+HII))23?**599^R+HII$$,,w-yy3R8&&t{33r  c                $   V P                   P                  4        UUu. uF9  w  rVR8w  g   K  VR8w  g   K  VP                  R4      '       d   K0  VR,          NK;  	  pppV'       g   R# RRRRRR	R
RRRRRRRR	RRV/RRRR	R//RRR.///# u uppi )zPBuild transfer_call tool definition with department enum from configured agents.r   r  r   r   Nr   functiontransfer_calldescriptionzTransfer the current call to another department or agent. Use this when the caller explicitly asks to be connected to another person or department. Your spoken text MUST be in the same language the caller is speaking.
parametersobject
propertiesr  stringz&The department or agent to transfer toenumreasonzBrief reason for the transferrequired)rj  rm  rT   )r  r  r   agent_namess   &   r3   _build_transfer_tool$PipelineSession._build_transfer_tool  s    /3{{/@/@/B P/BVS* !), !?@uuX !qyy/B PJ\
 H $"H)+S"K'
 !"H)+J#
# x 8
 	
	Ps   BBBBc                p    V P                   R,          R,          pRRRRRRRV R2R	RR
RRRRRR//RR.///# )zIBuild transfer_back tool for non-A agents to return caller to main agent.r   r   r   r  transfer_backr  zTransfer the caller back to z (the main receptionist). Use this when the caller wants to go back, asks for a different department, or when you have finished helping them and they need further assistance. Your spoken text MUST be in the same language the caller is speaking.r  r  r  r  r  z"Brief reason for transferring backr  )rj  )r  r  s   & r3   _build_transfer_back_tool)PipelineSession._build_transfer_back_tool  sz    KK$V,	J29+ >\ ]
 H  "H)+O## 
	
 	
r  c                N    RRRRRRRRRRR	R
RRRR/RRRRR/RRRRR//R. RO///# )zNBuild call_back tool for transfer agents to request a callback for the caller.r   r  r   	call_backr  aU  Request a callback for the caller. Use when the caller asks about pricing, quotations, or anything that requires a human follow-up. IMPORTANT: You MUST first ask for and receive the caller's name and phone number in separate conversation turns BEFORE calling this function. NEVER call with placeholder values like 'Please provide your name'.r  r  r  customer_namer  zThe caller's namecustomer_phonezThe caller's phone numberr  z%Brief reason for the callback requestr  )r  r  r  r   r  s   &r3   _build_call_back_tool%PipelineSession._build_call_back_tool  s     J2 H '"H)+>* )"H)+F+ !"H)+R##  M!
 	
r  c                4    RRRRRRRRRRR	R
RRRR//RR
.///# )z.Build end_call tool for ending the phone call.r   r  r   end_callr  zEnd the phone call. Call this when the caller says goodbye or indicates they are done. IMPORTANT: You must say a brief goodbye to the caller BEFORE calling this function.r  r  r  r  r  z Brief reason for ending the callr  r   r  s   &r3   _build_end_call_tool$PipelineSession._build_end_call_tool  s\     J
J H  "H)+M## 
	
 	
r  c                v    \        V P                  4      pV'       g   R# RRRRRRRRRR	R
RRRRRRV//RR.///# )zNBuild select_language tool for the Language Agent. Enum = supported languages.Nr   r  r   select_languager  zRecord the caller's chosen language for the rest of the conversation. Call this as soon as the caller clearly indicates their language preference.r  r  r  languager  z"Language code chosen by the callerr  r  )r   r3  )r  
lang_codess   & r3   _build_select_language_tool+PipelineSession._build_select_language_tool  sv    $223
J)c H ""H)+O"J%# 

 	
r  c                4    RRRRRRRRRRR	R
RRRR//RR
.///# )zMBuild change_language tool for Agent A (hands caller back to Language Agent).r   r  r   change_languager  zTransfer the caller back to the language selection agent so they can change the conversation language. Use this when the caller asks to switch language or speak in a different language.r  r  r  r  r  z5Brief reason (e.g., caller requested language change)r  r   r  s   &r3   _build_change_language_tool+PipelineSession._build_change_language_tool  s]     J)A H  "H)+b## 
	
 	
r  c                ,   \        V P                  4      p\        V4      ^8  d   R# . pV F.  p\        P	                  W34      pVP                  V RV 24       K0  	  RRRRRRRR	P                  V4      ,           R
,           RRRRRRRRRRV//RR.///# )zOBuild switch_language tool for Agent A (changes language without agent switch).Nz = r   r  r   switch_languager  zhSwitch the conversation language. Use when the caller asks to speak in a different language. Available: r   .r  r  r  r(  r  zThe language code to switch tor  r  )r   r3  r   r  rT   ra  r"   )r  r)  
desc_partscoder   s   &    r3   _build_switch_language_tool+PipelineSession._build_switch_language_tool.  s    $223
z?Q
D>>$-Dc$01  J)Aii
+,.12 H ""H)+K"J%# 

 	
r  c                b    V P                   '       g   R# RRRRRRRRRR	R
RRRRR/RRRRR/////# )z>Build search_extension tool for looking up people/departments.Nr   r  r   search_extensionr  a  Search the company directory by person name or department. Use this to look up a person's extension and availability before transferring. Returns matching entries with extension number, status, and availability. You MUST call this before using dial_extension.r  r  r  r  z-Person's name (partial or full) to search forr  zDepartment name to search forrZ  r  s   &r3   _build_search_extension_tool,PipelineSession._build_search_extension_toolN  sv    (((J*F
 H "H)+Z! %"H)+J'	#
 	
r  c                    V P                   '       g   R# RRRRRRRRRR	R
RRRRR/RRRRR//RRR.//RR. RORRRRRR//# )zLBuild dial_extension tool for transferring to a specific person's extension.Nr   r  r   dial_extensionr  zTransfer the call to a specific person. ONLY use when their status is ONLINE. For any other status (OFFLINE, BUSY, ONLEAVE, NOTALLOW), use leave_message_extension instead.r  r  r  	extensionr  z0The 4-digit extension number from REFERENCE DATAzThe person's full namer  rI   rP   rR   z09:00rS   z18:00rJ   rK   )rA   rB   rC   rD   rE   r9  r  s   &r3   _build_dial_extension_tool*PipelineSession._build_dial_extension_tooll  s    (((J(F H #"H)+]& "H)+C!	# f 5, ;w/	1
 	
r  c                
    V P                   P                  R\        V P                  4      RTR\	        V\
        4      '       d   \        V4      M/ R\	        V\        4      '       d   TMR/4       R#   \         d     R# i ; i)uj   Record a tool event for the post-call faithfulness check.
Append-only and fully isolated — never raises.	msg_indexr   	argumentsresultN)r  ra  r   ry  r2  r^  r`  rW   )r  r   argsrD  s   &&&&r3   _record_tool_event"PipelineSession._record_tool_event  ss    	$$S!6!67:dD+A+AT$ZrJvs$;$;&	&   		s   A/A3 3BBc                   VP                  R4      ;'       g    RP                  4       P                  4       pVP                  R4      ;'       g    RP                  4       P                  4       pV'       g   V'       g   R# . pV P                   F  pT;'       d#    W%P                  RR4      P                  4       9   pT;'       d#    W5P                  RR4      P                  4       9   pV'       d.   V'       d&   V'       g	   V'       d   VP	                  V4       K  K  V'       d   V'       d   VP	                  V4       K  V'       g   K  V'       g   K  VP	                  V4       K  	  V'       g3   V'       d   RVP                  R4       R2# RVP                  R4       R2# R	\        V4       R
2.pV EF  p	V	P                  RR4      .p
T
P	                  V	P                  R4      '       d   RV	R,           2MR4       V	P                  R4      '       d   V
P	                  RV	R,           24       V	P                  RR4      P                  4       pRRRRRRRRRR/pVP                  VR4      pV
P	                  RV RV R24       V	P                  R4      '       d   V
P	                  RV	R,           24       MV
P	                  R 4       V	P                  R!4      '       d   V
P	                  R"V	R!,           24       V	P                  R#4      '       d   V
P	                  R$4       VP	                  R%R&P                  R' V
 4       4      ,           4       EK  	  R(P                  V4      # ))zcSearch extensions directory by name and/or department.
Returns formatted result string for the LLM.r   r6   r  z2Please provide a name or department to search for.zNo person found matching "z1". Ask the caller to spell the name or try again.zNo department found matching "z".zFound z result(s):zDept: r  zExt: r  UNKNOWNONLINEzavailable - use dial_extensionOFFLINEz)unavailable - use leave_message_extensionBUSYz'on a call - use leave_message_extensionONLEAVEz&on leave - use leave_message_extensionNOTALLOWz5not accepting transfers - use leave_message_extensionzuse leave_message_extensionzStatus: r  r  rO   zHours: z)No extension (not available for transfer)emailzEmail: leaderLEADERz- r   c              3   8   "   T F  q'       g   K  Vx  K  	  R # 5ir  r   )r   r-   s   & r3   r   ;PipelineSession._handle_search_extension.<locals>.<genexpr>  s     *Aeq11es   	
r   )rT   r(   rZ   rZ  ra  r   rb  r"   )r  rE  
query_name
query_deptresultsr  
name_match
dept_matchlineseparts_status_status_hints_hints   &&            r3   _handle_search_extension(PipelineSession._handle_search_extension  s    hhv&,,"335;;=
hh|,2299;AAC
*G..E#SS
ii6K6Q6Q6S(SJ#YY
iib6Q6W6W6Y(YJjNN5) ",
u%

u% / 3DHHV4D3EEvww3DHH\4J3K2NN#g,{34AUU62&'ELLquu\7J7J6!L/!23PRSuuU||uQuXJ/0%%)4::<>JEG W! &))'3PQxy5';<55>>LL71W:,!78HIuuW~~wqzl34uuXX&LL

*Ae*A AAB/ 0 yyr  c                    . pV  F  pVP                  R/ 4      pVP                  RR4      pR
 F)  pVP                  V4      pVR8w  g   K  VRV^,            p M	  VP                  RRRRVP                  RR4      RVRRRR	/ ///4       K  	  V# )zConvert full tool definitions to lightweight stubs for two-tier routing.
Keeps name + first-sentence description, empties parameters.r  r  r6   Nr   r   r  r  r  r2  !?)rT   findra  )toolsstubsr[   funcdescdelimidxs   &      r3   _make_stub_tools PipelineSession._make_stub_tools  s     D88J+D88M2.D(ii&"9q>D	 )
 LL
DHHVR0!4 68\2"F    r  c                   . pR.pV  F  pVP                  R/ 4      pVP                  RR4      pV'       g   K1  VP                  V4       VP                  RR4      pR F)  pVP                  V4      pVR8w  g   K  VRV^,            p M	  VP                  RV RV 24       K  	  R	RRRR
RRP                  V4      RR	RRRR	RRRRV//RR.///# )zBBuild a single router tool with an enum of available action names.z/Select an action to perform. Available actions:r  r   r6   r  Nz  - r   r   
use_actionr   r  r  r  actionr  zThe action to performr  r  rb  re  )rT   ra  rf  r"   )	rg  actionsr3  r   fnr   r`   rk  rl  s	   &        r3   _build_meta_tool PipelineSession._build_meta_tool  s    GH
Az2&B66&"%DNN4 }b)A(ffUm"9(37A	 )
 TF"QC01  Jtyy4H  "H)+B"G## 


 	
r  c                l    V  F-  pVP                  R/ 4      P                  R4      V8X  g   K+  Vu # 	  R# )z8Find a tool definition by function name in a tools list.r  r   N)rT   )rg  r   r[   s   && r3   _find_full_toolPipelineSession._find_full_tool  s6     Dxx
B'++F3t;  r  c                4   V P                   pVP                  R4      ;'       g    . pV F-  pVP                  R/ 4      P                  R4      V8X  g   K+  Vu # 	  V P                   F-  pVP                  R/ 4      P                  R4      V8X  g   K+  Vu # 	  R# )zJFind tool definition by name across all tool sources (custom + per-agent).r   r  r   N)r  rT   r   )r  	tool_namer  agent_toolsr[   s   &&   r3   _find_tool_definition%PipelineSession._find_tool_definition  s    ii/552Dxx
B'++F3y@   %%Dxx
B'++F3y@ & r  c                <   VP                  4        F9  w  r4\        V\        4      '       g   K  RV9   g   K&  V P                  V4      W#&   K;  	  V P	                  V4      pV\
        9   d   \
        V,          ! W%R7      pM\        WR4      pV P                  WV4       V# )zExecute a custom tool handler or x_endpoint API call.
Checks CUSTOM_HANDLERS registry first, then falls back to x_endpoint.
Runs in executor (blocking). Returns None if no handler/endpoint found.r  )tool_def)rm  r2  r`  r  r|  r   r   rF  )r  rz  rE  _k_vr  rD  s   &&&    r3   _execute_tool_endpoint&PipelineSession._execute_tool_endpoint"  s    
 jjlFB"c""sby2226 # --i8'$Y/HF +8:F	8r  c                   V'       gJ   \        V P                  P                  4       4       F   pVR8w  g   K  W P                  V,          3u # 	  R# VP                  4       P	                  4       pV P                  P                  4        F/  w  r$VR8X  d   K  VR,          P	                  4       V8X  g   K,  W$3u # 	  V P                  P                  4        FJ  w  r$VR8X  d   K  W4R,          P	                  4       9   g   VR,          P	                  4       V9   g   KG  W$3u # 	  \        V P                  P                  4       4       F   pVR8w  g   K  W P                  V,          3u # 	  R# )z9Find the agent key (t1-t10) matching the department name.r   r   NN)sortedrj  r_  r(   rZ   rm  )r  department_namer  department_lowerr  s   &&   r3   _resolve_transfer_target(PipelineSession._resolve_transfer_target5  s/   dkk..01#:C 000 2 *00288:++++-JCczV}""$(88z!	 . ++++-JCcz=#6#6#88E&M<O<O<QUe<ez!	 . $++**,-CczKK,,, . r  c                $   VP                  4       P                  4       pV P                  P                  4        FS  w  r4VR9   d   K  VP	                  R4      '       g   K'  VP	                  R4      '       g   K@  VR,          V9   g   KP  W43u # 	  R# )zoCheck if transcript contains a hidden agent's trigger keyword.
Returns (agent_key, agent_dict) or (None, None).r   r   r   r  r  )r(   rZ   rj  rm  rT   )r  
transcript
text_lowerr  r  s   &&   r3   _check_keyword_trigger&PipelineSession._check_keyword_triggerQ  sy      %%'--/
++++-JCm#yy""uyy';';#z1:% . r  c                >/  "    V P                   '       Ed   V P                  4       G R j  xL
   RV n        V P                   '       EdO   V P                  R,          ^ 8  Ed6   V P                  p\        P                  V P                  \        \        ,          4      pVR,          VR,          ,          R,          VR,          VR,          ,          R,          ,           VR,          VR	,          ,          R,          ,           p\        R
VR,           RVR,           RVR,           RVR,           RVR,           RVR 24        V P                  RRRVR,          RVR,          RVR,          RVR,          RVR,          R\        V^4      /4      G R j  xL
  V P                  '       d   V P                  '       d    V P                  P                  R V P                   4      G R j  xL
 V n        V P"                  p\        RVR,           RVR,           RVR,           R24        V P                  RRRV/4      G R j  xL
  V P                  P                  R V P$                  4      G R j  xL
  V P                  P                  R V P&                  4      G R j  xL
  V P(                  '       d   V P*                  '       d   V P                  '       d   V P,                  '       g    V P                  P                  R V P.                  4      G R j  xL
 pV P                  RRRVP                  RR4      R VP                  R R!4      R"VP                  R"R!4      /4      G R j  xL
  V P2                  '       d   V P4                  '       d   V P                  '       do    V P                  P                  R V P6                  4      G R j  xL
 pV P                  RR$RVP                  RR4      R VP                  R R!4      /4      G R j  xL
  V P9                  4       G R j  xL
  V P:                  '       d#   V P:                  P=                  4       G R j  xL
  V P>                  '       d:    V P                  P                  R V P>                  P<                  4      G R j  xL
  \        R&4       R # V PA                  4       G R j  xL
  V PB                  '       d   V PE                  4       G R j  xL
  R'V n#        V P                  RRRR(/4      G R j  xL
  V P                  RR)R*V PH                  /4      G R j  xL
  V P                  RR+R,V PJ                  R-V PL                  R-,          /4      G R j  xL
  V P                  RRRR./4      G R j  xL
  V PN                  PQ                  4        UUu. uF  w  rxVRL9  g   K  VR-,          NK  	  p	ppV PR                  '       d(   \        R1V PN                  R0,          R-,           24       MhV	'       d:   \        R2V PN                  R/,          R-,           R3R4PU                  V	4       24       M'\        R2V PN                  R/,          R-,           R524       \V        PX                  ! V P[                  4       4      p
\V        PX                  ! V P]                  4       4      p\V        PX                  ! V P_                  4       4      pV PJ                  R08X  Edk   V P`                  '       EdX   V P`                  p\        R6VR7,           R824       R9V n#        V P                  RRRR:/4      G R j  xL
  V P                  RR;R<R=R>VR,V PL                  R-,          /4      G R j  xL
  V Pc                  R=WPL                  R-,          4       V PL                  R?,          Pe                  R@RARBV/4       V Pf                  P                  RCV Pf                  P                  RDRE4      4      pV P                  P                  R V Ph                  W4      G R j  xL
  R'V n#        V P                  RRRR./4      G R j  xL
  \        RF4       EMV PJ                  R/8X  Edv   V Pk                  V Pl                  RC4      pV'       EdQ   \        RGVR7,           R824       R9V n#        V P                  RRRR:/4      G R j  xL
  V P                  RR;R<R=R>VR,V PL                  R-,          /4      G R j  xL
  V Pc                  R=WPL                  R-,          4       V PL                  R?,          Pe                  R@RARBV/4       V Pf                  P                  RCV Pf                  P                  RDRE4      4      pV P                  P                  R V Ph                  W4      G R j  xL
  R'V n#        V P                  RRRR./4      G R j  xL
  RHV n7        \        RF4       \V        Pp                  ! WV.\V        Pr                  RI7      G R j  xL
 w  ppV F  pVPu                  4        K  	  RV n        V P                   '       EdO   V P                  R,          ^ 8  Ed6   V P                  p\        P                  V P                  \        \        ,          4      pVR,          VR,          ,          R,          VR,          VR,          ,          R,          ,           VR,          VR	,          ,          R,          ,           p\        R
VR,           RVR,           RVR,           RVR,           RVR,           RVR 24        V P                  RRRVR,          RVR,          RVR,          RVR,          RVR,          R\        V^4      /4      G R j  xL
  V P                  '       d   V P                  '       d    V P                  P                  R V P                   4      G R j  xL
 V n        V P"                  p\        RVR,           RVR,           RVR,           R24        V P                  RRRV/4      G R j  xL
  V P                  P                  R V P$                  4      G R j  xL
  V P                  P                  R V P&                  4      G R j  xL
  V P(                  '       d   V P*                  '       d   V P                  '       d   V P,                  '       g    V P                  P                  R V P.                  4      G R j  xL
 pV P                  RRRVP                  RR4      R VP                  R R!4      R"VP                  R"R!4      /4      G R j  xL
  V P2                  '       d   V P4                  '       d   V P                  '       do    V P                  P                  R V P6                  4      G R j  xL
 pV P                  RR$RVP                  RR4      R VP                  R R!4      /4      G R j  xL
  V P9                  4       G R j  xL
  V P:                  '       d#   V P:                  P=                  4       G R j  xL
  V P>                  '       d:    V P                  P                  R V P>                  P<                  4      G R j  xL
  \        R&4       R #  EL EL  \         d     EL)i ; i EL EL  \         d     ELi ; i  \         d!   p\        RT 24       R T n         R p?ELR p?ii ; i EL ELs EL EL  \         dZ   p\        R#T 24        T P                  RRRRR \1        T4      /4      G R j  xL 
   R p?EL  \         d	      R p?EL
i ; iR p?ii ; i EL ELz  \         dZ   p\        R%T 24        T P                  RR$RRR \1        T4      /4      G R j  xL 
   R p?EL  \         d	      R p?ELi ; iR p?ii ; i EL EL ELS  \         d     EL_i ; i ELC EL E
L E
L E
L E
Lu uppi  EL EL EL  EL ELd EL5 EL ELi EL*  \         dA   p\        RJT 24       T P                  RRKR \1        T4      /4      G R j  xL 
   R p?ELRR p?ii ; i EL  \         d     ELi ; i EL ELc  \         d     ELoi ; i  \         d!   p\        RT 24       R T n         R p?ELR p?ii ; i ELx ELM EL EL  \         dZ   p\        R#T 24        T P                  RRRRR \1        T4      /4      G R j  xL 
   R p?EL  \         d	      R p?ELi ; iR p?ii ; i EL ELT  \         dZ   p\        R%T 24        T P                  RR$RRR \1        T4      /4      G R j  xL 
   R p?EL  \         d	      R p?ELi ; iR p?ii ; i EL ELu EL-  \         d     EL9i ; i  RT n        T P                   '       Edb   T P                  R,          ^ 8  EdI   T P                  p\        P                  T P                  \        \        ,          4      pTR,          TR,          ,          R,          TR,          TR,          ,          R,          ,           TR,          TR	,          ,          R,          ,           p\        R
TR,           RTR,           RTR,           RTR,           RTR,           RTR 24        T P                  RRRTR,          RTR,          RTR,          RTR,          RTR,          R\        T^4      /4      G R j  xL 
  M  \         d     Mi ; iT P                  '       d   T P                  '       d    T P                  P                  R T P                   4      G R j  xL 
 T n        T P"                  p\        RTR,           RTR,           RTR,           R24        T P                  RRRT/4      G R j  xL 
  M>  \         d     M1i ; i  \         d    p\        RT 24       R T n         R p?MR p?ii ; iT P                  P                  R T P$                  4      G R j  xL 
  T P                  P                  R T P&                  4      G R j  xL 
  T P(                  '       Ed    T P*                  '       Ed   T P                  '       d   T P,                  '       g    T P                  P                  R T P.                  4      G R j  xL 
 pT P                  RRRTP                  RR4      R TP                  R R!4      R"TP                  R"R!4      /4      G R j  xL 
  Me  \         dX   p\        R#T 24        T P                  RRRRR \1        T4      /4      G R j  xL 
   R p?M  \         d      R p?Mi ; iR p?ii ; iT P2                  '       d   T P4                  '       d   T P                  '       d    T P                  P                  R T P6                  4      G R j  xL 
 pT P                  RR$RTP                  RR4      R TP                  R R!4      /4      G R j  xL 
  Me  \         dX   p\        R%T 24        T P                  RR$RRR \1        T4      /4      G R j  xL 
   R p?M  \         d      R p?Mi ; iR p?ii ; iT P9                  4       G R j  xL 
  T P:                  '       d$   T P:                  P=                  4       G R j  xL 
  T P>                  '       dM    T P                  P                  R T P>                  P<                  4      G R j  xL 
  M  \         d     Mi ; i\        R&4       i ; i5i)MNFr   r   r>   @B r   r?   r   r@   z[Cost] Turns: z	, Input: zt/za, Output: r   z
a, Cost: $.4fr   cost_summarytotal_cost_usdz[Faithfulness] r  r   flagged_countz flagged / checked_turnsz	 AI turnsfaithfulnessrD  z&[Faithfulness] check error (ignored): acrs_statussuccessmessager6   case_noz[ACRS] Dispatch error: 	cv_statusz[Validator] Dispatch error: z[Pipeline] Session ended	LISTENINGreadyrx  rm   agent_changer  r   	listeningr   r  u:   [Pipeline] Ready — Language Agent enabled, starting at: u   [Pipeline] Ready — Agent A: , Transfer targets: r    (single agent)z[Greeting] Language agent: "NP   N..."SPEAKINGspeakingr  speakerair  r   role	assistantcontentrc   r   r   z[Greeting] Done, listening...z[Greeting] Fixed: "Treturn_whenz[Pipeline] Error: errorr  );r5  	_run_omniru  rR  OMNI_PRICINGrT   r   r7  r6  _emitroundrW   r  ry  r/  run_in_executor_run_faithfulness_checkr  _save_conversation_save_caller_recordingr  r  r  _dispatch_to_acrsr`  r  r  _dispatch_to_validator_disconnect_emotion_enginert  closer8  _connect_asrr  _connect_emotion_enginers  rx  rr  r  rj  rm  rn  r"   r0  create_task_asr_receiver_browser_audio_handler_senderr  _log_messagera  r   _run_ttsrf  re  rq  waitFIRST_COMPLETEDcancel)r  ur-   cost_frrZ  rD  r  r   transfer_namesasr_taskbrowser_tasksender_taskgreetinggreeting_voiceinitial_greetingdonependingr   s   &                  r3   runPipelineSession.run_  s    u	.~~~nn&&&`  DK~~~$"9"9'"BQ"F++ $$T__l:6NO)*Q|_<yH,--0@@9LM-.>1BBYNO 
 qzl 3  !"5 67r!<P:Q9R S!!"#7!8 9A>S<T;U V  $Sz+ ,**7+Q/B-C,a0D.E,a0D.E-q1F/G(%a.&    (((T-B-B-B56:ii6O6Od::7< 1<D-33COCM?" 12+ 12)= >"jj&.*2C*9 : : : ))++D$2I2IJJJ))++D$2M2MNNN!!!d&7&7&7---d6J6J6J#'99#<#<d44$6 6F**!6::i#?!6::i#<!6::i#<	&   " 4???t7L7L7L#'99#<#<d99$; ;F**!6::i#?!6::i#<&    11333{{{kk'')))))33D$//:O:OPPP ,-c ##%%%###22444$DJ**fh'BCCC**flD$//JKKK**fngt?P?P$dkk&&9; < < <**fh+FGGG6:kk6G6G6I ;6IFC!$M!9 (aii6IN ;*** &&*kk&&9&&A%BD E6t{{37G7O6P Q++/99^+D*EG H 6t{{37G7O6PP_`a**4+=+=+?@H"..t/J/J/LML!--dlln=K   F*t/K/K/K774Xc]O4HI'
jj&(Hj!IJJJjj&,	4"((")4;;v+>"@ A A A !!$++f2EFI&--[)X>@!%!3!3DNN&&y':"<ii//$--C C C(
jj&(Hk!JKKK56""c)#'??43J3JD#Q ##/0@0E/FdKL!+DJ**fh*%MNNN**flIt&,.>&-t{{6/B&D E E E %%d,<kk&>QRKK	*11i9IJL%)^^%7%7**9g>&@N))33dmm-=O O O!,DJ**fh+%NOOO/3D,9:"),,5#33# MD' 
   DK~~~$"9"9'"BQ"F++ $$T__l:6NO)*Q|_<yH,--0@@9LM-.>1BBYNO 
 qzl 3  !"5 67r!<P:Q9R S!!"#7!8 9A>S<T;U V  $Sz+ ,**7+Q/B-C,a0D.E,a0D.E-q1F/G(%a.&    (((T-B-B-B56:ii6O6Od::7< 1<D-33COCM?" 12+ 12)= >"jj&.*2C*9 : : : ))++D$2I2IJJJ))++D$2M2MNNN!!!d&7&7&7---d6J6J6J#'99#<#<d44$6 6F**!6::i#?!6::i#<!6::i#<	&   " 4???t7L7L7L#'99#<#<d99$; ;F**!6::i#?!6::i#<&    11333{{{kk'')))))33D$//:O:OPPP ,-g '@ ! 1<:$   5B1#FG04D--5 KN
6 ! 	3A378"jj"M%u%s1v*   
 % 	;
 ! 	8<="jj"K%u%s1v*   
 % 	 4) Q  _ &4CK<G;, KAC L OEO P  	C&qc*+**fgy#a&ABBB	C& ! 1<:$   5B1#FG04D--5 KN
6 ! 	3A378"jj"M%u%s1v*   
 % 	;
 ! 	8<="jj"K%u%s1v*   
 % 	 4) Q  A  DK~~~$"9"9'"BQ"F++ $$T__l:6NO)*Q|_<yH,--0@@9LM-.>1BBYNO 
 qzl 3  !"5 67r!<P:Q9R S!!"#7!8 9A>S<T;U V  $Sz+ ,**7+Q/B-C,a0D.E,a0D.E-q1F/G(%a.&    ! 
 (((T-B-B-B56:ii6O6Od::7< 1< 1<D-33COCM?" 12+ 12)= >"jj&.*2C*9 : : :$   5B1#FG04D--5 ))++D$2I2IJJJ))++D$2M2MNNN!!!d&7&7&7---d6J6J6J#'99#<#<d44$6 6 6F**!6::i#?!6::i#<!6::i#<	&    ! 	3A378"jj"M%u%s1v*   
 % 	 4???t7L7L7L#'99#<#<d99$; ; ;F**!6::i#?!6::i#<&   
 ! 	8<="jj"K%u%s1v*   
 % 	 11333{{{kk'')))))33D$//:O:OPPP  ,-s	  A^&A@9 z-A@9 DA^Az3 z0z3 A^*A^=){ &{'?{ '{ ?{ { )A^-|.-A^|A^2A^A^A^))| |A| #|$| (A^:A^A^)~ }>	>~ ~~ A^+ A^6A^.A^+34 14 #A^0A@9 A@A@9 A@9 -A@	.#A@9 A@&A@9 8A@99A@9 2A@3A@9 A@!A@9 1A@A@AA@9 C0A@9 AA@9 A@1A@9 6A@!7B-A@9 $A@$%#A@9 A@'	AA@9 5A@9 A@*1A@9 8A@-9B-A@9 &A@0'#A@9 
A@3AA@9 A@6 A@9 -DA^AAB
 ABAB
 A^'A^:)AB4 #AB$?AB4 $AB" <AB=AB" )A^*AC"+-A^AC%A^/A^A^A^&)AC. AC(AAC.  AC+!AC. %A^7A^	A^)AE AE>AE AEAE 	A^AGA^3A^AGA^(3AG AGAG  A^-A@9 0z3 3{>A^{A^{ { {{ A^{{ |(|=A^|A^A^| | };"}61#} }} A^ }3+}6,A^2}33}66};;A^>~ ~ (##A^ #A^  ##((A^.A^14 4A@?A^@A@@A^@A@9 @	A@9 @A@9 @A@9 @A@9 @A@9 @A@9 @!A@9 @$A@9 @'A@9 @*A@9 @-A@9 @0A@9 @3A@9 @6A@9 @9ABA/AA?A3AA6A4AA?A9AG A?ABBAG BAB
 B
ABBA^BABBA^BAB4 BAB" B"AB1B-AB4 B.A^B0AB1B1AB4 B4ACB?ACCA^CACCA^C%A^C(AC. C+AC. C.AEC9AED#AD7D+AD.D,AD7D1A^D7AE
EAEEA^E	AE
E
AEEAEEA^EAE EAE EAF?E&AF:E5#AF$FAFFAF$FA^F$AF7F/AF:F0A^F6AF7F7AF:F:AF?F?A^GA^GAG GAGGA^GAGGA^GDA^K2AAMMAMMAMMA^MAMMA^MAMMA^M+A^M>)APN'AN*N(A APO)APPAPPAPPA^PAPPAPPA^PAPPAPPAQP$AP>P9A^P>AQQ,A^Q/AQ2Q0.A^RAR!RA^R7A^S
A^SA^S/)AU1TATTAAU1U*AU-U+AU1U0A^U1AWU<AWV#AV9V.AV1
V/AV9V4A^V9AW	WAWWA^W
AW	WAWWAWWA^W(A^W:A^X)AY=X6AX9X7?AY=Y6AY9Y7AY=Y<A^Y=A[ZA[Z#A[Z:AZ=
Z;A[[ A^[A[	[A[[A^[A[	[A[[A[[A^[5A[8[6A^\A^\*A\-\+A^]3A]=]6A]9]7A]=]<A^]=A^^A^^
A^^A^^A^c                  a a"   \        RS P                   RS P                   24       \        S 4      p\	        S P                  V\
        R7      S n        S P                  P                  RS P                  P                  4      G Rj  xL
  S P                  '       d   S P                  4       G Rj  xL
  S P                  4       pS P                  4       pRTRS P                  ;'       g    RRS P                  ;'       g    ^/oS P                   e   S P                   SR	&   V'       d   VSR
&   S P                  P                  RV V3R l4      G Rj  xL
  S P"                  P%                  R^R\&        P(                  ! 4       P+                  R4      RS P,                  RS P.                  P1                  RR4      RRRRV/.R
VRRRRRS P                  /	4       RS n        S P5                  RRRR/4      G Rj  xL
  S P5                  RR R!S P6                  /4      G Rj  xL
  S P5                  RR"RS P,                  RS P.                  R,          /4      G Rj  xL
  S P5                  RRRR#/4      G Rj  xL
  S P8                  P;                  4        UUu. uF  w  rEVR,9  g   K  VR,          NK  	  pppS P<                  '       d(   \        R&S P8                  R%,          R,           24       MhV'       d:   \        R'S P8                  R$,          R,           R(R)P?                  V4       24       M'\        R'S P8                  R$,          R,           R*24       \@        PB                  ! S PE                  4       4      p\@        PB                  ! S PG                  4       4      p\@        PB                  ! S PI                  4       4      p	\@        PB                  ! S PK                  4       4      p
S PM                  4       G Rj  xL
  \@        PN                  ! WxW.\@        PP                  R+7      G Rj  xL
 w  rV F  pVPS                  4        K  	  R#  EL EL EL EL_ EL; EL ELu uppi  Ll L>5i)-uG   Main lifecycle for Omni mode — single WebSocket replaces ASR+LLM+TTS.z[Omni] Starting session: model=z, voice=r#  callbackurlNr   r   皙?max_response_output_tokensr   rg  c                     < S P                   P                  ! RR \        P                  \        P                  .RS P
                  RS P                  RS P                  RS P                  /SB # )output_modalitiesvoiceturn_detection_threshold"turn_detection_silence_duration_msinput_audio_transcription_modelr   )	r8  update_sessionr   AUDIOTEXTr   r   r   r   )r  update_kwargss   r3   <lambda>+PipelineSession._run_omni.<locals>.<lambda>6  sq    DOO22 #0#6#68J8J"Koo *.);); 483K3K	
 15  r  turn	timestamp%H:%M:%Sr  
agent_namer   r6   messagesr  systemr  r5  T
omni_eventsession_startr  r  r   r  r  rx  rm   r  r  r   r  u6   [Omni] Ready — Language Agent enabled, starting at: u   [Omni] Ready — Agent A: r  r   r  r  r  )*r6  r   r   r   r   	OMNI_BASEr8  r/  r  connectr  r  _build_omni_tools_build_omni_instructionsr   r   r   rz  ra  r   rX   rY   rr  r  rT   rs  r  rx  rj  rm  rn  r"   r0  r  _omni_browser_audio_handlerr  _omni_keepalive_omni_idle_monitor_omni_play_greetingr  r  r  )r  r  rg  r   r  r   r  r  r  keepalive_task	idle_taskr  r  r   r  s   f             @r3   r  PipelineSession._run_omni  s    //@HYZ[  %2//H)
 ii''doo.E.EFFF..000 &&(446 L4++22s($//*@*@S

 ::!%)ZZM'"%*M'"ii''

 
	
 
	
 	A00<T&&$++//&"5&(I|DEU/T__
 
 
	 !
jj&(Hg>???jj&,dooFGGGjj&.'4;L;L $++f"57 8 	8 	8jj&(HkBCCC26++2C2C2E 72E 5 $!F))2E 7&&& ""&++f"5f"=!>@ A.t{{3/?/G.H I''+yy'@&AC D .t{{3/?/G.HXY **4+K+K+MN))$,,.9 ,,T-A-A-CD''(?(?(AB	 &&(((%llB//
 
 AHHJ W 	G0 
	
4 	@G	8C7& 	)
s   BQ1	Q
Q1 Q13Q49Q1.Q1(Q1-)Q1QB%Q1<Q=&Q1#Q$9Q1Q!Q1:Q$;!Q1Q',Q'9AQ1=DQ1 Q-/Q10Q/1"Q1Q1Q1Q1Q1!Q1$Q1'Q1/Q1c                   "    \         P                  ! V P                  P                  4       VR7      G Rj  xL
  R#  L  \         P                   d    \        RT R24        R# i ; i5i)zyWait for the current Omni response to finish (response.done event).
Returns True if response completed, False on timeout.timeoutNTz.  [Omni] Timed out waiting for response.done (s)F)r0  wait_forrQ  r  TimeoutErrorr6  )r  r  s   &&r3   _omni_wait_response_done(PipelineSession._omni_wait_response_donep  sm     	""..335wH H HH ## 	B7)2NO	s5   A+3A  >A  A+A   $A($A+'A((A+c                D  "   V P                   '       g   R# RV n        V P                  P                  4        \        P
                  ! ^ 4      G Rj  xL
  V P                  P                  4        V P                  P                  RV P                   P                  V4      G Rj  xL
  V P                  VR7      G Rj  xL
 p\        ^24       FD  pV P                  P                  4       '       d    V# \        P
                  ! R4      G Rj  xL
  KF  	  V#  L Lu L] L5i)zSend a response.create message and wait for it to complete.
Clears the done-event first to avoid returning on a stale signal.
After response.done, drains the sender queue so all audio reaches
the client before the next response can bump _omni_audio_gen.FTNr  皙?)r8  r<  rQ  clearr0  sleepr/  r  send_rawr  ranger   empty)r  r   r  rD  r1   s   &&&  r3   _omni_send_response_and_wait,PipelineSession._omni_send_response_and_wait{  s     
 $(!&&,,. mmA&&,,.ii''$//**C1 	1 	144W4EErAzz!! --$$$   		1E
 %sJ   AD DAD $D%D >D?AD DD D D D c                H  "   V P                   R8X  d    V P                  '       d   V P                  pM0V P                   R8X  d   V P                  V P                  R4      pMRpV'       g   R# V P                  '       g   R# \        RVR,           R24       V P                   R8X  d   R	V n        R	V n        \        P                  ! R
RRRRR.RRV R2//4      pV P                  P                  RV P                  P                  V4      G Rj  xL
  \        R4       R#  L5i)z}Have Omni speak the initial greeting via response.create.
OmniCallback handles logging and history when Omni actually speaks.r  r   rc   r6   Nz[Omni Greeting] "r  r  Tr   response.createresponse
modalitiesr  audior   zSay EXACTLY the following greeting, word for word. Do not add, remove, or change anything. Do not add any extra greeting or introduction:

"r   z7[Omni Greeting] Triggered, waiting for Omni to speak...)rr  r  rf  re  r8  r6  rq  r<  r   dumpsr/  r  r  )r  r  response_msgs   &  r3   r  #PipelineSession._omni_play_greeting  s     &4+G+G+G33H#%t'>'>EHH!(3-56#'+D$
 %)!zz%vw/JJRSTV
#
 
 ii''$//**L: 	: 	:GH	:s$   #D"AD"+D"?BD"D D"c                F
  "    V P                     Rj  xL
  p\        P                  ! V4      pVP                  R4      R8X  dR   V P                  '       g>   VP                  RR4      pV P
                  '       d   V P                  V4      G Rj  xL
  K  VP                  R4      R8X  d\   V P                  '       dH   V P                  '       d6   V P                  '       g$   \        R4       V P                  4       G Rj  xL
  K  VP                  R4      R8w  d   EK   \        P                  ! VR,          4      pVP                  R4      pVe   V P                  e   V P                  P                  4       '       d|    V P                   P#                  RV P                  P$                  V4      G Rj  xL
 pV'       d7   \        P&                  ! V4      P)                  4       pV P+                  V4       MRpMVe   V P+                  V4       V'       Ed   V P                  '       Ed   V P                  '       Ed   V P                  '       Eg   \-        V4      ^,          pV^ 8  Ed   \.        P0                  ! R	V R
2VRV^,           4      p\3        R V 4       4      p	\4        P6                  ! W,          4      R,          p
\9        V R4      '       g   ^ V n        RV n        V ;P:                  ^,          un        \?        V P<                  V
4      V n        V P:                  ^,          ^ 8X  dA   \        RV
R RV P<                  R RV P@                   RV PB                  RJ 24       RV n        WP@                  8  d   V PB                  f   \D        PD                  ! 4       V n!        \D        PD                  ! 4       V PB                  ,
          R,          pWPF                  8  d-   \        RV
R RVR R24       V P                  4       G Rj  xL
  MRV n!        V PH                  '       d@   V PJ                  '       d.   V'       d&   \L        PN                  ! V PQ                  V4      4       V P
                  '       g   EKs  Vf   EKz   V P
                  PS                  V4       EK   EL EL EL  \         d    Rp ELi ; i EL  \         d    T P+                  T4        ELi ; i L  \         d     EK  i ; iEDR#   \T        PV                   d     R# i ; i5i)z@Receive audio from browser/bridge and forward to Omni WebSocket.Nr   greeting_triggerprompt"[call connected, greet the caller]barge_in_vadz&  [Omni BARGE-IN] Client VAD triggeredr  <hc              3   2   "   T F  qV,          x  K  	  R # 5ir  r   r   r   s   & r3   r   >PipelineSession._omni_browser_audio_handler.<locals>.<genexpr>  s     $<GqUUG         @_dbg_rms_count        z  [Omni RMS] rms=r  z max=z threshold=z speech_start=  z'  [Omni BARGE-IN] Speech detected (RMS=.3fr   .0fms)),r.  r   loadsrT   r9  r8  _omni_inject_system_messager   r:  r6  _omni_trigger_barge_inbase64	b64decoderW   r  r  r/  r  process	b64encodedecode_rec_add_callerr   structunpacksummathsqrthasattrr   _dbg_rms_maxmaxr   r=  timer   r  r  r0  r  _forward_audio_to_emotionappend_audio
websocketsConnectionClosed)r  rawdatar  	pcm_chunkforward_b64denoisednum_samplessamplessum_sqrms
elapsed_mss   &           r3   r  +PipelineSession._omni_browser_audio_handler  se    \	!WW Y Yczz#88F#'99000!%(4X!Y???"&"B"B6"JJJ88F#~5--- $ 5 5 5$($7$7$7FG"99;;;88F#w.% & 0 0g ?I #hhw/)d.D.D.P 22<<>>8)-)B)B $"8"8"@"@)*M $M $*0*:*:8*D*K*K*MK 00:*.K *((3 I$"7"7"7 111$:M:M:M"%i.A"5K"Q"(--!K=0B09:J;?0K#M!$$<G$<!<"ii(<=G&t-=>>23D/03D-++q0+,/0A0A3,G)..2a7!$5c#YeDDUDUVYCZ [//3/E/E.F G2262R2RZ^2^1_#a b 14D-!7!77#??GCG99; @*.))+,0,L,L+MPT*UJ)-J-JJ % )..1#YbC8H'M !N&*&A&A&C C C?CD< '''D,<,<,<''(F(Fy(QR ???{'>44[AoY K < ! % $I%$M % 8,,Y78F !D % q %t ** 		sR  T!T TR)T?T #T <T R,-T ?T T #T R/T "R2?AT 4S	7S8S	5S	9T :S	<T T .T T F<T S,T /T T 	4T T S.&T )T,T /T 2S?T ST S		S)%T (S))T .S>9T =S>>T T!TT!TT!c                F  "   V P                   '       g   R# \        P                  ! RRRRRRRRRR	R
V/.//4      p V P                  P	                  RV P                   P
                  V4      G Rj  xL
  R#  L  \         d   p\        RT 24        Rp?R# Rp?ii ; i5i)a  Add a text item to the Omni conversation WITHOUT triggering a
response (unlike _omni_inject_system_message). Used to nudge the model
after a barge-in so the interruption reads as a continued flow rather
than a brand-new turn. The next server-VAD auto-response picks it up.Nr   conversation.item.createitemr  r  userr  r>   r  z)  [Omni BARGE-IN] context inject failed: )r8  r   r  r/  r  r  rW   r6  )r  r  item_msgrZ  s   &&  r3   _omni_add_context_item&PipelineSession._omni_add_context_item  s     
 ::.	V\64@A
 	C))++doo..: : : 	C=aSABB	Cs@   :B!4A: 1A82A: 6B!8A: :BBB!BB!c                  "   V P                   '       g   R# \        P                  ! RRRRRRRRRR	R
V/.//4      pV P                  P	                  RV P                   P
                  V4      G Rj  xL
  RV n        \        P                  ! RR/4      pV P                  P	                  RV P                   P
                  V4      G Rj  xL
  R#  L^ L5i)zNInject a system-level message into the Omni conversation and trigger response.Nr   rH  rI  r  r  rJ  r  r>   r  Tr  )r8  r   r  r/  r  r  r<  )r  r  rK  r  s   &&  r3   r'  +PipelineSession._omni_inject_system_message.  s     ::.	V\64@A
  ii''$//**H6 	6 	6$(!zz6+<"=>ii''$//**L: 	: 	:		6	:s%   A.C0C1ACC	CCc                t  "   \         P                   ! 4       p\        RV RVR,           RV 24        V'       d   \        P                  ! V4      M/ p V P                  WW#4      G Rj  xL
  \        \         P                   ! 4       V,
          R,          4      pV P                  RRR	R
RVRV/4      G Rj  xL
  R#   \        P                  \
        3 d    / p Li ; i Lv L+  \        \         P                   ! 4       T,
          R,          4      pT P                  RRR	R
RTRT/4      G Rj  xL 
  i ; i5i)z=Handle a tool call from Omni. Runs on the asyncio event loop.z  [Omni Tool] (N   Nz
) call_id=Nr"  r   timingstage	tool_callr[   rg   )	r7  r6  r   r&  r   	TypeError_handle_omni_tool_call_innerintr  )r  r   rC  call_idt_startrE  tool_mss   &&&&   r3   _handle_omni_tool_call&PipelineSession._handle_omni_tool_callA  s    ))+tfAio%6j	JK	,54::i(2D	<33D	SSS499;0D89G**fh$dD'; < < < $$i0 	D	 T< 499;0D89G**fh$dD'; < < <sl   1D8 B> C% *C!+C% /AD87C#8D8>CD8CD8!C% #D8%A	D5.D1/D55D8c                  "   V P                  ^R7      G Rj  xL
  V P                  p. V n        VR8X  dV   V P                  '       dD   \        WWCV4      G Rj  xL
 pVf   V P	                  WR4       R# V P	                  WV4       TpEM[VR8X  dD   \        WWCV4      G Rj  xL
 pVf   V P	                  WR4       R# V P	                  WV4       TpEMVR8X  d*   V P	                  WR4       \        WWCV4      G Rj  xL
  R# VR	8X  d*   \        WWCV4      G Rj  xL
 pV P	                  WV4       EMVR
8X  dU   V P                  R8X  dD   \        WWCV4      G Rj  xL
 pVf   V P	                  WR4       R# V P	                  WV4       TpEMVVR8X  d*   V P	                  WR4       \        WWCV4      G Rj  xL
  R# VR8X  dC   \        WWCV4      G Rj  xL
 pVf   V P	                  WR4       R# V P	                  WV4       TpMVR8X  d]   V P                  RRRVRV/4      G Rj  xL
  V P                  RRV RV R24       V P                  V4      pV P	                  WV4       MzVR#9  d9   V P                  RRRVRV/4      G Rj  xL
  V P                  RRV RV R24       V P                  P!                  RV P"                  W4      G Rj  xL
 pVe   V R2pMRpV'       dl   V P$                  '       dZ   \&        P(                  ! RRRRRRVR V//4      p	V P                  P!                  RV P$                  P*                  V	4      G Rj  xL
  VR#9   dQ   \-        WW$W5V4      G Rj  xL
  V P                  RRRVRV/4      G Rj  xL
  V P                  RRV RV R24       R# V'       do   V P$                  '       d[   R!V n        \&        P(                  ! RR"/4      p
V P                  P!                  RV P$                  P*                  V
4      G Rj  xL
  R# R# R#  EL EL EL EL3 EL EL EL ELf EL EL ELq L L L L15i)$uA   Inner handler for Omni tool calls — routes to tool_handlers.py.r  Nr  SUCCESS: transfer initiated.r  z!SUCCESS: transfer back initiated.r#  zSUCCESS: call ended.r  r'  r  zSUCCESS: language selected.r-  z SUCCESS: language agent engaged.r1  zSUCCESS: language switched.r8  r   rV  r   rC  r  
Function: rQ  r  z
Do not repeat any parameter values (such as phone numbers, links, or IDs) in your spoken response. Just confirm the action naturally to the caller.zFunction executed successfully. Do not repeat any parameter values (such as extension numbers, phone numbers, or IDs) in your spoken response. Just confirm the action naturally to the caller.rH  rI  function_call_outputrZ  outputTr  )r=  dial_department)r  rH  rl  r   rF  r   r   r	   rr  r
   r   r   r  r  r_  r/  r  r  r8  r   r  r  r   r<  )r  r   rE  rC  rZ  buffered_audiorD  result_text
api_resulttool_result_msgr  s   &&&&&      r3   rX  ,PipelineSession._handle_omni_tool_call_innerR  s     ++A+666 66(*%
 ?"t'C'C'C/GP^__F~ ''4RS##D7 K_$/GP^__F~''4WX##D7 KZ##D0FG!$g.QQQ[  0WQ_ ``K##D<&&4+<+<+F1$gR`aaF~''4QR##D7 K&&##D0RS(WXXX&&1$gR`aaF~''4QR##D7 K''**VTY    h*TF!I;a(HI77=K##D< @@jjK"    !!(ja	{!,LM#yy88d114 ? ?J%!l #G G G  t"jj22wk* O ))++doo..A A A 88d$T_``` **VTY    h*TF!I;a(HI t(,D%::v/@&ABL))++doo..> > > '7w 	7 ` ` R a b Y b
?6A
 a>s2  QP)/Q	QP,A	Q#P/$AQ?P2 QP5A QP8AQ:P;;QP>AQ+Q,A"QQAQQQ/QAQQ
Q2Q3QQ&Q9QAQQQ,Q/Q2Q5Q8Q;Q>QQQQ
QQQQc                  "   V P                   '       g   R# VR,          pV P                  R,          p\        P                  ! RR/4      pV P                  P                  RV P                   P                  V4      G Rj  xL
  \        P                  ! R4      G Rj  xL
  RpV P                  '       d1   V P                  R8w  d    RV P                  V P                  4       R	2p\        P                  ! RR
RRRR.RRV 2//4      pV P                  V^
R7      G Rj  xL
  V P                  RRRVRVRRVR,           2/4      G Rj  xL
  V P                  RRV RV 24       V P                  RRVRRVR,           2/R4       V P                  ^ 8  dL   V P!                  V P                  4      G Rj  xL
  \        P                  ! V P                  4      G Rj  xL
  Wn        V P                  RRR VRV/4      G Rj  xL
  V P%                  4       G Rj  xL
  \'        R!V 24       RpV P                  '       dM   V P                  R8w  d<   R"V P                  V P                  4       R#V P                  V P                  4       R	2pR$V n        \        P                  ! RR
RRRR.RR%V 2//4      p	V P                  P                  RV P                   P                  V	4      G Rj  xL
  R#  ELu ELZ EL EL ELI EL$ EL L L5i)&zAHandle keyword-triggered transfer to a hidden agent in Omni mode.Nr   r   response.cancelr   r6   rc   z
 Speak in r2  r  r  r  r  r  r   zITell the caller you are now connecting them. Keep it to 1 short sentence.r  transferfromtor  	Keyword: r   r  Transfer (keyword):  -> r  r  z	keyword: r`  r  r  z1  [Omni KEYWORD] Transfer greeting triggered for z The caller has been speaking z . You MUST greet and respond in TzYA caller has just been connected to you. Generate a warm, brief greeting (1-2 sentences).)r8  r  r   r  r/  r  r  r0  r  rv  
_lang_namer
  r  r  rF  r   _emit_silencerr  _omni_update_agent_sessionr6  r<  )
r  
target_keytarget_agentto_name	from_name
cancel_msg_fw_langfarewell_msg_gr_langgreeting_msgs
   &&&       r3   _omni_keyword_transfer&PipelineSession._omni_keyword_transfer  s8    v&KK'	 ZZ): ;<
ii''$//**J8 	8 	8mmC       T%:%:d%B#DOOD4I4I$J#K1MHzz%vw/33;*>#
  //b/IIIjj&* )T7"iY0G/H$IK L 	L 	L 	("9+T';	=!-w!)Y|I7N6O+P!R >	@ "$$T%8%8999-- 3 3444 'jj&.': '+ , 	, 	,--///A'KL    T%:%:d%B8??4+@+@AB C9??4+@+@AB!EH %)!zz%vw/GGOjR#
  ii''$//**L: 	: 	:u	8  	J	L :4	,/(	:s   A=L?K4 LK7L6A)LK: *L
K=A,L7L 8'LL $LLLL	CL-L.L7L:L=L LLL	LLc                   V P                  4       pVR,          pV P                  '       d   VRV P                   2,          pVR,          pV P                  4       pVRV RV R2,          pV P                  '       dH   V P                  R8w  d7   V P	                  V P                  4      pRV R	2V,           R
V RV R2,           pWP                  4       ,          pV# )zIBuild full instructions for Omni session including language restrictions.^   
IMPORTANT: Keep every reply to 1-2 short sentences. Be concise — this is a live phone call.z
SPEECH STYLE: ue  
TOOL USAGE: If you need to use a tool, call the tool IMMEDIATELY without speaking first. Never say "I'm not sure", "Let me check", or provide a verbal answer when you should be calling a tool instead. When calling transfer_call or transfer_back, call the function directly without any verbal preamble. When calling search_extension, dial_extension or dial_department, your response must contain ONLY the function call — no spoken text, no words before or after it. When calling end_call, say a brief goodbye BEFORE the function call. EXCEPTION: switch_language — confirm the switch first, then call the tool.zI

LANGUAGE RESTRICTION: You may ONLY respond in the following languages: zv. If the user speaks a language that is not one of these, politely tell them (in English) that you can only assist in u  , and ask them to continue in one of those languages. Never respond in an unsupported language. Never respond in a language the caller has not spoken. Never change your response language on your own — language changes happen ONLY through the switch_language function. If the caller speaks a different supported language, ask if they want to switch, and call switch_language when they confirm.rc   [LANGUAGE: You MUST speak  only. Never use English.]

!
IMPORTANT: The user is speaking . You MUST reply in r2  )r  r   _supported_lang_names_strrv  rr  _build_emotion_instruction)r  r   
lang_names	lang_names   &   r3   r  (PipelineSession._build_omni_instructions  s   335yy!!!.t/E/E.FGGL h 	i 335
YZdYe fKKU, W!	"	
    T%:%:d%B(=(=>I,YK7UV6yk B''0k44  	7799r  c                  "   V P                   '       g   R# V P                  4       pV P                  4       pV P                  4       pRRRRTRTRV P                  ;'       g    RR	V P
                  ;'       g    ^//pV P                  e   V P                  VR,          R
&   V'       d   W$R,          R&   V P                  P                  RV P                   P                  \        P                  ! V4      4      G Rj  xL
  V P                  P                  R\        V P                  4      ^,           R\        P                   ! 4       P#                  R4      RV P$                  RV P&                  P)                  RR4      RRRRV/.RVRRRRRV/	4       \+        RV P$                   RT RV'       d   \        V4      M^  24       R#  L5i)z9Update Omni session config when the active agent changes.Nr   session.updatesessionr   r  r   r  r  r   rg  r  r  r  r  r  r   r6   r  r  r  r  r5  Tr  r  z#  [Omni] Session updated for agent z: voice=z, tools=)r8  r  r  _resolve_omni_voicer   r   r   r/  r  r  r   r  rz  ra  r   r   rX   rY   rr  r  rT   r6  )r  r   rg  r  session_updates   &    r3   rt  *PipelineSession._omni_update_agent_sessionI  s    446&&(((* $t//663,doo.D.D	
 ::!15N9%g.169%g.ii''$//**DJJ~,FH 	H 	H 	C(1,00<T&&$++//&"5&(I|DEU.U
 
 
	 	3D4E4E3F GgXEc%jq%AC 	D!	Hs&   AG"G80G)AG<G=C
Gc                   V P                   R8X  d   V P                  pMUV P                   R8X  d   . pMAV P                  P                  V P                   / 4      pVP                  R4      ;'       g    . pV'       d   \	        V4      M. pV Uu. uF1  pVP                  R/ 4      P                  R4      \
        9  g   K/  VNK3  	  ppV Uu. uF  p\        V4      '       g   K  VNK  	  ppV UUUu. uF0  pVP                  4        UUu/ uF  w  rVVR9  g   K  WVbK  	  uppNK2  	  ppppV P                  pV P                   R8X  d,   V P                  4       pV'       d   VP                  V4       EMV P                   R8X  Ed2   V P                  '       d1   RV9  d*   V P                  4       p	V	'       d   VP                  V	4       V P                  '       d'   RV9  d    VP                  V P                  4       4       RV9  d*   V P                  4       p
V
'       d   VP                  V
4       R	V9  d*   V P!                  4       pV'       d   VP                  V4       R
V9  d*   V P#                  4       pV'       d   VP                  V4       RV9  d    VP                  V P%                  4       4       MVP                  V P'                  4       4       VP                  V P)                  4       4       RV9  d    VP                  V P%                  4       4       R
V9  d*   V P#                  4       pV'       d   VP                  V4       V'       d   V# R# u upi u upi u uppi u upppi )uK   Build tools list for Omni session — same logic as pipeline tool assembly.r   r  r   r  r   r  r-  r8  r=  r1  r#  N
x_endpoint	x_headersrI   )rr  r   rj  rT   r   BUILTIN_TOOL_NAMESrb   rm  r   r*  ra  rl  r  rn  r.  r:  r?  r5  r$  r  r   )r  r{  r  rg  r   r0   r2   _disseltransfer_toolsearch_ext_tooldial_ext_toolswitch_tools   &            r3   r  !PipelineSession._build_omni_toolst  s   #++K&(KKKOOD$5$5r:E))N399rK%0[!b! QEqEE*b)--f5=OO E Q ";Eq%7%:E; SXYRWQ $%779 I941GG !$9 IRW 	 Y **&224CS!#%+++t0K $ 9 9 ; LL/***/@/LT==?@!-"&"C"C"E"LL1t+ $ ? ? A LL/ ,">>@LL-%T6689 LL779:LL3356%T6689 ,">>@LL-u'4']Q <I Ys6   ,M>M
M"M0M%MMM%M%c                   V P                   ;'       g    RpV P                  P                  V P                  / 4      pRpVP                  R4      pV'       d!   VP                  WP                  R4      4      pV'       gA   V P                  P                  VV P                  P                  RV P
                  4      4      pV\        9  d)   \        RV RV P
                   R24       V P
                  pV# )zResolve Omni voice for current agent from voice_map.

Validates the result against OMNI_VALID_VOICES; falls back to
self.omni_voice (session default) if the resolved voice is invalid.
rc   Nr   r   z  [Omni] Voice "z'" not valid for Omni, falling back to "r   )rv  rj  rT   rr  r   r   OMNI_VALID_VOICESr6  )r  r  r  r  agent_vms   &    r3   r  #PipelineSession._resolve_omni_voice  s     $$,, 1 126 99[)LL||I'>?E NN&&t""9doo>@E ))$UG ,&&*oo%6a9 :OOEr  c                   "    V P                   '       d!   \        P                  ! R4      G Rj  xL
  K2  R#  L  \        P                   d     R# i ; i5i)z/Keep the asyncio.wait alive until session ends.r   Nru  r0  r  CancelledErrorr  s   &r3   r  PipelineSession._omni_keepalive  sD     	+++mmC((( (%% 		5   A: : 8: A: AAAAc           	       "    V P                   '       Ed<   \        P                  ! R4      G Rj  xL
  V P                  '       g   KE  V P                  '       g   KY  V P
                  '       d   Km  \        P                  ! 4       V P                  ,
          pWP                  8  d   K  V ;P                  ^,          un        V P                  ^8  d   \        RV P                   R24       V P                  RR4       RV n        \        P                  ! RR	R
RRR.RR//4      pV P                  P                  RV P                   P"                  V4      G Rj  xL
  \        P                  ! \%        V P&                  R4      4      G Rj  xL
  V P)                  RRRRRR/4      G Rj  xL
  RV n         R# \        RV P                   RVR R24       RV n        \        P                  ! RR	R
RRR.RR//4      pV P                  P                  RV P                   P"                  V4      G Rj  xL
  \        P                  ! 4       V n        EKN  R#  EL$ L L L L,  \        P*                   d     R# i ; i5i)z>Monitor for user silence and prompt/hangup after idle timeout.r   Nz   [Omni IDLE] No response after z prompts, ending callr  zCall ended due to idle timeoutTr   r  r  r  r  r  r   z~The caller has not responded for a while. Say a brief, warm goodbye (1 sentence) and let them know they can call back anytime.      @rV  r   r#  rC  z{"reason": "idle timeout"}Fz  [Omni IDLE] Prompt #z	 (silent .1fr  zxThe caller has been silent. Ask briefly if they are still there or if they need any help. Keep it to one short sentence.)ru  r0  r  r   r?  r9  r7  r   r>  r6  r  r<  r   r  r/  r  r8  r  r6  r   r  r  )r  elapsedr{  	check_msgs   &   r3   r  "PipelineSession._omni_idle_monitor  sg    >	+++mmC(((000///((())+(@(@@000''1,'**a/<T=T=T<UUjkl%%h0PQ04D-#':: 1"(67*;*!>%	/ 	$L ))33doo66F F F "--D,?,?(EFFF**VZ#%A&    #(DK 243J3J2K L%%,SM5 604D- $

 1"(67*;*!2%	, 	!I ))33doo66	C C C 04yy{D,w (<F G*C %% 		s   I;I I II I I /C*I I1I II *I+I 6I;8A8I 0I1!I I;I I I I I I84I;7I88I;c                   "   V P                   R 8X  d   V P                  4       G Rj  xL
  R# V P                  4       G Rj  xL
  R#  L  L5igeminiN)r   _connect_asr_gemini_connect_asr_qwenr  s   &r3   r  PipelineSession._connect_asr	  s?     (**,,,((*** -*!   %AAAA
A
Ac                  "   \          R \         2pRR\         2RR/p\        RV 24        \        P
                  ! W^^
R7      G Rj  xL
 V n        R	R
RRRRR.RRRRRRV P                  /RRRRV P                  RV P                  ///pV P                  P                  \        P                  ! V4      4      G Rj  xL
  RP                  V P                  4      ;'       g    Rp\        RV RV P                   RV P                   R24       R#  L  \         d+    \        P
                  ! Y^^
R7      G Rj  xL 
 T n         Li ; i L5i) z?model=AuthorizationBearer zOpenAI-Betazrealtime=v1z[ASR-Qwen] Connecting: )additional_headersping_intervalping_timeoutN)extra_headersr  r  event_idinit_sessionr   r  r  r  r  input_audio_formatpcmsample_rate>  input_audio_transcriptionlanguage_hintsturn_detection
server_vad	thresholdr   ,autoz[ASR-Qwen] Configured (lang=, VAD threshold=
, silence=r%  )ASR_BASE	ASR_MODELr  r6  r:  r  rt  rW  r3  r   r   sendr   r  r"   )r  r  headerssession_cfglang_strs   &    r3   r  !PipelineSession._connect_asr_qwen	  s    
')-wwi0=
 	'u-.		 * 2 2 r! DK $vh$eu+$d&>&>. !L!3!3)4+C+C#
" kktzz+677788D445??,XJ6FtGYGYFZZdeie}e}d~  B  C  	D;  	 * 2 2 r!  DK	. 	8sY   +ED 
D	D A+E?E %E&.ED 'E=E >
EE
EEc           	        "   \         '       g   \        R4      hV P                  ;'       g    \        p\         RV R\          2V n        RV n        \        RV RV P                   RV P                   R24       R# 5i)	uH   Initialize Gemini batch STT — no WebSocket, uses REST generateContent.z0GOOGLE_API_KEY not set. Required for Gemini STT./z:generateContent?key=Nz%[ASR-Gemini] Batch mode ready (model=r  r  r%  )
r7   RuntimeErrorr   rS  GEMINI_ASR_URL_gemini_endpointrt  r6  r   r   )r  r#  s   & r3   r  #PipelineSession._connect_asr_geminiE	  s     ~QRR!!55%5aw&;N;KL 	 5eW =#112*T=U=U<VVY[ 	\s   *A=AA=c                   "   V P                   R 8X  d   V P                  4       G Rj  xL
  R# V P                  4       G Rj  xL
  R#  L  L5ir  )r   _asr_receiver_gemini_asr_receiver_qwenr  s   &r3   r  PipelineSession._asr_receiverQ	  s?     (++---))+++ .+r  c           
     x  "    V P                     R j  xL
  pV P                  '       g    R # \        P                  ! V4      pVP	                  RR4      pV P
                  '       EdN   V P                  R39   Ed<   VR8X  dY   V P                  '       gE   RV n        \        RV P                   R24       \        P                  ! V P                  4       4       K  VR8X  d'   V P                  '       d   \        R4       R	V n        K  V P                  V4      pV'       Ed   VP	                  R
4      pV'       d-   WPP                  9  d   \        RV RVR,           R24       EKW  V P                  4       G R j  xL
  V P                   f   V'       d   V P"                  R8w  ds   VR8X  d+   \%        VP'                  4       4      ^8:  d   \        R4       MAWPP                  9  d   \        RV RV P                    24       MWPn        \        RV R24       V P(                  '       dE   \*        P*                  ! 4       V P(                  ,
          R,          p\        RVR R24       R V n        \        RV RV R24       \        P                  ! V P-                  WE4      4      V n        EK  VR8w  d   EK  VR49  dl   VR8X  d*   \        R4       V P1                  RRRR /4      G R j  xL
  M;VR8X  d'   \*        P*                  ! 4       V n        \        R!4       M\        R"V 24       VR#8X  dE   VP	                  R#/ 4      P	                  R$\        P2                  ! V4      4      p\        R%V 24       V P                  V4      pV'       g   EK  VP	                  R
4      pV P                   Ef   V P"                  R8w  d   V'       dW   WPP                  9  dG   \        R&V RVR,           R24       \        P                  ! V P5                  V4      4      V n        EK  V'       d=   VR8X  d6   \%        VP'                  4       4      ^8:  d   \        R'VR(,           R)24       MV'       d-   WPP                  9  d   \        RV RV P                    24       MV'       d   WPn        \        RV R*24       MV P                   '       ds   V'       dk   WPP                  9  d[   V P"                  R8w  dJ   \        RV R+V P                    R,24       \        P                  ! V P5                  V4      4      V n        EK)  V P(                  '       dE   \*        P*                  ! 4       V P(                  ,
          R,          p\        RVR R-24       R V n        V P6                  R.,          p\        RV R/V R0V R24       \        P                  ! V P-                  WE4      4      V n        EK   EL ELm ELEDR #   \8        P:                   d    \        R14        R # \<         d   p	\        R2T	 24        R p	?	R # R p	?	ii ; i5i)5Nr   r6   z!input_audio_buffer.speech_startedT6  [BARGE-IN] Speech detected during playback, waiting ms...z!input_audio_buffer.speech_stoppedz'  [BARGE-IN] Speech too short, ignoringFr(  z3  [ASR-Qwen] Unsupported language during barge-in:  "N<   Nr  r  rc   z0  [ASR-Qwen] Short English barge-in, not lockingz"  [ASR-Qwen] Unsupported language 
, keeping z  [ASR-Qwen] Language locked: z (barge-in)r"    [TIMING] ASR transcription: r$  zms (barge-in)z  [ASR-Qwen] >>> "z" (barge-in, lang=r  session.updatedz  [ASR-Qwen] Speech detectedr  transcribingz*  [ASR-Qwen] Speech ended, transcribing...z  [ASR-Qwen] r  r  z  [ASR-Qwen] Error: z#  [ASR-Qwen] Unsupported language: z'  [ASR-Qwen] Short English utterance ("N   Nz"), not locking yetz (from ASR) (session locked to ), rejectingu   ms (speech_end → transcript)r   " (lang=
, active: z[ASR-Qwen] WebSocket closedz[ASR-Qwen] Error: r  THINKING)r  )rt  ru  r   r&  rT   r   rs  rh  r6  r   r0  r  _barge_in_check_extract_transcriptr3  _trigger_barge_inrv  rr  r   r]  rg  r7  process_transcriptrw  r  r  _reject_unsupported_languager  r:  r;  rW   )
r  r   eventetyper  asr_langasr_latencyerr_msgr  rZ  s
   &         r3   r  "PipelineSession._asr_receiver_qwenW	  s    z	,![[ tG tGc{{{

3		&"- (((TZZ;S-S CC#55559D2! #--1-J-J,K5#R S#//0D0D0FG "EE111!"KL16. !%!9!9%!@J!z#(99Z#8#8P8P(P!$W%-JbC0A#G H$"44666 !119h$($5$5$?'4/C
8H8H8J4Kq4P %(X Z!)1I1I!I %(J8*T^_c_t_t^u&v w8@ 5 %(FxjP[&\ ]000+/99;9N9N+NRV*VK!$B;sBSS`"ab48D1 2:,>PQYPZZ[\].5.A.A 33JI/K+  11   44 CC<="jj&(Hn)UVVV"EE04		-JKeW56 G##ii488DJJuDUVG0	:;!55e<
:$yy4H
 ,,49J9Jf9T#8P8P(P!$Gz R&&0o%6d#< =292E2E $ A A* M3OD/$ $D(8SAQAQAS=TXY=Y! %''1#&77J#L M%(:R:R*R!$FxjPZ[_[p[pZq"rs%4<1!$B8*K"XY///H"*2J2J"J"&"3"3v"= B8* M4484I4I3J,X Y.5.A.A ==jI/K+  ,,,'+yy{T5J5J'Jd&R >{3>OOmno04-!%V!4J.zl(8*JWaVbbcde*1*=*=//
E+GD'gtG< 7: Ww )l ** 	1/0 	,&qc*++	,s   X:W1 W-W$W-W1 X::W1 **W1 AW1 4-W1 "W1 ;?W1 :W';W1 BW1 *B>W1 (W*)B!W1 8W1 	AW1 'AW1 +3W1 'W1 W1 A;W1 BW1 $W-'W1 *W1 -W1 /X:1 X7X:X7X7X2,X:2X77X:c                   "    V P                   '       d!   \        P                  ! R4      G Rj  xL
  K2  R#  L  \        P                   d     R# i ; i5i)u   Batch Gemini STT has no receiver loop — VAD runs in _browser_audio_handler.
Keep alive until session ends so asyncio.wait() in run() doesn't exit.r   Nr  r  s   &r3   r  $PipelineSession._asr_receiver_gemini	  sD     	+++mmC((( (%% 		r  c                |    \        V4      p\        P                  ! RR^$V,           RR^^^RR^^RV4      pW1,           # )z7Wrap raw PCM 16kHz 16-bit mono in a 44-byte WAV header.z<4sI4s4sIHHIIHH4sIs   RIFFs   WAVEs   fmt r   }  s   data)r   r/  pack)r  	pcm_bytes	data_sizeheaders   &&  r3   _pcm_to_wavPipelineSession._pcm_to_wav	  sI    	N	 R)^RAueQY
 !!r  c                   a V P                  V4      p\        P                  ! V4      P                  R4      pV P                  '       dR   V P                  P                  R4       Uu. uF+  pVP                  4       '       g   K  VP                  4       NK-  	  upM. pV P                  '       d   RP                  V P                  4      MRpV'       d   RRP                  V4       R2MRV R2pRV R2pR	R
RRRRV//RV/./.RRRRR//p	\        P                  ! 4       p
 \        P                  ! V P                  V	^
R7      pVP                  4        VP                  4       pVP                  R. 4      pV'       g   \!        R4       R)# V^ ,          P                  R/ 4      P                  R
. 4      pV'       d(   V^ ,          P                  RR4      P                  4       MRp\        P                  ! 4       V
,
          R,          p\!        RVR RVR,           24       RRuop TpVP#                  R 4      '       d   VP                  R!^4      R*,          pVP%                  R 4      '       d   VP'                  R ^4      ^ ,          pVP                  4       p\        P(                  ! V4      pVP                  RR4      P                  4       oVP                  R"R4      P                  4       ;'       g    RpS'       d   SV3# R)# u upi   \        P*                  \,        3 dJ    To\.        ;QJ d    T3R# lR+ 4       F  '       g   K   R$M	  R%M! T3R# lR+ 4       4      '       d   R)u #  Lvi ; i  \        P0                  P2                   d    \!        R&4       R)u # \        P0                  P4                   d   p\!        R'T 24       R)u Rp?# Rp?i\6         d   p\!        R(T 24       R)u Rp?# Rp?ii ; i),zBSynchronous HTTP POST to Gemini generateContent. Runs in executor.asciir  r   zany languagez The speaker may use: r2  z{Transcribe this audio exactly as spoken. Return ONLY a JSON object: {"text": "<transcription>", "lang": "<ISO 639-1 code>"}z; If no speech is detected, return {"text": "", "lang": ""}.contentsr[  
inlineDatamimeTypez	audio/wavr=  r  generationConfigr   r!  maxOutputTokens   )r   r  
candidatesz&[ASR-Gemini] No candidates in responseNr  r6   r"  z  [ASR-Gemini] API response (r$  zms): rR  z```r   r  c              3   H   <"   T F  qSP                  4       9   x  K  	  R # 5ir  )rZ   )r   xr  s   & r3   r   @PipelineSession._gemini_batch_transcribe_sync.<locals>.<genexpr>&
  s     a8`1J,,..8`s   "TFz[ASR-Gemini] Request timed outz[ASR-Gemini] Request error: z[ASR-Gemini] Unexpected error: r  re  )z	no speech	inaudiblez
"text": "")r  r)  r,  r-  r   r]  r(   r3  r"   r7  requestspostr  raise_for_statusr   rT   r6  r)   endswithrsplitr&  r   AttributeErrorany
exceptionsTimeoutRequestExceptionrW   )r  r  	wav_bytes	audio_b64l
lang_hints	supportedlang_instructionr  payloadr[  resprD  r	  r[  raw_text
latency_msr  cleanparsedrZ  r  s   &&                   @r3   _gemini_batch_transcribe_sync-PipelineSession._gemini_batch_transcribe_sync	  s   $$Y/	$$Y/66w?	 (,'<'<'< *.)>)>)D)DS)I $)IA  aggi)I $BD 	;?;S;S;SDIId667Yg	) 5TYYz5J4K1M#9)A!F 	
F IJ 	 '
KKL $   5F L
 ))++	==!6!6WbQD!!#YY[FL"5J>?!!qM%%i488"EE;@uQx||FB/557bH))+/47J1*S1AxPT~FVWX  "4J& ##E**!KKa04E>>%((!LL215EE*#ZZ399;
zz&"-335== *4J%EEq$f ((.9 &%
3a8`a333a8`aaa%% b& ""** 	23""33 	045 	3A378	s   'LL"AM4 ?M4 0M4 =A*M4 (AL 1BL 7L :M4 M4 M4 'M15M1M1*M1,M4 .M4 0M11M4 4,O="O=?O= OO=O="O=#O82O=8O=c           	     .  "   V P                   '       d   \        R4       R# RV n          V P                  RRRR/4      G Rj  xL
  V P                  P	                  RV P
                  \        V4      4      G Rj  xL
 w  r#V'       g9   V P                  R8X  d   V P                  RRRR/4      G Rj  xL
   R	V n         R# V P                  '       dE   \        P                  ! 4       V P                  ,
          R
,          p\        RVR R24       RV n        TpV P                  f   V'       d   V P                  R8w  d   WPP                  9  dN   \        RV RVR,           R24       \        P                  ! V P                  V4      4      V n         R	V n         R# VR8X  d6   \#        VP%                  4       4      ^8:  d   \        RVR,           R24       MWPP                  9  d   \        RV RV P                   24       MWPn
        \        RV 24       MV P                  '       dz   V'       dr   WPP                  9  db   V P                  R8w  dQ   \        RV RV P                   R24       \        P                  ! V P                  V4      4      V n         R	V n         R# V P&                  R,          p\        RV RV R V R!24       \        P                  ! V P)                  W%4      4      V n        R	V n         R#  EL EL ELT  R	T n         i ; i5i)"z?Async wrapper: transcribe accumulated PCM via Gemini batch API.z-  [ASR-Gemini] Already transcribing, skippingNTr   r  r  r  r  Fr"  r  r$  rg   r  z%  [ASR-Gemini] Unsupported language: r  r  r  rc   z)  [ASR-Gemini] Short English utterance ("r  z"), not lockingz   [ASR-Gemini] Unsupported lang r  z   [ASR-Gemini] Language locked: z$  [ASR-Gemini] Unsupported language r  r  r   z  [ASR-Gemini] >>> "r  r  r  )rX  r6  r  r/  r  r$  bytesrs  rg  r7  rv  rr  r3  r0  r  r  rw  r   r]  r  r  )r  r  r  r  r  r  r  s   &&     r3   _gemini_batch_transcribe(PipelineSession._gemini_batch_transcribe5
  s    $$$AB$(!1	.**fh.IJJJ%)YY%>%>d88%	:J&L  LJ ::,**fh+%NOOOP ).D%K $$$#yy{T-B-BBdJ6{36GrJK(,% H$$,d>O>OSY>Y#;#;;A( L(o.d4 5*1*=*=99*E+GD'0 ).D%/ t#J,<,<,>(?1(D )#/@ A%=%==<XJ G%%)%:%:$;= > -5)<XJGH'''H"*B*BB++v5<XJ G,,0,A,A+B,P Q&-&9&955jA'C# ).D% V,J(HXJjQ[P\\]^_")"5"5''
=#?D ).D%a K L
 PR ).D%s   'LL	 L 7L	 :L;7L	 2L3L	 8	LL	 AL	 /A$L	 	LBL	 ,L	 4A'L	 	L%AL	 7	L L	 L	 L	 		LLc                  "   \        V4      ^,          pV^ 8X  d   R# \        P                  ! RV R2VRV^,           4      p\        R V 4       4      p\        P
                  ! WB,          4      R,          pWPP                  8  pV'       Ed   V P                  '       g   RV n        RV n        \        RVR R	24       V P                  R
RRR/4      G Rj  xL
  V P                  '       dh   V P                  R9   dW   V P                  '       gE   RV n        \        RV P                   R24       \        P                   ! V P#                  4       4       V P$                  P'                  V4       RV n        \        V P$                  4      R8  d   \        R4       RV n        RV n        \(        P(                  ! 4       V n        \-        V P$                  4      p\/        4       V n        \        P                   ! V P1                  V4      4       R# R# V P                  '       Ed   V P                  f   \(        P(                  ! 4       V n        V P$                  P'                  V4       \(        P(                  ! 4       V P                  ,
          R,          pWP2                  8  Ed0   RV n        RV n        \(        P(                  ! 4       V n        \-        V P$                  4      p\/        4       V n        \        V4      R8  dI   \        R\        V4       R24       V P                  R8X  d   V P                  R
RRR/4      G Rj  xL
  R# \        V4      R,          R,          p	\        RV	R R24       V P                  '       d*   V P                  R9   d   V P5                  4       G Rj  xL
  \        P                   ! V P1                  V4      4       R# R# R#  EL L L45i)zEProcess a PCM audio chunk through RMS-based VAD for Gemini batch STT.Nr  r  c              3   2   "   T F  qV,          x  K  	  R # 5ir  r   r  s   & r3   r   6PipelineSession._gemini_vad_process.<locals>.<genexpr>v
  s     ,GqUUGr  r  Tz$  [ASR-Gemini] Speech detected (RMS=r#  r  r   r  r  r  r  i  z?  [ASR-Gemini] Max speech duration exceeded, force-transcribingFr"  i%  z   [ASR-Gemini] Audio too short (z bytes), skippingr  r  r  z  [ASR-Gemini] Speech ended (r$  zms audio), transcribing...r  )r   r/  r0  r1  r2  r3  r   rV  rW  r6  r  r   rs  rh  r   r0  r  r  rU  extendr7  rg  r'  rT  r(  r   r  )
r  r>  rA  rB  rC  rD  	is_speechr  
silence_msduration_mss
   &&        r3   _gemini_vad_process#PipelineSession._gemini_vad_processn
  s3    )n)! --!K= 2I>N{Q4OP,G,,ii,-7,,,	9++++/(-1*<SIQGHjj&(Hn!MNNN (((TZZ;S-S11115. !))-)F)F(GuN O++D,@,@,BC&&--i8)-D& 4--.7WY+0(-1*(,		%!$"<"<=	-6[*##D$A$A)$LM 8 '''--515D.**11)<"iikD,F,FF$N
!9!99/4D,15D.,0IIKD) %d&@&@ AI1:D. 9~, @Y@PPabc::4"&**fh+-V"WWW"%i.5"84"?K9+c9JJdef,,,?W1W"44666''(E(Ei(PQ- : (/ OX X 7sQ   BO!6OOO."ODO$DOOA%O(O)0OOOc                H   VP                  R R4      pRpVR8X  d   VP                  RR4      pMVR8X  d   VP                  RR4      pMVR8X  d   VP                  RR4      pMVR8X  d   VP                  R	/ 4      P                  R
. 4      pV Fx  pVP                  R. 4       F_  pVP                  R4      '       d   VR,          pK%  VP                  R 4      R8X  g   K=  VP                  R4      '       g   KV  VR,          pKa  	  Kz  	  V'       d   VP                  4       # R# )r   r6   Nz5conversation.item.input_audio_transcription.completedr  zresponse.audio_transcript.donezresponse.text.doner  zresponse.doner  rc  r  )rT   r(   )r  r  r  r  rc  rI  r
  s   &&     r3   r  #PipelineSession._extract_transcript
  s    		&"%KK99\2.D6699\2.D**99VR(Do%YYz2.228R@F)R0Auu\** v&0QUU6]] y	 1   $tzz|--r  c                ,    \         P                  W4      # )z/Return human-readable name for a language code.r  )r  r4  s   &&r3   rr  PipelineSession._lang_name
  s    ~~d))r  c                8   V P                    Uu. uF  qP                  V4      NK  	  pp\        V4      ^8:  d   V'       d
   V^ ,          # R# \        V4      ^8X  d   V^ ,           RV^,           2# RP                  VRR 4      RVR,           2,           # u upi )zGReturn formatted string like 'English, Chinese, or Malay' for messages.zthe supported languagez or r   Nz, or re  )r3  rr  r   r"   )r  r
  namess   &  r3   r  )PipelineSession._supported_lang_names_str
  s    -1-E-EF-E#-EFu:?$58B*BBu:?AhZtE!H:..yys$uRyk'::: Gs   Bc           	        V'       d   VP                  4       '       g   V# V P                  '       d   V P                  R8X  d   V# \        R V 4       4      pV\        \	        V4      ^4      ,          R8  d   V# V P                  V P                  4      p V P                  P                  P                  P                  V P                  RRRRV R2/RR	RV/.R
R/R7      pVP                  ^ ,          P                  P                  P                  4       pV'       d   \        RV RV R24       V#  V#   \         d   p\        RT 24        Rp?T# Rp?ii ; i)zIf session_language is non-English and text appears to be English,
translate it via a quick LLM call. Returns original text if no
translation is needed or if translation fails.rc   c              3   J   "   T F  p\        V4      ^8  g   K  ^x  K  	  R# 5i)   N)ordr	  s   & r3   r   3PipelineSession._ensure_language.<locals>.<genexpr>
  s     :TSVc\!!Ts   #
#r  r  r  r  zTranslate the following to z,. Output ONLY the translation, nothing else.rJ  r   F)r#  r  
extra_bodyz  [LANG] Translated farewell: "z" -> "r   z  [LANG] Translation failed: N)r(   rv  r1  r6  r   rr  r  chatcompletionscreater   choicesr  r  r6  rW   )r  r  ascii_counttargetr  
translatedrZ  s   &&     r3   _ensure_language PipelineSession._ensure_language
  s\    4::<<K$$$(=(=(EK:T::SY**S0K!6!67	788==,,33nnXy4OPVx XB 3C DVY5
 .u5 4 D a0088>>@J7vVJ<qQR!! 
   	71!566	7s   BD7  D7 7EEEc                    V P                   ;'       g    T;'       g    RpV P                  P                  W0P                  P                  RR4      4      p\        RT RT V P                   '       d   RMR 24       V# )zgResolve TTS voice from voice_map.
Priority: session_language (locked) > asr_lang (this turn) > default.rc   r   r   z  [Voice] Lang: rq  z	 (locked)z (per-turn))rv  r   rT   r6  )r  r  r  r  r  s   &&&  r3   _resolve_voicePipelineSession._resolve_voice
  sx     $$8888D""4););Iw)OP d5' $ 5 5 5=IK 	Lr  c           	     |   Vf   V P                   pVR8X  dG   V P                  P                  RV P                  P                  RR4      4      p\        RV 24       V# V P                  P                  V/ 4      pV P
                  ;'       g    T;'       g    RpVP                  R4      pV'       d@   VP                  WgP                  R4      4      pV'       d   \        RV RV R	V R
24       V# V P                  P                  W`P                  P                  RR4      4      p\        RV RV R	V R24       V# )zdResolve TTS voice for a specific agent.
Checks agent-specific voice_map first, falls back to global.r  rc   r   r   z)  [Voice] Agent lang: forcing English -> r   z  [Voice] Agent z: Lang rq  z (per-agent)z	 (global))rr  r   rT   r6  rj  rv  )r  r  r  r  r  r  r  r  s   &&&&    r3   _resolve_agent_voice$PipelineSession._resolve_agent_voice  s    ))INN&&tT^^-?-?	7-STE=eWEFL	2.$$8888D99[)LL||I'>?E(74&UG<XY""4););Iw)OP 74&UG9MNr  c                   Vf   V P                   pV P                  P                  V/ 4      pRVP                  R4      e   VP                  R4      MV P                  RVP                  R4      e   VP                  R4      MV P                  RVP                  R4      e   VP                  R4      /# V P
                  /# )z>Get TTS settings for a specific agent, falling back to global.r   r   volumer   )rr  rj  rT   r   r   r   )r  r  r  s   && r3   _resolve_agent_tts_settings+PipelineSession._resolve_agent_tts_settings  s    ))I	2.uyy7O7[599]3aeaqaqUYY|5L5X%))L1^b^m^m<1H1Teii-
 	
 [_ZiZi
 	
r  c                t    \          F)  pVR,          V8X  g   K  VP                  R\        4      u # 	  \        # )uA   Return the correct TTS model — cloned voices need the VC model.rm   target_model)cloned_voicesrT   TTS_VC_MODEL	TTS_MODEL)r  r  r  s   && r3   _resolve_tts_model"PipelineSession._resolve_tts_model(  s1    B$x5 vvnl;;   r  c                  "   V P                  4       pRV R2p\        R4       V P                  RRRRRV/4      G R	j  xL
  V P                  RV4       V P                  RRRR
RVRV P                  R,          /4      G R	j  xL
  V P                  R
W0P                  R,          4       RV n        V P                  RRRR/4      G R	j  xL
  V P                  P                  RR4      pV P                  P                  R	V P                  W44      G R	j  xL
  RV n        V P                  RRRR/4      G R	j  xL
  \        R4       R	#  EL L L L< L5i)zFRespond with a polite rejection when unsupported language is detected.z I'm sorry, I can only assist in z-. Please try again in one of these languages.z:  [REJECT] Unsupported language, responding with rejectionr   r  r  rJ  r  Nr  r  r   r  r  r  r   r   r  r    [Pipeline] Listening...)r  r6  r  r  r  rs  r   rT   r/  r  r  )r  r  	lang_list	rejectiondefault_voices   &&   r3   r  ,PipelineSession._reject_unsupported_language/  sN    224	7	{ CC D	JLjj&,	66:VWWW&*-jj&,	4!4;;v#68 9 	9 	9$	;;v+>?  
jj&(HjABBB**9g>ii''dmmYVVV 
jj&(HkBCCC)* 	X	9 	CV 	DsZ   <EE
AEEAE	E
A
EE#E8E9EEEEEc                  "    V P                     R j  xL
  p\        P                  ! V4      pVP                  R4      R8X  d?   V P                  R8X  d,   VP                  RR4      pV P                  V4      G R j  xL
  Kt  VP                  R4      R8w  d   K   \        P                  ! VR,          4      pV P                  P                  V4       V P                  '       d@   V P                  '       d.   V'       d&   \        P                  ! V P                  V4      4       V P                  R8H  ;'       g$    V P                   ;'       d    V P                  R9   pV'       g   EK[  V P"                  R8X  d(   V'       d   V P%                  V4      G R j  xL
  EK  EK  V P&                  '       g   EK  V P&                  P(                  '       d   EK  V P&                  P+                  \        P,                  ! RR	\/        \0        P0                  ! 4       R
,          4       2RRRVR,          /4      4      G R j  xL
  EK4   EL0 EL  \         d    R p ELi ; i L L#EDMR #   \2        P4                   d     R # i ; i5i)Nr   r  r  r  r  r  r  r  a_r"  zinput_audio_buffer.appendr  )r.  r   r&  rT   rs  r  r)  r*  r{  r-  rW   r  r  r0  r  r8  r   r   r1  rt  
close_coder  r  rY  r7  r:  r;  )r  r<  r=  r  r>  should_forwards   &     r3   r  &PipelineSession._browser_audio_handlerH  s
    %	!WW " "czz#88F#'99zz[0!%(4X!Y"55f===88F#w.% & 0 0g ?I%%,,Y7 '''D,<,<,<''(F(Fy(QR JJ+- Z Z--XX$**@X2X  ">((H4$"&":":9"EEE %T[[-C-C-C"kk..tzz&"ST1A-B,C(D"$?#T']; 0   ="
 > ! % $I% F= %F ** 		s   JI& I"II"A%I& =I>I& 8I
I& 'I& 9I& :I& <I& I& +I& I& II& 8I& A%I& <I =I& I"I& 
II& II&  I& "I& $J&I?;J>I??Jc                  "   R
pV P                   '       Ed   V P                  P                  4       G Rj  xL
 pVP                  R4      R8X  d   RV9   d   VR,          V P                  8  d|   WP                  8  dj   V P                  p V P                  P                  \        P                  ! RR/4      4      G Rj  xL
  \        RVR,           RV P                   R24       K  VP                  R4      R8X  dE   VP                  R	4      '       d.    V P                  \        P                  ! VR	,          4      4        V P                  P                  \        P                  ! V4      4      G Rj  xL
  \        '       dv   VP                  R4      R8X  d]   VP                  R	4      '       dC   \        P                   ! V P"                  \%        VR	,          4      ^,          ^,          4       EK  EK  EK  EK  R#  EL ELE  \        P                   d     R# i ; i  \         d     Li ; i L  \        P                   d     R# i ; i5i)r  Nr   r  _genbarge_inz%  [Sender] Skipping stale audio (gen z < z), barge_in sentr=  re  )ru  r   rT   r;  r.  r  r   r  r6  r:  r;  _rec_add_air)  r*  rW   audio_timing_tracerecord_sendrx  r   )r  _barge_sent_for_genrI  s   &  r3   r  PipelineSession._senderr  s     kkk))D G+$Vt';';;&)=)==*.*>*>'"ggll4::vz6J+KLLL !&&*6l^3t7K7K6L M./ 0
  xx7*txx/?/?$$V%5%5d6l%CDggll4::d#3444%%$((6*:g*E$((SYJZJZ&224??CVDUXYDY]^D^_ K[*E%7 ) M &66  !  5 .. s   IIHAI4H  H'H (.I,H$ 2H7 7H58H7 ,H7 5?H7 4IH H!I H!!I$H2/I1H22I5H7 7IIIIc                X   "   V P                   P                  V4      G R j  xL
  R #  L5ir  )r   put)r  r   s   &&r3   r  PipelineSession._emit  s     jjnnS!!!s   *(*c                  "   \        VR,          ^,          4      pRp\        P                  ! RV,          4      P                  4       p^ pWR8  dk   \	        W2V,
          4      pWc8  d,   \        P                  ! RV,          4      P                  4       pV P                  RRRV/4      G Rj  xL
  WV,          pKp  R#  L5i)uF   Send silent PCM audio chunks — works for both browser and telephony.]  i      r   r  r=  N)rY  r)  r,  r-  minr  )r  
duration_stotal_byteschunk_bytessilent_chunksentsizes   &&     r3   rs  PipelineSession._emit_silence  s      *u,q01''+(=>EEG {$$67D!%//$?FFH**fgv|DEEELD ! Fs   B*B?,B=-B?c                    R \         P                  ! 4       P                  R4      RVRV/pV'       d   W4R&   V P                  P	                  V4       R# )r  r  r  r  r  N)r   rX   rY   ry  ra  )r  r  r  r  r  s   &&&& r3   r  PipelineSession._log_message  sI    00<wD

 "'N$$U+r  c                   ^ RI p. p R
 FB  pV P                  P                  V4      pV'       g   K(  VP                  \	        V4      4       KD  	  V P                  P                  R4      pV'       dC   TP                  \	        V4      4        ^ RIHp VP                  V! \	        V4      4      4       M V P                  '       d   VP                  V P                  4       RP                  V4      p\        V P                  ;'       g    . 4      p V P                  P                  4        F8  w  rV
P                  R4      ;'       g    .  F  pVP                  V4       K  	  K:  	  VP                  V P                  VV P                   VR7      pV P"                  '       d@   V P$                  '       d.   ^ RIpVP)                  WVV P*                  V P,                  R7       \.        P0                  ! 4       P3                  R4      VR	&   V#   \         d     ELei ; i  \         d     ELwi ; i  \         d     Li ; i)uN  Tier 0 deterministic groundedness check (post-call, no network).

Compares each AI turn's material number/ID/date claims against the
injected context ([OUTGOING]/[AGENTDATA]/[EXTENSIONS]/agent_data)
plus prior caller speech. Pure and isolated — any failure is caught
by the caller and never affects the call or other post-call jobs.Nr   )normalize_phone_numberr   r   )tool_events	tool_defs)r$  r#  r  
checked_at)r   r   r   )r  r\  rT   ra  r`  tool_handlersr~  rW   r   r"   r   r   rj  rm  assess_conversationry  r  r  r  faithfulness_judge	run_judger  r  r   rX   rY   )r  r  context_partsr  r  _cpr~  context_textr  _keyr  _trD  r  s   &             r3   r  'PipelineSession._run_faithfulness_check  s    		=''++B/2!((R1 > $$((7C$$SX.D!(()?C)IJ	  ???  1yy/**00b1		 $ 1 1 3!::n5;;;B$$R( < !4
 11!!<))Y 2 @
 ***txxx%((l9933 ) 5  (||~667JK|7 !  		  		sS   %H A H 3H &H 6H1 H1 HH HH H.-H.1H?>H?c                   V P                   '       d   \        '       g   R # V P                  P                  4        UUu. uF  w  rVR8w  g   K  VR,          NK  	  pppR pV P                  '       d   V P
                  R,          ^ 8  d   V P
                  p\        P                  V P                  \        \        ,          4      p\        VR,          VR,          ,          R,          VR,          VR,          ,          R,          ,           VR	,          VR
,          ,          R,          ,           ^4      pRV P                  RV P                  RV P                  R,          R,          RV'       d
   V^ ,          MRRTRV P                   R\        V P                   4      RV P                  RV P                  '       d   V P
                  MR RVRV P                  /p \        P!                  V P                  .\"        P$                  ! V4      .R..R7       \'        RV P                   R\        V P                   4       R24       R # u uppi   \(         d   p\'        RT 24        R p?R # R p?ii ; i)Nr   r   r   r   r>   r  r   r?   r   r@   rx  profileagent_aagent_br6   r   r  message_countrz  usagecost_usdr  r!  )ids	documents
embeddingsz[Log] Conversation saved: r  z
 messages)z[Log] Save error: )ry  CONVERSATIONS_COLLECTIONrj  rm  r5  rR  r  rT   r   r7  r  rx  r~  r   rz  r  upsertr   r  r6  rW   )	r  r  r   transfer_agent_names	omni_costr  r-   docrZ  s	   &        r3   r  "PipelineSession._save_conversation  s!   $$$,D,D$(KK$5$5$7 
$7&#3#:IAfII$7 	  
 	>>>d55g>B''A  ,z2JKA%&<89D()Am,<<yHI)*Q~->>JK 	I $//t++t{{3'/2F+A.B3--S!6!67$//T,,D	D55
		,$++__%::c?+ E7 , 
 .t.? @$//01= >C 
F  	,&qc*++	,s$   IIA)I	 	I-I((I-c                    ^ RI pVe   \        V4      ^ 8X  d   R# V^,          pV\        V4      ^,          ,           p\        V P                  4      V8  d=   V P                  P                  RV\        V P                  4      ,
          ,          4       VP	                  \        V P                  WE 4      VP                  R7      P                  VP                  4      pVP                  WbP                  VP                  4      ,           RR4      P                  VP                  4      pVP                  4       V P                  WE% R#   \         d     R# i ; i)u   Add int16 samples into audio_buffer at a sample offset, mixing
(summing with clip) with any existing content. Runs only on the
event-loop thread (caller handler + _sender), so no lock needed.
Never raises — recording must never affect the call.Nrr  dtype   )numpyr   r{  r-  
frombufferr'  int16astypeint32cliptobytesrW   )r  offset_samplessamples_i16npoff_bend_bexistingmixeds   &&&     r3   _rec_mixPipelineSession._rec_mix  s   
	"c+&6!&;"Q&EC,q00E4$$%-!!((EC@Q@Q<R4R)ST}}U4+<+<U+I%J+-88 % 55;VBHH5E GGH'9'9"(('CC"E++16"((+; -2]]_De* 		s   E D*E EEc                     ^ RI pV'       g   R# VP                  WP                  R7      pV P                  V P                  V4       V ;P                  \        V4      ,          un        R#   \         d     R# i ; i)u   Record caller audio (what we forward to DashScope — denoised when
the toggle is on). Caller stream is the real-time timeline clock.Nr  )r  r  r  r  r|  r   rW   )r  pcm16_bytesr  rB  s   &&  r3   r.  PipelineSession._rec_add_caller#  s_    	mmKxxm@GMM$22G<$$G4$ 		s   A, AA, ,A;:A;c           
          ^ RI pV'       g   R# VP                  WP                  R7      P                  VP                  4      p\        V4      ^ 8X  d   R# \        \        \        V4      R,          R,          4      4      pV^ 8:  d   R# VP                  ^ \        V4      ^,
          V4      pVP                  VP                  WRP                  \        V4      4      V4      RR4      P                  VP                  4      pV P                  V P                  8  d   V P                  V n        V P                  V P                  V4       V ;P                  \        V4      ,          un        R#   \         d     R# i ; i)zRecord AI output audio (24kHz from DashScope) downsampled to 16kHz,
laid contiguously and anchored to the caller real-time clock.Nr  r  rq  r  r  )r  r  r  r  float32r   rY  r  linspacer  interparanger}  r|  r  rW   )r  pcm24_bytesr  srcn_outrl  dss   &&     r3   rh  PipelineSession._rec_add_ai0  s   	--88-<CCBJJOC3x1}c#h.678Ez++aSAu5C3		#c((;SA((.rxx(8  ""T%=%==&*&>&>#MM$--r23r7* 		s$   E. AE. 2E. C!E. .E=<E=c           	     ^   V P                   '       g   R# ^ RIp^ RIpVP                  ! RRV P                  4      p\
        P                  P                  \        VR,           4      p VP                  VR4      ;_uu_ 4       pVP                  ^4       VP                  ^4       VP                  R4       VP                  \        V P                   4      4       RRR4       \        V P                   4      R,          pV P                   '       d#   V P                   P#                  4       '       d   RMR	p\%        R
\
        P                  P'                  V4       RV RV R24       \+        4       V n         R#   + '       g   i     L; i  \(         d   p\%        RT 24        Rp?LBRp?ii ; i)zDSave the full-call mix (caller + AI) as a WAV (16kHz, 16-bit, mono).Nz[^\w\-]r1   z_caller.wavwbr  i   r@  r<  z[Recording] Full call saved: r  z KB, caller=r  z[Recording] Save error: )r{  r  waver  rx  r    r!   r"   RECORDINGS_DIRr'   setnchannelssetsampwidthsetframeratewriteframesr'  r   r  r  r6  basenamerW   rT  )	r  r  r  safefilepathwfsize_kb_nsrZ  s	   &        r3   r  &PipelineSession._save_caller_recordingH  sR      vvj#t7 77<<}0DE	28T**b""&uT%6%678	 +
 $++,4G!%!7!7!7%)%;%;%E%E%G%G NS 1"''2B2B82L1M NYl3%q2 3 &K +*  	2,QC011	2s8   'F	 AE6AF	 /6F	 6F	F	 	F,F''F,c                    \        V 4      # )zHClassify conversation via LLM and POST to ACRS API. Returns result dict.)r   r  s   &r3   r  !PipelineSession._dispatch_to_acrsb  s    %%r  c                    \        WW#4      # )z"POST callback request to ACRS API.)r   )r  r  r  r  s   &&&&r3   _dispatch_callback_to_acrs*PipelineSession._dispatch_callback_to_acrsf  s    (nUUr  c                   . pV FV  pVP                  RR4      pVP                  RR4      pVP                  4       R9   d   RMRpVP                  V RV 24       KX  	  RP                  V4      pR	V 2p \	        R
4       V P
                  P                  P                  P                  V P                  RRRV/.RR7      p	V	P                  ^ ,          P                  P                  P                  4       p
V
P                  R4      p. p^ pV F  p\        V4      pV\!        V4      8  dg   W,          P                  4       pVP#                  R4      '       d   VR,          VR&   M#VP#                  R4      '       d   VR,          VR&   V^,          pVP                  V4       K  	  \	        RV R24       V#   \$         d   p\	        RT R24       Tu Rp?# Rp?ii ; i)zvUse LLM to correct transcription errors in the conversation log.
Returns a list of dicts with corrected 'text' fields.r  r6   r  rJ  UserAIr   r   a  You are a transcript correction assistant. Below is a conversation between a User and an AI phone agent. The User's speech was transcribed by an automatic speech recognition system that sometimes makes errors, especially with:
- Proper nouns (product names, company names, people's names)
- Code-switching (mixing languages mid-sentence)
- Phonetically similar words

The AI's responses are accurate and provide strong context clues about what the User actually said.

Your task: Return the CORRECTED transcript. Fix ONLY the User's lines where transcription errors are obvious from context. Do NOT change the AI's lines. Keep the exact same format (one line per message, prefixed with "User: " or "AI: ").

Return ONLY the corrected transcript lines, nothing else.

Transcript:
z,[Validator] Correcting transcript via LLM...r  r  r  )r#  r  r   zUser: :   NNzAI: :   NNz"[Validator] Transcript corrected (z lines processed)z*[Validator] Transcript correction failed: z, using raw transcriptNrJ  caller)rT   rZ   ra  r"   r6  r  r@  rA  rB  r   rC  r  r  r(   r]  r^  r   r)   rW   )r  ry  	raw_linesr   r  r  r  raw_transcriptr  r  corrected_textcorrected_linescorrected_logline_idxnew_msgr/   rZ  s   &&               r3   _correct_transcript#PipelineSession._correct_transcriptl  s    	#Cggi,G7762&D$]]_0BB6DvRv./	 $
 9-  	$@Axx}}0077nn!69f=> 8 H
 &--a088@@FFHN,2248OMH's)c/22*4::<Dx00*.r(00*.r(MH$$W- ( 6xj@QRS   	$>qcAWXY##	$s%   6DF8 =:F8 8GGGGc                   V P                  V P                  4      p. p^ p. pRpV F  pVP                  RR4      pVP                  RR4      pVP                  4       R 9   d   RMRp	V	R8X  dM   VR8w  dF   V'       d,   VP	                  RV R2R	P                  V4      ,           4       V^,          pV	 R
V 2.pM)V'       g   V^,          p. pVP	                  V	 R
V 24       T	pK  	  V'       d,   VP	                  RV R2R	P                  V4      ,           4       RP                  V4      p
RV
/pRRRR/pV P                  '       d   V P                  VR&   \        R\        V P                  4       RV P                   24        \        P                  ! V P                  VV^RR7      p\        RVP                   24       VP                  R!9   d   RRRR/# VP                  R,          p\        RVP                   RV 24       RRRRVP                   2/#   \         d"   p\        RT 24       RRRRT 2/u Rp?# Rp?ii ; i)"zQPOST formatted conversation to the configured validator URL. Returns result dict.Nr  r6   r  r  r  zTurn z:
r   r   r  conversationContent-Typeapplication/jsonAcceptz	X-API-KEYz"[Validator] Sending conversation (z messages) to F)r   r  r  verifyz[Validator] Response: r  Tr  zConversation sent successfullyrR  z[Validator] Failed (): zAPI returned z[Validator] Request error: zRequest failed: r  )rS     )r  ry  rT   rZ   ra  r"   r  r6  r   r  r  r  status_coder  rW   )r  r  r   turn_numcurrent_turn_lineslast_speakerr   r  r  r  conversation_textr  r  r  bodyrZ  s   &               r3   r  &PipelineSession._dispatch_to_validator  sa    001F1FG  Cggi,G7762&D$]]_0BB6Dv~,&"8%LL5
#!6CU9V!VWA)-b&7%8")MH)+&"))TF"TF*;<L! !$ LL5
#.;M1NNO"KK.!#45!#5xAST???#'??GK 23t7L7L3M2Nn]a]l]l\mno	I==gED *4+;+;*<=>:-!44TUUyy,T-=-=,>c$HI!5)}TEUEUDV5WXX 	I/s34ui3CA31GHH	Is&   AH A H I&I<IIc           
     Z  "   V P                   '       d   V P                  '       g   R#  \        P                  ! \        P
                  ! V P                  RR7      RR7      G Rj  xL
 V n        V P                  P                  \        P                  ! RRRV P                  RR	/4      4      G Rj  xL
  \        P                  ! V P                  4       4      V n        \        R
V P                   24       R#  L LI  \         d!   p\        RT 24       RT n         Rp?R# Rp?ii ; i5i)zLConnect to external emotion detection engine. Fails silently if unavailable.N)max_sizer  r  r   zsession.startrx  r  r  z[Emotion] Connected to z2[Emotion] Connection failed (continuing without): i   )r  r  r0  r  r:  r  r  r  r   r  rx  r  _emotion_receiverr  r6  rW   )r  rZ  s   & r3   r  'PipelineSession._connect_emotion_engine  s    ###4+B+B+B	$%,%5%5""4#:#:UK&  D ""''

doou4 )   
 ")!4!4T5K5K5M!ND+D,C,C+DEF   	$FqcJK#D	$sY   $D+D+;C= %C9&AC= 1C;2AC= 7D+9C= ;C= =D(D#D+#D((D+c                D    RV 9   d   V P                  R4      R,          # T # )u8   Normalize emotion label — e.g. '难过/sad' → 'sad'.r  re  )r]  )r  s   &r3   _normalize_emotion_key&PipelineSession._normalize_emotion_key  s"     &)CZsyy~b!8S8r  c                (  "    V P                     Rj  xL
  p \        P                  ! V4      pVP                  R4      R8w  d   K9  VP                  R/ 4      pVP	                  4        UUu/ uF  w  rEV P                  V4      VbK  	  pppV P                  VP                  RR4      4      pVP                  R^ 4      pWrR&   WbR&   V P                  '       d   V P                  P                  R4      MRp	W n        V P                  RRRVRVRV/4      G Rj  xL
  V P                  '       dQ   V P                  '       d?   W8w  d9   VR8  d2   VR8w  d+   Wpn
        \        P                  ! V P                  4       4       \        R	V R
VR R24       EK   ELu uppi  L  \        P                  \         3 d     EK  i ; iEDR#   \"        P$                   d    \        R4        R# \&         d   p
\        RT
 24        Rp
?
R# Rp
?
ii ; i5i)z:Receive emotion inference results from the emotion engine.Nr   r%  scoresprimaryneutral
confidenceg333333?z  [Emotion] r  z.2fr  z[Emotion] Connection closedz[Emotion] Receiver ended: )r  r   r&  rT   rm  r  r  r  r5  r8  r  r0  r  _omni_emotion_session_updater6  r   KeyErrorr:  r;  rW   )r  r   r=  
raw_scoresr0   r2   r  new_primarynew_confidenceold_primaryrZ  s   &          r3   r  !PipelineSession._emotion_receiver  s    ,	4!-- ' 'c&::c?Dxx'94  "&(B!7J*4*:*:*<>*<$! #99!<a?*<  >"&"="=I6#8K%)XXlA%>N&1O%+NHLH[H[H[$"5"5"9"9)"DaeK*.' **	!;$n &	&     $ + : .# 5 +y 85@2++D,M,M,OPLRs7K1MNK'>" ,,h7 M .P ** 	1/0 	4.qc233	4s   HG	 GFGG	 ,F"G	 	%F".FBF"F F"1F"AF"G	 GF""G=G	 GG	 H	 H)H,H5H6H
H
HHc                   "   V P                   '       d'    V P                   P                  V4      G Rj  xL
  R# R#  L  \         d     R# i ; i5i)zBForward PCM audio to emotion engine. Non-blocking, ignores errors.N)r  r  rW   )r  r  s   &&r3   r8  )PipelineSession._forward_audio_to_emotion&  sI     &&++I666 6 s1   A? =? A? A
AAAc                  "   V P                   '       d]    V P                   P                  \        P                  ! RR/4      4      G Rj  xL
  V P                   P	                  4       G Rj  xL
  V P                  '       d;   V P                  P                  4       '       g   V P                  P                  4        RV n         RV n	        R#  L Lb  \
         d     Lmi ; i5i)z+Gracefully close emotion engine connection.r   zsession.endN)
r  r  r   r  r  rW   r  r  r  r  r  s   &r3   r  *PipelineSession._disconnect_emotion_engine.  s     &&++DJJ7N,OPPP&&,,... d&8&8&=&=&?&?%%'" Q. sX   C"4C 
C!C ,C-C 1C"C"#*C"C C CC"CC"c                    V P                   '       d   V P                  '       g   R# V P                  P                  RR4      pV P                  P                  R^ 4      pVR8X  g   VR8  d   R# RV RVR R	2# )
zBuild an emotion context string for injection into system prompts.
Returns empty string if no emotion data or detection disabled.r6   r  r  r  皙?z.

CALLER EMOTION: The caller currently sounds z (confidence: z.0%u{   ). Adjust your tone and response appropriately — acknowledge their emotional state if relevant, and respond with empathy.)r  r  rT   )r  r  r  s   &  r3   r  *PipelineSession._build_emotion_instruction;  s     ###4+>+>+>%%)))Y?((,,\1=
i:#3>wi H&s+ ,()	
r  c                  "   V P                   '       g   R# V P                  4       p\        P                  ! RRRRV//4      p V P                  P                  RV P                   P                  V4      G Rj  xL
  \        RV P                  P                  R4       24       R#  L-  \         d   p\        RT 24        Rp?R# Rp?ii ; i5i)	zNUpdate Omni session instructions when a significant emotion shift is detected.Nr   r  r  r   z,  [Omni] Session updated for emotion shift: r  z(  [Omni] Emotion session update failed: )r8  r  r   r  r/  r  r  r6  r  rT   rW   )r  r   r  rZ  s   &   r3   r  ,PipelineSession._omni_emotion_session_updateL  s     446$5%
 	B))++doo..@ @ @@ATATAXAXYbAc@def@  	B<QC@AA	BsB   AC4B( 8B&9+B( $C&B( (C3CCCCc                   "   \         P                  ! V P                  R,          4      G Rj  xL
  V P                  '       d*   V P                  R9   d   V P                  4       G Rj  xL
  RV n        R#  LH L5i)zHWait for min duration, then trigger barge-in if speech is still ongoing.r"  NFr  )r0  r  r   rh  rs  r  r  s   &r3   r  PipelineSession._barge_in_check^  s]     mmD99D@AAA!!!djj4L&L((***!& 	B*s'   +A:A6A:$A:(A8)A:8A:c                v  "   V P                   R8X  d   R# \        R4       V P                  '       d6   RV P                  n        V P                  P                  P                  4        V P                  '       dB   V P                  P	                  4       '       g"   V P                  P                  4        RV n        . pV P                  P                  4       '       gG    V P                  P                  4       pVP                  R4      R8w  d   VP                  V4       Kd  Kf  V F&  pV P                  P                  V4      G Rj  xL
  K(  	  V P!                  RR/4      G Rj  xL
  RV n         V P!                  RRRR	/4      G Rj  xL
  R
V n        R#   \        P                   d     K  i ; i Ll LO L-5i)zCCancel TTS, flush audio queue, notify browser, return to LISTENING.r  Nz"  [BARGE-IN] Interrupting playbackTr   r  rg  r  r  F)rs  r6  ri  	cancelledr  rc  rw  r  r   r	  
get_nowaitrT   ra  r0  
QueueEmptyrn  r  rh  )r  keptrI  s   &  r3   r  !PipelineSession._trigger_barge_ine  so    ::$23 %%%37D&&0&&++//1 t':':'?'?'A'A&&("&D **""$$zz,,.88F#w.KK% / D**..&&&  jj&*-... 
jj&(HkBCCC!& %%  ' 	/ 	Dsh   A7F9:F9AF9AF 'F9F3F9%F5&#F9	F7
F9F0,F9/F00F95F97F9c                  "   V P                   '       d   R# \        R4       RV n         RV n        V P                  '       d>   . V n        RV n        V P
                  e"   V P
                  P                  4        RV n        V P                  '       dQ    V P                  P                  RV P                  P                  \        P                  ! RR/4      4      G Rj  xL
  . pV P                  P                  4       '       gG    V P                  P!                  4       pVP#                  R4      R8w  d   VP%                  V4       Kd  Kf  V F&  pV P                  P+                  V4      G Rj  xL
  K(  	  V P-                  RR	/4      G Rj  xL
  V P.                  '       d\   V P0                  '       d   V P0                  R,          M^ pVR
8  d,   V P3                  R4      G Rj  xL
  \        RVR R24       R# R# R#  EL#  \         d   p\        RT 24        Rp?EL@Rp?ii ; i  \&        P(                   d     K  i ; i L L Ld5i)z8Cancel Omni response, drain audio queue, notify browser.Nz'  [Omni BARGE-IN] Interrupting playbackTFr   rk  z&  [Omni BARGE-IN] Cancel send failed: r  rg  r	  u.  [SYSTEM: You were interrupted mid-sentence; the caller heard only part of your last reply. Treat what they say next as a continuation of the same topic — answer it directly and pick up the flow naturally. Do NOT restart or repeat your previous explanation, and do NOT apologize for the interruption.]z;  [Omni BARGE-IN] Smooth-continuation note injected (spoke r  r  i  )r:  r6  r=  rN  rK  rM  r  r8  r/  r  r  r   r  rW   r   r	  r  rT   ra  r0  r  rn  r  r   r@  rL  )r  rZ  r  rI  spoken_ss   &    r3   r(  &PipelineSession._omni_trigger_barge_in  s    78"+/(((()+D&,1D)((4))002,0)???Dii//$//22JJ(9:;= = = **""$$zz,,.88F#w.KK% / D**..&&& jj&*-... $$$::: 779E@A 311-. . .    (~R1 2  %-=  D>qcBCCD %%  '..s   BIA
H G?H !!IAH) 'I,I-III"I40I$I	%I?H H&H!I!H&&I)I>IIII	Ic                9  a a.a/a0a1"   S P                   '       g   R # \        P                  ! 4       pS P                  o.S P                  RR/4      G R j  xL
  RS n        S P                  RRRR/4      G R j  xL
  S P                  RRRRR	V/4      G R j  xL
  S P                  RV4        S P                  V4      w  rEV'       Ed|   S P                  R
8X  Edj   VR,          pS P                  R,          p\        RVR,           RV RV R24       RpS P                  P                  R S P                  V4      G R j  xL
 pS P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       S P                  S P                  V4      p	S P                  S P                  4      p
S P                  P                  R S P                  WV
4      G R j  xL
  S P                  RRRVRVRRVR,           2/4      G R j  xL
  S P                  RRV RV 24       S P                  S P                   4      G R j  xL
  VS n        S P                  RRRVRV/4      G R j  xL
  S P                  P                  R S P"                  V4      G R j  xL
 pS P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       S P                  WK4      pS P                  V4      pS P                  P                  R S P                  WV4      G R j  xL
  RS n        S P                  RRRR/4      G R j  xL
  R # S P                  S P                  W4      p	S P                  S P                  4      p
RS n        S P                  RRRR /4      G R j  xL
  S P                  P                  R S P$                  WW4      G R j  xL
 pVP'                  R!^ 4      p\)        \        P                  ! 4       V,
          R",          4      pVR,          R8X  Ed   S P*                  '       Ed   VP'                  R	R#4      pVP'                  RR#4      pVP'                  R$R#4      pS P                  R,          pS P-                  V4      w  ppVf   \        R%V R&24       EMVR,          pVP/                  4       '       g   R'V R(2pS P                  P                  R S P                  V4      G R j  xL
 p\        R)V RV RV R*V R+V R,24       S P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       VP'                  R-R.4      '       g   S P                  RR/4      G R j  xL
  S P                  S P                  V4      pS P                  S P                  4      pS P                  P                  R S P                  VVV4      G R j  xL
  S P                  RRRVRVRV/4      G R j  xL
  S P                  RR/V RV RV R24       S P0                  R
,          R0,          P3                  R1R2R3R4R5R6V R72/4       S P                  S P                   4      G R j  xL
  VS n        S P                  RRRVRV/4      G R j  xL
  S P                  P                  R S P"                  V4      G R j  xL
 p\        R8V R9VR:,           R;24       S P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       S P                  VV4      pS P                  V4      pS P                  P                  R S P                  WV4      G R j  xL
  \)        \        P                  ! 4       V,
          R",          4      pS P                  RR<R=R>R?V/4      G R j  xL
  VP'                  R@4      '       d%   S P                  RRA/VR@,          C4      G R j  xL
  EMQVR,          RB8X  Ed   VP'                  RCR#4      ;'       g    RDpVP'                  R	R#4      pS P                  R,          pVS P4                  9  d   RDpVS n        \        REV RFV R24       VP/                  4       '       d4   S P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       S P                  RRGV 24       \8        P:                  ! RH4      G R j  xL
  R
S n        S P0                  R
,          R,          pS P                  RRRR
RV/4      G R j  xL
  S P<                  '       g'   S P?                  S P@                  V4      pRIS n        RJpMBS P?                  S PB                  V4      ;'       g    S P?                  S P@                  V4      pRKpV'       d   \        RLV RMVRN,           R;24       S P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       S P0                  R
,          R0,          P3                  R1ROR5V/4       S P                  R
V4      pS P                  R
4      pS P                  P                  R S P                  WV4      G R j  xL
  MS P                  P                  R S P"                  R
4      G R j  xL
 p\        R8V RPVR:,           R;24       S P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       S P                  R
V4      pS P                  R
4      pS P                  P                  R S P                  WV4      G R j  xL
  \)        \        P                  ! 4       V,
          R",          4      pS P                  RR<R=R>R?V/4      G R j  xL
  VP'                  R@4      '       d%   S P                  RRA/VR@,          C4      G R j  xL
  EMtVR,          RQ8X  Ed   VP'                  R	R#4      pVP'                  RR#4      pS P                  R,          p\        RRV RSV R24       VP/                  4       '       d4   S P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       S P                  RRTV 24       R S n        RUS P0                  9   d   . S P0                  RU,          R0&   \8        P:                  ! RH4      G R j  xL
  RUS n        S P0                  RU,          R,          pS P                  RRRRURV/4      G R j  xL
  S PD                  '       d   S PD                  p\        RVVR:,           R;24       S P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       S P0                  RU,          R0,          P3                  R1ROR5V/4       S PF                  P'                  RDS PF                  P'                  RWRX4      4      pS P                  P                  R S P                  W4      G R j  xL
  \)        \        P                  ! 4       V,
          R",          4      pS P                  RR<R=R>R?V/4      G R j  xL
  VP'                  R@4      '       d%   S P                  RRA/VR@,          C4      G R j  xL
  EMVR,          RY8X  Edg   VP'                  RCR#4      ;'       g    RDpVP'                  R	R#4      pS P                  R,          pVS P4                  9  d   RDpVS P6                  8X  d\   \        RZV R[24       VP/                  4       '       d5   S P                  RRRRR	VRV/4      G R j  xL
  S P                  RVV4       EMVS n        \        R\V R]24       VP/                  4       '       g   S PI                  V4      pR^V R72pVP/                  4       '       d   S P                  RRRRR	VRV/4      G R j  xL
  S P                  RVV4       S P                  RR/4      G R j  xL
  S P                  S P                  V4      p	S P                  S P                  4      p
S P                  P                  R S P                  VW4      G R j  xL
  S P                  RR_RCV/4      G R j  xL
  S P                  RR`V 24       S PI                  V4      o1RaS1 RbS1 Rc2o/V/V1V 3Rd lpS P                  P                  R V4      G R j  xL
 pVP/                  4       '       d   S P                  RRRRR	VRV/4      G R j  xL
  S P                  RVV4       S P                  S P                  V4      pS P                  P                  R S P                  VVV
4      G R j  xL
  \)        \        P                  ! 4       V,
          R",          4      pS P                  RR<R=R>R?V/4      G R j  xL
  VP'                  R@4      '       d%   S P                  RRA/VR@,          C4      G R j  xL
  E	M<VR,          Re8X  Ed   VP'                  R	R#4      pVP'                  RR#4      pS P                  R,          pS P0                  R
,          R,          pVP/                  4       '       g   RfV R72pS P                  P                  R S P                  V4      G R j  xL
 p\        RgV RV RSV R+V R,2	4       S P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       VP'                  R-R.4      '       g   S P                  RR/4      G R j  xL
  S P                  S P                  V4      pS P                  S P                  4      pS P                  P                  R S P                  VVV4      G R j  xL
  S P                  RRRVRVRV/4      G R j  xL
  S P                  RRhV RV RV R24       S P                  p S P0                  V ,          R0,          P3                  R1R2R3RiR5RjV R72/4       S P                  S P                   4      G R j  xL
  R
S n        S P                  RRRR
RV/4      G R j  xL
  V'       d	   RkV RlV 2MRkV R72p!S P0                  R
,          R0,          P3                  R1RR5V!/4       S P                  P                  R S P"                  R
V4      G R j  xL
 p\        R8V R9VR:,           R;24       S P                  RRRRR	VRV/4      G R j  xL
  S P                  RW4       S P                  R
V4      pS P                  R
4      pS P                  P                  R S P                  WV4      G R j  xL
  \)        \        P                  ! 4       V,
          R",          4      pS P                  RR<R=R>R?V/4      G R j  xL
  VP'                  R@4      '       d%   S P                  RRA/VR@,          C4      G R j  xL
  EMLVR,          Rm8X  Ed   VP'                  R	R#4      p"VP'                  RnR#4      p#VP'                  RoR#4      p$VP'                  RR#4      pS.R,          p\        RpV RqV# RrV$ RsV 24       S P                  RRtV# RV$ RuV 24       S P                  RRmRVRnV#RoV$RV/4      G R j  xL
  S PJ                  '       d   S PL                  '       d   S PN                  '       d   S PP                  '       g   S P                  P                  R S PR                  V#V$V4      G R j  xL
 p%V%P'                  Rv4      '       d   RIS n(        S P                  RRwRxRIRvV%P'                  RvR.4      RyV%P'                  RyR#4      RzV%P'                  RzR#4      /4      G R j  xL
  V"P/                  4       '       g   R#o0S P6                  '       d3   S P6                  RD8w  d"   S PI                  S P6                  4      p&R{V& R72o0V.V0V 3R| lp'S P                  P                  R V'4      G R j  xL
 p"V"'       d   S.R0,          P3                  R1ROR5V"/4       VP'                  R-R.4      p(V"'       d   S P                  RRRRR	V"RV/4      G R j  xL
  S P                  RV"V4       V('       g   S P                  RR/4      G R j  xL
  S P                  S P                  V"4      p)S P                  S P                  4      p*S P                  P                  R S P                  V"V)V*4      G R j  xL
  \)        \        P                  ! 4       V,
          R",          4      pS P                  RR<R=R>R?V/4      G R j  xL
  VP'                  R@4      '       d%   S P                  RRA/VR@,          C4      G R j  xL
  EMVR	,          p"S.R,          p\        R}V R~V RV"R:,           R;24       S P                  RRRRR	V"RV/4      G R j  xL
  S P                  RV"V4       V"P/                  4       '       d   VP'                  R-RI4      '       g   S P                  RR/4      G R j  xL
  S P                  S P                  V"4      p+S P                  S P                  4      p,S P                  P                  R S P                  V"V+V,4      G R j  xL
  S P                  RR<R=R>R?V/4      G R j  xL
  VP'                  R@4      '       d%   S P                  RRA/VR@,          C4      G R j  xL
  VP'                  R4      '       d   S P                  RR4       R.S n         R #  S P                   '       dE   S P                  R8w  d2   RS n        S P                  RRRR/4      G R j  xL
  \        R4       R # R # R #  ELD EL# EL EL` ELB EL EL ELl ELI EL EL EL EL} EL# EL EL EL ELX EL EL ELf ELC EL EL EL~ EL6 EL ELL EL
 EL EL EL ELX EL! EL ELw EL? EL ELA EL EL EL EL EL EL ELL EL! EL EL ELK EL E
L E
Lr E
L: E	L E	LZ E	L EL EL EL EL EL ELP EL EL ELn EL ELD EL ELQ EL EL EL] EL EL EL EL6 EL EL EL}  \8        PT                   d    \        R4        R # \V         dA   p-\        RT- 24       S P                  RRRy\Y        T-4      /4      G R j  xL 
   R p-?-ELR p-?-ii ; i ELv5i)Nr   rg  r  r  thinkingr  r  rJ  r  r   r   z  [KEYWORD] "r   u   " matched → transferring to r  r  z$Sure, let me connect you right away.r  r  rl  rm  rn  r  ro  r  rp  rq  r  r  r  r  r  llm_msr"  r6   r  z"  [TRANSFER] No target found for "z", skippingzSure, let me transfer you to z right away.z  [TRANSFER] z) (reason: r   r%  
tts_playedFz
Transfer: r   r  r[   tool_call_idcall_transferr  zTransferred to r2    [z] Greeting: "r  r  rT  rU  totalrg   timingsdebug_timinglanguage_selectedr(  rc   z  [LANG] Language selected: z (from zLanguage selected:       ?Tfirstreturnedz  [Greeting:z] "r  r  z] Generated greeting: "r-  z(  [LANG] Change language requested from z
 (reason: zChange language requested: r  z  [Lang Agent] Greeting: "r   r   r1  z  [LANG] Already in z, ignoring no-op switchz  [LANG] Switched to: z (in-place)zSure, switching to language_switchedzLanguage switched to: z[System: You just switched to z!. Say a single short sentence in z; asking how you can help. Do NOT introduce yourself again.]c                  2  < R RRSP                  SP                  4      RS R2,           /R RRS/.p Rp SP                  P                  P                  P                  SP                  V RRR	/R
7      pV FZ  pVP                  ^ ,          P                  p\        VR4      '       g   K4  VP                  '       g   KH  WP                  ,          pK\  	  VP                  4       #   \         d(   p\        RT 24        Rp?TP                  4       # Rp?ii ; i)r  r  r  
IMPORTANT: You MUST reply in r2  rJ  r6   Tr   Fr#  r  streamr?  z!  [LLM] Language followup error: Nr  rr  r  r@  rA  rB  r   rC  deltar4  r  rW   r6  r(   )	msgsr  r*  chunkr,  rZ  followup_promptnew_lang_namer  s	         r3   _gen_followup9PipelineSession.process_transcript.<locals>._gen_followup  s   #Xy$:V:VW[WhWh:i!@qQ;R S#VYH 
  "	K%)XX]]%>%>%E%E&*nntD,=u+E &F &GF *0(-a(8(>(>#*5)#<#<$(MM$9D *0  $zz|+  ) K!$EaS"IJJ#zz|+Ks$   A0C$ *C$ >C$ $D/DDr  zLet me transfer you back to z  [TRANSFER BACK] zTransfer back: call_transfer_backzTransferred back to zCaller returned from z
. Reason: r  r  r  z  [CALL BACK] Agent z: name=z, phone=z	, reason=zCallback requested: z) - r  r  r  r  r  r(  c                  J  < R RRSP                  SP                  4      R,           S,           /.SR,          ,           p Rp SP                  P                  P                  P                  SP                  V RRR/R	7      pV FZ  pVP                  ^ ,          P                  p\        VR4      '       g   K4  VP                  '       g   KH  WP                  ,          pK\  	  VP                  4       #   \         d(   p\        R
T 24        Rp?TP                  4       # Rp?ii ; i)r  r  r  r  r   r6   Tr   Fr)  z&  [LLM] call_back confirmation error: Nr+  )	r-  r  r*  r.  r,  rZ  r  
lang_instrr  s	         r3   _gen_cb_confirmation@PipelineSession.process_transcript.<locals>._gen_cb_confirmation  s   #Xy$:V:VW[WhWh:i  A;A);* +  "),	 -
  "	P%)XX]]%>%>%E%E&*nntD,=u+E &F &GF *0(-a(8(>(>#*5)#<#<$(MM$9D *0  $zz|+  ) P!$J1#"NOO#zz|+Ps%   A0C0 6C0 
C0 0D";DD"z  [LLM+TTS] (zms total, LLM ms) "r#  zCall ended by agentz!  [Pipeline] Cancelled (barge-in)z  [Pipeline] Error: r  r[  )-ru  r7  r  r  rs  r  r  rr  r6  r/  r  rG  rM  rQ  r  rs  r   _generate_greeting_run_pipeline_streamedrT   rY  rl  r  r(   rj  ra  r3  rv  r0  r  rq  rf  re  rp  r  r   rr  r  r  r  r  r  r  rW   r`  )2r  r  r  r[  kw_keykw_agentrw  rx  farewellr  tts_settingsr  r  greeting_ttsrD  r  total_msr  r  ru  rv  farewell_voicefarewell_ttsselected_langgreeting_kindnew_langspokenr  
lang_labelr1  followupfollowup_voicetransfer_agent_keycontext_msgresponse_textr  r  acrs_resultlnr6  tts_already_playedcb_voicecb_tts
resp_voiceresp_ttsrZ  r  r/  r5  r0  s2   f&&                                           @@@@r3   r  "PipelineSession.process_transcript  s    {{{))+ jj&*-...
jj&(HjABBBjj&,	66:VWWW&*-Y	C#:::FFv$++s2"6* KK/	hy&9%: ;))0	F81> ? B!%!:!:$//"; ;jj&,	4"((GY"H I I I!!$<11$2C2CXN#??@Q@QRii//$--,H H H jj&*"()T7"*i8K7L,M"O P P P !!(*9+T'CE (()<)<===$*!jj&.'6"('"3 4 4 4 "&!:!:$116"; ;jj&,	4"((GW"F G G G!!$:!%!:!:6!L#??Gii//$--<Q Q Q )
jj&(Hk!JKKK--d.?.?VE;;D<M<MNL $DJ**fh*EFFF9944d11:l F ZZ!,FDIIK'1T9:Hf~+0L0L0L!::fb1Hb1#ZZb9
 KK/	+/+H+H+T(
L%>zl+VW*62G#>>++%B7)<#X &*YY%>%>d33X&?  ?H M)D	J< P&&,XRxs< = **flIt&,h&L M M M%%dH@ "::lE::"jj&*)=>>>)-)B)B4CTCTV^)_'+'G'GHYHY'Z"ii77 $--><Y Y Y **
	4(F&    %%h(29+T'"VHTU&VX KK$Y/66&!_WIQ#?8  ,,T-@-@AAA(2D%**fngz&,g&7 8 8 8 &*YY%>%>d55z&C  CHCyhsm_DIJ**flIt&,h&J K K K%%dH>%)%>%>z8%TN#'#C#CJ#OL))33dmmX|U U U  #DIIK'$9T#ABH**fh&*H&6 7 7 7zz),,"jj&. *?,29,=*? @ @ @ #66 &

:r : B Bd!::fb1 KK/	 !(@(@@$(M(5%4]O79+UVWX>>##**flIt&,h&L M M M%%dH@!!($7"GI mmC((( %(!++c*62jj&.'3"('"3 4 4 4 ///#t/F/FVH/3D,$+M (J(JMZ S S??4+B+BMR  %/MLs8C=/NO**flIt&,h&J K K K%%dH>KK$Y/66iBD%)%>%>sH%MN#'#C#CC#HL))33dmmX|U U U &*YY%>%>d55s&<  <HCy(?dST**flIt&,h&J K K K%%dH>%)%>%>sH%MN#'#C#CC#HL))33dmmX|U U U 		g 5=>jj&(GW"&"2 3 3 3::i((**fn &;(.y(9&; < < < #44!::fb1Hb1 KK/	@ L""(, - >>##**flIt&,h&L M M M%%dH@!!($?x"HJ )-%T[[(57DKK'	2mmC((($*!++f-f5jj&.'6"('"3 4 4 4 ///#;;H6x}oTJK**flIt&,h&J K K K%%dH>KK'	299iBD%)^^%7%7**9g>&@N))33dmmXG G G 		g 5=>jj&(GW"&"2 3 3 3::i((**fn &;(.y(9&; < < < #44!::j"5==FB/![[0
4#;#;;#H t4440
:QRS||~~"jj&,	4*0&':*O P P P))$
C,4D)28*KHI!<<>>%)__X%>
#6zl!!D||~~"jj&,	4*0&':*O P P P))$
C"jj&*)=>>> $ 9 9$:K:KV T'+'G'GHYHY'Z"ii77 $--N N N ** 3Z&    %%h2H
0ST %)OOH$=M8 H::G I<= $
,$ &*YY%>%>t]%SSH~~''"jj&,	4*0(GZ*Q R R R))$*E)-)B)B4CTCTV^)_"ii77 $--><Y Y Y 		g 5=>jj&(GW"&"2 3 3 3::i((**fn &;(.y(9&; < < < ?2!::fb1Hb1 KK/	++c*62~~''!=gYaHH "&!:!:$//"; ; *9+T' C""(F838 9 jj&,	4"((GY"H I I I!!$< zz,66**fj%9:::%)%>%>t?P?PRZ%[N#'#C#CDDUDU#VL))33dmmX~|U U U jjJItWh"    !!($3I;d7)2fXUV"WY &*%6%6"./	:AAF"$8!5gYa@C  (()<)<===$'!jj&.'3"('"3 4 4 4 X^ 5i[
6(Sez  |E  {F  FG  dHC +22Hi4 
 "&!:!:$113"@ @G9M(3-EFjj&,	4"((GW"F G G G!!$:!%!:!:3!I#??Dii//$--<Q Q Q 		g 5=>jj&(GW"&"2 3 3 3::i((**fn &;(.y(9&; < < < ;. &

62 6 &

?B ?!',<b!AHb1"6]
,ZL 9+_H^4D E  &x) * !!($8 H&&4%5T&#CD jjKZ#]$nf"    %%%$*;*;*; 666t?S?S?S(,		(A(Ad==%~v)? #?K #y11/3,**"D!;??9e#D!;??9b#A!;??9b#A&    %**,,!#J,,,1F1F$1N!__T-B-BC'Frd!%L
,$ +/))*C*CDJ^*_$_M$i(//iQ^0_` &,ZZe%D" **flIt&,mWj&R S S S%%dM:F-"jj&*)=>>>#'#<#<T=N=NP]#^!%!A!A$BSBS!T"ii77 $--&R R R 		g 5=>jj&(GW"&"2 3 3 3::i((**fn &;(.y(9&; < < <
 !'v"6]
hZ~fX F',-T3 4 jj&,	4"(-*"N O O O!!$zB !&&((L$1O1O**fj%9:::!%!:!:4;L;Lm!\J#??@Q@QRH))33dmm]JR R R jj&(GW"&"2 3 3 3::i((**fn &;(.y(9&; < < < ::j))%%h0EF"'DK * ;;;4::4$DJ**fh+FGGG-. 5;G 	/ 	CW;I
HP >4;G
Q L G2 ?M ?Y B8 CKU7@ M )
4 KU <K
U3<M )4KG3<"PP ?N<  TRY3<;I ;U >4@GQ3<&#?
@ %`S ?R3<O ;R3< %% 	56 	C(,-**fgy#a&ABBB	C Hs-	  AAs:An#As:7An8As:AnAs:.BAr  An  Ar !An#"A8Ar An&*Ar An):Ar  An,%Ar &An/'.Ar An2 Ar 6An57A#Ar An8#Ar >An;?Ar As:AAr An>/Ar AoA#Ar 0A0Ar  As:"Ar 0Ar 1Ao2;Ar -Ao.AAr 2Ao
3A'Ar Ao Ar ;Ao<A1Ar -Ao.%Ar Ao.Ar Ao9Ar <Ao=A$Ar !Ao"A
Ar ,Ao"-Ar Ar 'Ao%(Ar ,As:.'Ar BAr Ao(AAr !Ao+"?Ar !Ao."Ar 8AAr &Ar (5Ar Ao1BAr /Ao40/Ar Ao7 9Ar Ao:A$Ar >Ao=?A
Ar 	Ap 
Ar %Ar ApAr 	As:B
Ar ApA2Ar Ap		?Ar Ap	Ar >Ar ApB#Ar ApA
Ar ApAr (Ar ApAr As:'Ar 6BAr ApA1Ar 6Ar Ap-Ar @ Ap!@A&Ar A'Ap$A(Ar BAp'BAAr CAp*C Ar C:Ar DAp-DAAr E6Ap0E7A
Ar GAp3GAr GAr G<Ap6G=Ar HAs:HA5Ar I90Ar J)Ap9J*8Ar K"Ap<K#AAr L'Ap?L(A'Ar NAqN Ar N0AqN1A=Ar P.AqP/%Ar QAqQAr Q!A&Ar SAqS9Ar TAqTA$Ar U&AqU'A
Ar V1AqV2Ar WAr W,AqW-Ar W1As:W3B0Ar Z#AqZ$Ar Z:Ar [Ar [Ar [0,Ar \Aq \Ar \8AAr ^Aq#^Ar ^(Ar ^<AAr `Aq&`Ar `"5Ar aAr a4Aq)a5Ar bAr b*Aq,b+A'Ar dAq/dA
Ar eAq2eAr e9Ar fAq5fAr fAs:fA
Ar g)Aq8g*,Ar hAr h/Ar iAq;iA'Ar j-Aq>j.Ar kArkAr k(Ar lArlAr l#Ar l<As:m0As:nAs7nAs:nAs:nAs:n Ar n#Ar n&Ar n)Ar n,Ar n/Ar n2Ar n5Ar n8Ar n;Ar n>Ar oAr oAr oAr o
Ar oAr oAr oAr oAr oAr oAr oAr o"Ar o%Ar o(Ar o+Ar o.Ar o1Ar o4Ar o7Ar o:Ar o=Ar p Ar pAr pAr p	Ar pAr pAr pAr pAr pAr pAr pAr p!Ar p$Ar p'Ar p*Ar p-Ar p0Ar p3Ar p6Ar p9Ar p<Ar p?Ar qAr qAr qAr qAr qAr qAr qAr qAr qAr qAr q Ar q#Ar q&Ar q)Ar q,Ar q/Ar q2Ar q5Ar q8Ar q;Ar q>Ar rAr rAr r As4r'As:r*As4r3As4r4/As/s#As&s$As/s)As:s/As4s4As:c                0   V P                   pVR ,          P                  RRRV/4       RpRpV P                  '       d<   V P                  R8w  d+   V P                  V P                  4      pRV R2pRV R	V R
2pV P                  '       dk   V'       dc   W P                  8w  dS   W P                  9   dC   V P                  V4      pV P                  V P                  4      pVRV RV RV RV R2	,          pW@P                  4       ,           R,           V,           V P                  4       ,           p	RRRV	/.VR ,          ,           p
RRV P                  //pV P                  R8X  d   V P                  pM/V P                  R8X  d   . pMVP                  R4      ;'       g    . pV'       d   \        V4      M. pV Uu. uF-  pVP                  R/ 4      P                  R4      RQ9  g   K+  VNK/  	  ppV Uu. uF  p\        V4      '       g   K  VNK  	  ppV UUUu. uF2  pVP                  4        UUu/ uF  w  ppVRR9  g   K  VVbK  	  uppNK4  	  ppppV P                  pV P                  R8X  d,   V P                  4       pV'       d   VP                  V4       EMvV P                  R8X  d   V P                   '       d1   RV9  d*   V P#                  4       pV'       d   VP                  V4       V P$                  '       d'   RV9  d    VP                  V P'                  4       4       RV9  d*   V P)                  4       pV'       d   VP                  V4       RV9  d    VP                  V P+                  4       4       MVP                  V P-                  4       4       VP                  V P/                  4       4       RV9  d    VP                  V P+                  4       4       RV9  d*   V P)                  4       pV'       d   VP                  V4       V'       g   RpRpRpRp \1        RSR V P2                  R!V
R"R#/VB pV P4                  e   V P4                  VR$&   V P6                  e   V P6                  VR%&   V P8                  e   V P8                  VR&&   V'       d   VVR'&   V P:                  P<                  P>                  P@                  ! RS/ VB pV EF  pVPB                  ^ ,          PD                  p\G        VR4      '       d&   VPH                  '       d   VVPH                  ,          p\G        VR(4      '       g   Kl  VPJ                  '       g   K  VPJ                   F  pVPL                  '       g   K  VPL                  PN                  '       d   VVPL                  PN                  ,          pVPL                  PP                  '       g   Kn  VVPL                  PP                  ,          pK  	  EK  	  V'       g   V'       d   \V        PX                  ! R+V4      pV'       d]   VP[                  ^4      pVP[                  ^4      ;'       g    R,pVRVP]                  4        P_                  4       p\U        R-V 24       MR\V        PX                  ! R.V4      '       d6   RpR,p\V        P`                  ! R/RV4      P_                  4       p\U        R04       VR8X  d   V P                   '       d}   RpRp  \b        Pd                  ! V4      p!V!P                  R1R4      pV!P                  R2R4      p VR ,          P                  RR3RT;'       g    RR(R4R5R6RRRRR7V//./4       R6R8R9VR1VR2V /# VR8X  dg   Rp \b        Pd                  ! V4      p!V!P                  R1R4      pVR ,          P                  RR3RT;'       g    RR(R4R:R6RRRRR7V//./4       R6RR9VR1V/# VR;8X  d   / p" \b        Pd                  ! V4      p"VR ,          P                  RR3RT;'       g    RR(R4R<R6RRRR;R7V//./4       VR ,          P                  RR=R>R<RR?/4       V"P                  R@R4      Pk                  RAR4      p#R6R;R9VRBV"P                  RBR4      R@V#R1V"P                  R1R4      /# VR8X  dx   V P                  R8X  dg   Rp$ \b        Pd                  ! V4      p!V!P                  RCR4      p$VR ,          P                  RR3RT;'       g    RR(R4RDR6RRRRR7V//./4       R6RER9VRCV$/# VR8X  dx   V P                  R8X  dg   Rp \b        Pd                  ! V4      p!V!P                  R1R4      pVR ,          P                  RR3RT;'       g    RR(R4RFR6RRRRR7V//./4       R6RR9VR1V/# VR8X  dx   V P                  R8w  dg   Rp$ \b        Pd                  ! V4      p!V!P                  RCR4      p$VR ,          P                  RR3RT;'       g    RR(R4RGR6RRRRR7V//./4       R6RR9VRCV$/# VRH8X  d   V Pl                  Po                  V Pp                  Pr                  R6RIRVR7V/4       V Pu                  RRJV RKV RL24        V'       d   \b        Pd                  ! V4      M/ p%V Pw                  V%4      p&V Py                  RHV%V&4       VR ,          P                  RR3RRR(R4RMV 2R6RRRVR7V//./4       VR ,          P                  RR=R>RMV 2RV&/4       R6RNR9R/# T;'       d    VRQ9  p'V''       d   V Pl                  Po                  V Pp                  Pr                  R6RIRVR7V/4       V Pu                  RRJV RKV RL24        V'       d   \b        Pd                  ! V4      M/ p(V P{                  VV(4      p)V)e"   VR ,          P                  RR=R>RMV 2RV)/4       VP}                  4       '       g1   V''       d   VR8X  d   ROp*V P                  V*4      pMV''       d   RpMRPpRR3RT;'       g    R/p+V''       d   R4RMV 2R6RRRVR7V//.V+R(&   VR ,          P                  V+4       \        VR ,          4      ^8  d   VR ,          RTR VR &   R6RNR9V/p,VR8X  d   R#V,R&   V,# u upi u upi u uppi u upppi   \R         d   pR)p\U        R*T 24        Rp?ELRp?ii ; i  \b        Pf                   d    Tp ELi ; i  \b        Pf                   d    Tp EL[i ; i  \b        Pf                  \h        3 d     EL"i ; i  \b        Pf                   d     EL\i ; i  \b        Pf                   d    Tp ELi ; i  \b        Pf                   d     ELi ; i  \R         d    / p% ELi ; i  \R         d    / p( ELi ; i)Ur   r  rJ  r  r6   rc   r  r  r  r  w   . This includes ALL spoken text — even when calling functions like transfer_call or transfer_back. Never use English.#
Note: The user may be speaking in " now, but you MUST still reply in . After responding in &, ask if they would like to switch to r2  r  r  r?  r   r   r  r   r  r   r  r  r'  r-  r1  r#  Nr#  r  r*  Tr   r   r   rg  
tool_callsz:I'm sorry, I encountered an error processing your request.z  [LLM] Error: +<function=(\w+)>\s*(\{.*?\})?\s*</function>{}&  [LLM] Extracted function from text: \bend_call\b\s*$\s*\bend_call\b\s*$)  [LLM] Extracted bare end_call from textr  r  r  rm   r  r   rC  rl  r  r3  r  call_call_backr[   r  'Callback request recorded successfully.r  r  r  r(  call_select_languager"  call_change_languagecall_switch_languager8  rV  ra  rQ  r  call_r  Goodbye! Thank you for calling.3I didn't quite catch that. Could you please repeat?r  r  r'  r-  r1  r  r   )Ar  ra  rv  rr  r3  r  r  r   rr  r   rT   r   rb   rm  r   r*  rl  r  rn  r.  r5  r$  r  r   r^  r   r   r   r   r  r@  rA  rB  rC  r,  r4  r  r[  r  r   rC  rW   r6  r  r  r  rR   rstripr  r   r&  r   rW  r  r/  call_soon_threadsafer   r   r  r_  rF  r  r(   rG  r   )-r  r  r  r  lang_prefixr  r  mismatch_lang_namesession_lang_name
sys_promptr  extrar{  rg  r   r0   r2   r  r  r  r  rL  tool_call_nametool_call_argskwargsr*  r.  r,  tcrZ  fn_matchr  r  rE  cb_argscb_phoner  _se_args	se_resultcustom_tool_called
_args_dictrg  r=  history_entryr  s-   &&&                                          r3   _run_llmPipelineSession._run_llm  sa   iJ GH   T%:%:d%B(=(=>I6ykA_`K"DYK P55>K @U!V !!!h 5 55 8 88!%!: $0E0E F67I6J K//@.A B''8&99_`r_sstvw !#?#?#AAmn#>>@A
 Xy*5
)
  143G3GHI #++K&(K))N399rK%0[!b! )EqEE*b)--f5 >( ( E ) ";Eq%7%:E; SXYRWQ $%779 I941aGG !Q$9 IRW 	 Y**&224CS!#%+++t0K $ 9 9 ; LL/***/@/LT==?@ ,">>@LL-%T6689LL779:LL3356%T6689 ,">>@LL-E$	) nn!  	F +(,(8(8}%*'+|$zz%"&**w"'wXX]]..55??Fa(.. 5),,!U]]2M 5,//E4D4D4D#..;;;!{{/// ."++2B2B B!{{444 ."++2G2G G /  * -yy>OH!)!2!)!2!:!:d -.?x~~/? @ G G I>~>NOP.>>!+!% "'=r= Q X X ZAC _,1M1M1MFJ(zz.1(B/!XXlB7
 )##=00D/J+~ V  %  Jx *. . _,F(zz.1(B/ )##=00D.J+~ V  %  OV]HfUU[(G**^4 )##=00D*Jk> R  %  )## 0D%  {{#3R8@@bIHV]_b!A ('++h3	  ..43D3D3NDzz.1xx
B/ )##=00D0J):K X  %  /
TXYY ..43D3D3KF(zz.1(B/ )##=00D0J):K X  %  -v}hPVWW ..43D3D3NDzz.1xx
B/ )##=00D0J):K X  %  -v}jRVWW //II**

%%fnk>Z h*^4DAnEUUV(WX9G4::n5R 55h?I##$6)L)##YE.!12Jn U  %  )##%'7 89% 
 J33  # #~ 6#  # 	
 II**

%%fnk>Z h*^4DAnEUUV(WX ;ITZZ7r
 44^ZPJ%i ''F"eN+;$<z)  ""$$!n
&B< $ 5 5h ?# " U  i9N9N$On-.
V^[.Q, +M,'
 	i. uY 1$$Y/4E)
FM:Z'#Dg	) <I YL  	)XMOA3'((	)8 '' ('(* '' ('(" (()4 > '' & '' ('(& '' ,  D   
 s  :(q<'q<3rrr1rr	r$A9r A;r "r r r 8r 6r &r 0:r< 1(s s8 .(t ,(t6 *(u $u0 ,u0 "v *v rr9r44r9<sss54s58ttt32t36uuu-,u-0v vvvc                   Vf   V P                   pV P                  V,          pRpV'       d   RV R2pRpRpV P                  '       d<   V P                  R8w  d+   V P                  V P                  4      pRV R2pRV R	V R
2pRRRWPP	                  V4      ,           V,           /RRRV/.pRp	 V P
                  P                  P                  P                  V P                  VRR7      p
V
 FZ  pVP                  ^ ,          P                  p\        VR4      '       g   K4  VP                  '       g   KH  WP                  ,          p	K\  	  V	P!                  4       '       g   RVR,           R2p	VR,          P#                  RRRV	/4       V	#   \         d&   pRTR,           R2p	\        RT 24        R p?LlR p?ii ; i)Nz[System: A caller has just been transferred to you. Generate a warm, brief greeting (1-2 sentences). Introduce yourself and ask how you can help.]zJ[System: A caller has been transferred back to you. The caller's request: u   . Act on this request immediately in your response. Do NOT give a generic greeting or ask how you can help — go straight to fulfilling the request.]r6   rc   r  r  r  r  z. Never use English.r  r  r  rJ  T)r#  r  r*  zHello! This is r   z. How can I help you?z  [LLM] Greeting error: r   r  )rr  rj  rv  rr  r  r  r@  rA  rB  r   rC  r,  r4  r  rW   r6  r(   ra  )r  r  contextrv  r  rn  r  r  r  r  r*  r.  r,  rZ  s   &&&           r3   r9  "PipelineSession._generate_greetingQ  s   ))I{{9-< 	
 **1 3:;     T%:%:d%B(=(=>I6ykA_`K"DYK P55>K?S!U Xy+8T8TU^8_*_br*rsVY/

 	2XX]]..55nn! 6 F
  a(..5),,-H   ~~(f)=(>>STH 	Y&&[)X6	
   	2(f)=(>>STH,QC011	2s%   0A-F "F 6F F=F88F=c           
     P   Vf   V P                  4       pV P                  V4      p^p\        V4       EF  p\        V P                  V P
                  4      pWpn        \        WGRR7      p VP                  4        VP                  V\        P                  RVR,          VR,          VR,          R7       ^Pp	\        ^ \        V4      V	4       FF  p
VP                  '       d    M3VP                  WW,            4       \        P                   ! R4       KH  	  VP#                  4        VP$                  P'                  ^R	7        R V n         R # 	  R #   \(         d   pTP                  '       d)   TP$                  P+                  4         R p?R T n         R # Ye^,
          8  d7   \-        R
T^,            RT RT 24       \        P                   ! R4        R p?M8\-        RT RT 24       TP$                  P+                  4         R p?MR p?ii ; iR T n        EK    R T n        i ; i)Nr=   r  server_commitr   r   rP  r  response_formatmoder   r   rP  r   r  z  [TTS] Retry r  r   r#  z  [TTS] Error after z attempts: )rQ  rX  r  r   r/  r   ri  r   r  r  r   PCM_24000HZ_MONO_16BITr   r  append_textr7  r  finishr  r  rW   rc  r6  )r  r  r  r>  	tts_modelmax_retriesattemptr  tts
chunk_sizer  rZ  s   &&&&        r3   r  PipelineSession._run_tts  s   ;;=L++E2	[)G"499djj9H)1&!JC 2""$/$F$F( ,] ;+L9'1 #   
q#d)Z8A)))OOD1>$:;JJt$	 9 

""2". .2*O *8  	(%%%MM%%' .2* 1_,N7Q;-qRsKLJJsOO0[LMMM%%''	( .2*T*sC   +CEH,H
	H>H
H+H
H
HH	H%c                8  aaa[a\ Sf   V P                  4       o\        P                  ! 4       pV P                  pVR,          P                  RRRV/4       RpRpV P                  '       d<   V P                  R8w  d+   V P                  V P                  4      p	RV	 R	2pR
V	 RV	 R2pV P                  '       dk   V'       dc   W@P                  8w  dS   W@P                  9   dC   V P                  V4      p
V P                  V P                  4      pVRV
 RV RV RV
 R2	,          pWpP                  4       ,           R,           V,           V P                  4       ,           pRRRV/.VR,          ,           pRRV P                  //pV P                  R8X  d   V P                  pM/V P                  R8X  d   . pMVP                  R4      ;'       g    . pV'       d   \        V4      M. pV Uu. uF-  pVP                  R/ 4      P                  R4      R9  g   K+  VNK/  	  ppV Uu. uF  p\        V4      '       g   K  VNK  	  ppV UUUu. uF2  pVP                  4        UUu/ uF  w  ppVR9  g   K  VVbK  	  uppNK4  	  ppppV P                   pV P                  R8X  d,   V P#                  4       pV'       d   VP                  V4       EMV P                  R8X  Ed2   V P$                  '       d1   RV9  d*   V P'                  4       pV'       d   VP                  V4       V P(                  '       d'   RV9  d    VP                  V P+                  4       4       R V9  d*   V P-                  4       pV'       d   VP                  V4       R!V9  d*   V P/                  4       pV'       d   VP                  V4       RV9  d*   V P1                  4       pV'       d   VP                  V4       R"V9  d    VP                  V P3                  4       4       MVP                  V P5                  4       4       VP                  V P7                  4       4       R"V9  d    VP                  V P3                  4       4       RV9  d*   V P1                  4       pV'       d   VP                  V4       RpV P8                  R9   Ed   V'       Ed   V Uu. uF1  pVP                  R/ 4      P                  R4      \:        9   g   K/  VNK3  	  ppV Uu. uF1  pVP                  R/ 4      P                  R4      \:        9  g   K/  VNK3  	  ppV'       d   TpV P8                  R#8X  d>   V P=                  V4      V,           p\?        R%\A        V4       R&\A        V4       R'24       M?V PC                  V4      pV.V,           p\?        R(\A        V4       R)\A        V4       R'24       V'       g   Rp\E        RR*V PF                  R+VR,R-/VB pV PH                  e   V PH                  VR.&   V PJ                  e   V PJ                  VR/&   V PL                  e   V PL                  VR0&   V'       d   VVR1&   \        P                  ! 4       p\O        R2 V 4       4      p \?        R3\Q        VV,
          R4,          4       R5\A        V4       R6V  R7V PJ                   R82	4       V PR                  P                  R9\A        V PR                  4      ^,           R:\T        PV                  ! 4       PY                  R;4      R<V P                  R=VP                  RR4      R+V U!u. uF  p!\E        V!4      NK  	  up!R1V/4       \[        V P\                  V P^                  4      o[S[V n0        \b        Pd                  Pg                  ^R>7      p"V Pi                  S4      o\V[V\VV3R? lp#V"Pk                  V#4      p$Rp%Rp&Rp'Rp(Rp)R@p*Rp+Rp,Rp-Rp.^ p/^ p0\        P                  ! 4       p1\l        Pn                  ! RA4      p2\?        RB\Q        V1V,
          R4,          4       RC24       V Pp                  RD8H  p3\?        REV3'       d   RFMRG 24        V Pr                  Pt                  Pv                  Px                  ! R/ VB p4\        P                  ! 4       p.\?        RH\Q        V.V1,
          R4,          4       RI24       V4 EF  p5S[Pz                  '       d=   \?        RJ\Q        \        P                  ! 4       V,
          R4,          4       RI24        EMV5P|                  ^ ,          P~                  p6\        V6R4      '       Ed   V6P                  '       Ed   V+f<   \        P                  ! 4       p+\?        RK\Q        V+V1,
          R4,          4       RI24       V%V6P                  ,          p%V&V6P                  ,          p& V2P                  V&4      p!V!'       g   MV&V!P                  4       R p&V0^,          p0K9  V3'       g   S[Pz                  '       g   V)f   \        P                  ! 4       p7V$P                  ^
RL7      p)\        P                  ! 4       p-\Q        V-V7,
          R4,          4      p/\        P                  ! 4       p,\?        RM\Q        V,V,
          R4,          4       RNV/ ROV6P                  RP,           RQ24       V)P                  V6P                  4       R-p*\        V6RR4      '       g   EK*  V6P                  '       g   EK?  V6P                   F  p8V8P                  '       g   K  V8P                  P                  '       d   V'V8P                  P                  ,          p'V8P                  P                  '       g   Kn  V(V8P                  P                  ,          p(K  	  EK  	   \        P                  ! 4       p:\Q        V:V1,
          R4,          4      p;\?        RUV; R5V0 RV\A        V%4       RW24       ^ p<VRJ;'       d    T';'       d
    V'\:        9  p=T'p>V='       d   V P8                  R$8X  d/   V'RX8X  d(    \        P                  ! V(4      P                  RYR4      p>V P                  VV>4      p?V?f*   R@p=V P8                  R$8X  d   RZMR[p@\?        R\V@ R]V> R^24       V='       Ed   \        P                  ! 4       pAV P8                  R$8X  d   RZMR[p@\?        R\V@ R_V> R`V( Ra24       V P\                  P                  V P^                  P                  RbRcRdReRfV>RgV P8                  /4       RRRV/.VR,          ,           RRRRhV> RiV> Rj2/.,           pB\E        RR*V PF                  R+VBR,R-/VB pCV PH                  e   V PH                  XCR.&   V PJ                  e   V PJ                  XCR/&   V PL                  e   V PL                  XCR0&   X?.XCR1&   V PR                  P                  R9\A        V PR                  4      ^,           R:\T        PV                  ! 4       PY                  R;4      R<V P                  R=VP                  RR4      R+XB U!u. uF  p!\E        V!4      NK  	  up!R1V?.Rk^/4       T%pDRp%Rp'Rp( V Pr                  Pt                  Pv                  Px                  ! R/ XCB pEVE EF}  p5S[Pz                  '       d    EMjV5P|                  ^ ,          P~                  p6\        V6R4      '       ds   V6P                  '       da   V%V6P                  ,          p%V3'       gF   S[Pz                  '       g4   V)f   V$P                  ^
RL7      p)V)P                  V6P                  4       R-p*\        V6RR4      '       g   K  V6P                  '       g   K  V6P                   F  p8V8P                  '       g   K  V8P                  P                  '       d   V'V8P                  P                  ,          p'V8P                  P                  '       g   Kn  V(V8P                  P                  ,          p(K  	  EK  	   \Q        \        P                  ! 4       XA,
          R4,          4      p<V;V<,          p;\?        R\X@ RmT< RnT';'       g    Ro Rp\A        V%4       Rq2	4       XD'       d4   V''       d   XDp%M(V%'       d   XDRr,           V%,           P                  4       MXDp%V3'       Ed   V%'       Ed   S[Pz                  '       g   V)fT   \        P                  ! 4       p7V$P                  ^
RL7      p)\Q        \        P                  ! 4       V7,
          R4,          4      p/\        P                  ! 4       p,\?        Rs\Q        V,V,
          R4,          4       RtV/ Ru\A        V%4       RW24       \        ^ \A        V%4      ^4       F2  pFS[Pz                  '       d    MV)P                  V%XFVF^,            4       K4  	  R-p*\        P                  ! 4       pGV)f    V$P                  ^RL7      p)V)'       d6   V*'       d.   V)P                  4        S[P                  P                  ^RL7       MS[P                  P                  4        \        P                  ! 4       pH\Q        VHXG,
          R4,          4      pI\Q        VHV,
          R4,          4      pJRV n0        V"P                  R@Rv7       \?        RwVI RI24       \?        RxTJ RyV,'       d   \Q        V,V,
          R4,          4      MRz R{24       R|\Q        VV,
          R4,          4      R}V.'       d   \Q        V.V1,
          R4,          4      M^ R~V+'       d   \Q        V+V1,
          R4,          4      M^ RV,'       d   \Q        V,V,
          R4,          4      M^ RV/RV;RXIRXJR\A        \        4      RV<RcV P8                  /pKV''       g   V%'       d   \l        P                  ! RV%4      pLVL'       d]   XLP                  ^4      p'VLP                  ^4      ;'       g    Rp(V%RXLP                  4        P                  4       p%\?        RV' 24       MR\l        P                  ! RV%4      '       d6   R"p'Rp(\l        P                  ! RRV%4      P                  4       p%\?        R4       V'R8X  d   V P$                  '       d   RpMRpN \        P                  ! V(4      pOVOP                  RR4      pMVOP                  RR4      pNVR,          P                  RRRT%;'       g    RRRRRRbRRRRRV(//./4       RbRRV%RXMRXNRV*RV;RXK/# V'R8X  dm   RpM \        P                  ! V(4      pOVOP                  RR4      pMVR,          P                  RRRT%;'       g    RRRRRRbRRRRRV(//./4       RbRRV%RXMRV*RV;RXK/# V'R8X  d   / pP \        P                  ! V(4      pPVR,          P                  RRRT%;'       g    RRRRRRbRRRRRV(//./4       VR,          P                  RRfRRRR/4       XPP                  RR4      P                  RrR4      pQRbRRV%RVPP                  RR4      RVQRVPP                  RR4      RV*RV;RXK/# V'R8X  d|   V P                  R8X  dk   RpR \        P                  ! V(4      pOVOP                  RR4      pRVR,          P                  RRRT%;'       g    RRRRRRbRRRRRV(//./4       RbRRV%RXRRV;RXK/# V'R8X  d|   V P                  R8X  dk   RpM \        P                  ! V(4      pOVOP                  RR4      pMVR,          P                  RRRT%;'       g    RRRRRRbRRRRRV(//./4       RbRRV%RXMRV;RXK/# V'R8X  d|   V P                  R8w  dk   RpR \        P                  ! V(4      pOVOP                  RR4      pRVR,          P                  RRRT%;'       g    RRRRRRbRRRRRV(//./4       RbRRV%RXRRV;RXK/# V'R 8X  d   V P\                  P                  V P^                  P                  RbRRV'RV(/4       V P                  RRV' R`V( R824        V('       d   \        P                  ! V(4      M/ pSV P                  XS4      pTV P                  R VSVT4       VR,          P                  RRRRRRRRV' 2RbRRRV'RV(//./4       VR,          P                  RRfRRV' 2RVT/4       RbRRRRV;RXK/# T';'       d    V'R9  pUVU'       d   V P\                  P                  V P^                  P                  RbRRV'RV(/4       V P                  RRV' R`V( R824        V('       d   \        P                  ! V(4      M/ pVV P                  V'XV4      pWVWe"   VR,          P                  RRfRRV' 2RXW/4       V%P                  4       '       g1   XU'       d   V'R"8X  d   RpXV P                  VX4      p%MXU'       d   Rp%MRp%RRRT%;'       g    R/pYXU'       d   RRV' 2RbRRRV'RV(//.XYRR&   VR,          P                  XY4       \A        VR,          4      ^8  d   VR,          RR VR&   RbRRV%RV;RV*RXK/pZV'R"8X  d   R-XZR"&   XZ# u upi u upi u uppi u upppi u upi u upi u up!i   \         d&   p9T%;'       g    RSp%\?        RTT9 24        Rp9?9ELRp9?9ii ; i  \        P                  \        3 d    Rp> ELdi ; iu up!i   \         d)   p9T%;'       g    RSp%\?        R\X@ RlT9 24        Rp9?9E
LRp9?9ii ; i  \         d     E	Li ; i  \        P                  \        3 d    T(pM ELdi ; i  \        P                  \        3 d    T(pM ELi ; i  \        P                  \        3 d     ELi ; i  \        P                  \        3 d     ELi ; i  \        P                  \        3 d    T(pM ELi ; i  \        P                  \        3 d     ELPi ; i  \         d    / pS ELi ; i  \         d    / pV ELi ; i)zmStream LLM output to TTS sentence-by-sentence for low latency.
Pre-connects TTS in parallel with LLM startup.Nr   r  rJ  r  r6   rc   r  r  r  r  rV  rW  rX  rY  rZ  r2  r  r  r?  r   r   r  r   r  r   r  r  r'  r-  r1  r8  r=  r#  r*  r+  z  [TWO-TIER] z custom tool(s) stubbed, z built-in kept fullz  [META-TOOL] u    custom tool(s) → 1 router, r#  r  r*  Tr   r   r   rg  c              3   l   "   T F*  p\        VP                  R R4      ;'       g    R4      x  K,  	  R# 5i)r  r6   N)r   rT   )r   r  s   & r3   r   9PipelineSession._run_pipeline_streamed.<locals>.<genexpr>8  s+     JAAEE)R066B77s   "44z  [TIMING] kwargs built: r"  zms (z msgs, ~z chars, max_tokens=r  r  r  r  r  r  )max_workersc                    < \         P                   ! 4       p \        SSR R7      pVP                  4        \         P                   ! 4       pVP                  S\        P
                  RSR,          SR,          SR,          R7       \         P                   ! 4       p\        R\        W ,
          R,          4       R	\        W2,
          R,          4       R
\        W0,
          R,          4       R24       V# )r=   r  r  r   r   rP  r  z  [TIMING] TTS connect: r"  zms, session update: zms, total: rg   )r7  r   r  r  r   r  r6  rY  )tc0r  tc1tc2r  r  r>  r  s       r3   _connect_tts<PipelineSession._run_pipeline_streamed.<locals>._connect_ttsN  s    ))+C!(JC KKM))+C + B B$(7'5#H-   ))+C,S#)T1A-B,C D%%(#)T)9%:$; <D 012"6 7 Jr  Fu   [.!?。！？;；:：\n]\s*z!  [TIMING] LLM request starting: zms since entryr)  z  [TIMING] TTS mode: zBATCH (wait for full LLM)zSTREAMING (token-by-token)z  [TIMING] LLM stream opened: rg   z  [TIMING] Cancelled at z  [TIMING] LLM first token: r  z  [TIMING] First text -> TTS: zms total (TTS wait: r8  :N(   Nr  r[  z"I'm sorry, I encountered an error.z  [LLM] Streaming error: z  [TIMING] LLM stream done: z sentences, z chars)rp  rq  z	META-TOOLzTWO-TIERr  z] WARNING: "z(" has no full tool def, skipping re-callz] Routed to: rQ  u   ) — re-calling with full toolr   r   rU  recallr[   r  zThe caller needs the z action. Call z; now with the correct parameters based on the conversation.two_tier_roundz] Round 2 error: z] Round 2 done: z	ms, tool=z(text only)r    charsr  z  [TIMING] Batch send to TTS: zms (TTS wait: zms, )r  z  [TIMING] TTS finish+drain: u     [TIMING] ═══ TOTAL: u   ms ═══ (first audio ≈rd  z ms)setup_msllm_connect_msllm_first_token_msfirst_audio_mstts_wait_msllm_total_mstts_drain_msr@  r   	recall_msr\  r]  r^  r_  r`  ra  r  r  r  rm   r  rC  rl  r  r  r  r   r3  r  rb  r  rc  r  r  r(  rd  r"  re  rf  rV  ra  rg  r  rh  ri  rj  r  )r*  r+  r   rk  )drQ  r7  r  ra  rv  rr  r3  r  r  r   rr  r   rT   r   rb   rm  r   r*  rl  r  rn  r.  r:  r?  r5  r$  r  r   r   r  rm  r6  r   rt  r^  r   r   r   r   r1  rY  rz  r   rX   rY   r   r/  r   ri  
concurrentfuturesThreadPoolExecutorrX  submitr  compiler   r  r@  rA  rB  r  rC  r,  r4  r  r  rS   rD  r  r[  r  r   rC  rW   r   r&  r   rW  rw  rm  r   r(   r  r  r  r  rc  shutdownr   r  rR   rl  r  r  r  r_  rF  r  rG  )]r  r  r  r>  r  t0r  rn  r  r  ro  rp  rq  r  rr  r{  rg  r   r0   r2   r  r  r  r  r  r  full_custom_toolsbuiltincustommetaru  t_setup	msg_charsr  tts_poolr  
tts_future	full_textsentence_bufferrs  rt  r  tts_usedt_first_tokent_first_sentencet_tts_readyt_llm_connectedtts_waitsentence_countt_llm_startsentence_re	use_batchr*  r.  r,  t_before_tts_waitrv  rZ  
t_llm_doner  r  needs_recallrecall_tool_name	full_tooltagt_recall_startmessages_r2	kwargs_r2round1_text	stream_r2r  t_tts_finish_start
t_tts_doner  r@  r   rw  r  r  rE  rx  ry  r  rz  r{  r|  r}  rg  r=  r~  r  r  r  s]   &&ff&                                                                                      @@r3   r:  &PipelineSession._run_pipeline_streamed  s    ;;=LYY[iJ GH   T%:%:d%B(=(=>I6ykA_`K"DYK P55>K @U!V !!!h 5 55 8 88!%!: $0E0E F67I6J K//@.A B''8&99_`r_sstvw !#?#?#AAmn#>>@A
 Xy*5
)  143G3GHI #++K&(K))N399rK%0[!b! )EqEE*b)--f5 >( ( E ) ";Eq%7%:E; SXYRWQ $%779 I941aGG !Q$9 IRW 	 Y**&224CS!#%+++t0K $ 9 9 ; LL/***/@/LT==?@!-"&"C"C"E"LL1t+ $ ? ? A LL/ ,">>@LL-%T6689LL779:LL3356%T6689 ,">>@LL- ! 99ee"' S%Q%%
B/33F;?QQ q%G S!& VAz2.226:BTT aF V$*!$$
2 11&9GCEM#f+6O \N*=? @  008D!FW,EN3v;-7U \N*=? @ETDNNTXTdTeT'$($4$4F=!??&#'??F< ::!"jjF7O#F7O))+JJJ	)#w|T.A*B)C Dh-3FtFWWXZ 	[ 	C(1,00<T&&%))FB/(3(Qa(3U 
 	 tyy$**5%-"%%88Q8G++E2		 	, __\2
 	iikjj!?@1#{R7G6M2N1O~^_]]g-	%Y&ATp%qrs6	3XX]]..55??F"iikO23+8UW[7[3\2]]_`a%%%4S$))+:JD9P5Q4RRTUVa(..5),,$,(,		 <S-R]B]_cAc=d<eeghi.I#u}}4O '..? !*9!%%'(*C&!+ %X-?-?-?;04		-","3"3B"3"?C*.))+K'*K:K,Kt+S'TH/3yy{,!$B%(*:R*?)E%F$G H008z :&&+mmC&8%9#? @ 6#'5,//E4D4D4D#..;;;!{{/// ."++2B2B B!{{444 ."++2G2G G /Q  f YY[
j;.$67,VH 5 !c)n-=WF 	G 	T) 9 99 9&88 	
 *  K/Nl4R*'+zz.'A'E'EhPR'S$ ,,->@PQI $%)%6%6+%Ek:C5-=,> ?? @ A <!YY[N!%!2!2k!A+zCCuM*:);1^<L M2 3 4 II**

%%()643D3DF #HiDEiHXX9+,<+= >,- .12\ K  34>> 3K 3$(3,13I++/+;+;	-(**.//	,'zz%%)ZZ	'""+Ig OO""DOO,q0X\\^44Z@**eii3k:kT!Wk:) !$  $KINN7 HHMM55<<IyI	&E)))!MM!,22Eui00U]]]!U]]2	(1C1C1C"{&0&7&7&7&COOEMM:'+Hul338H8H8H"'"2"2B!{{{#%;;#3#3#3$2bkk6F6F$FN#%;;#8#8#8$2bkk6K6K$KN #3 ', TYY[>9TABIiFCu,YK 8(99M:"S^<LFT U ! +I %. #."3i"?!F!F!H3>  98+=+=+={$(IIK! '''3		.? ?4GH#yy{238H28Mt7S3T2U V  (zc)n-=WF G 1c)nc2%%%	!AG 45 3 H "YY[; '''2 8JJLMMr*MMYY[
J);;tCD
R4/0%)"u%-l^2>?,XJ 7!FV&6&;T%A!B\_ ``df 	g
 Wr\T12_c?[#@D"HIbc }#}{'Bd&J"KbcEUc#3b#8D"@A[\8FLs?3D--
 )yy>	KH!)!2!)!2!:!:d%&7x~~'78??A	>~>NOP.	::!+!%FF#92yIPPR	AC _,1M1M1MFJ(zz.1(B/!XXlB7
 )##9,,/J+~ V  %  J	8V *lHfi: :
 _,F(zz.1(B/ )##9,,.J+~ V  %  OVY& (fi: : [(G**^4 )##9,,*Jk> R  %  )## 0D%  {{#3R8@@bIHVY_b!A ('++h3h&)W  ..43D3D3NDzz.1xx
B/ )##9,,0J):K X  %  /JPTfi: : ..43D3D3KF(zz.1(B/ )##9,,0J):K X  %  -vy(Ffi: : ..43D3D3NDzz.1xx
B/ )##9,,0J):K X  %  -vy*dfi: : //II**

%%fnk>Z h*^4DAnEUUV(WX9G4::n5R 55h?I##$6)L)##YE.!12Jn U  %  )##%'7 89% 
 JHfiQXYY  # #~ 6#  # 	
 II**

%%fnk>Z h*^4DAnEUUV(WX ;ITZZ7r
 44^ZPJ%i ''F"eN+;$<z)    !n
&B< 11(;	#	Q	  i9J9JdKn-.
V^[.Q, +M,'
 	i.uY 1$$Y/4E)
FIxh	7<Z'#Du) <I YRSVJ 4Z  	3!II%II-aS122	3. ,,i8 *')$*` ;@  7%MM)M	C5 1!5667P  p (()4 ('(* (()4 ('(& (()4 B (()4 ( (()4 ('(( (()4 .  B   
 s3  '(AiAi Ai8AiAiAi/Ai6Ai,Ai3Ai?,Ai$0Ai$9Ai)B=Ai. AAi. A>Ai. &Ai. Ai. CAi. 1Ai. Ai. )Ai. 6Ai.  &Ai. 7&Aj! >Ak(A	Ak
 3A Ak
 4Ak
 Ak
 !AAk
 (Ak
 <Ak
 Ak
 ;6Ak
 6&Ak
 G%Al  R:Al T(Al6 VAm Y$(Am< [&(An ]((Ao `&Ao$ `.Ao$ d(Ao8 d0Ao8 iAii.Aji9AjjAjj!AkkAkk
Ak=kAk8k8Ak=l AllAllAl3l2Al3l6AmmAmmAm9m8Am9m<AnnAnnAn?n>An?oAo!o Ao!o$Ao5o4Ao5o8Ap	pAp	)~rh  ri  r   r5  r  r  r  r  r  r  rV  rW  rU  rX  r>  r?  rq  r  rO  r;  r:  r=  r8  rH  rK  rN  rL  rM  r9  r@  rQ  rA  rB  r<  rI  rJ  rE  rG  rF  rD  rR  rC  rw  r}  r|  rg  r  r\  r  r  r  r  r  r  r  r  r  r  r  r  r  ru  rr  r  rp  r   rj  rt  r{  r   r   ry  r   r  r  r  r   r  r  r   rZ  r  r  r  r  r   re  r   r   r   r   rn  r  ro  r  r   r/  r   r  r   r5  r   r   r   r   r   rz  r   rx  rv  r~  r   r   rs  r   r3  r   r   r   rl  r   r   r   r   r   r.  )rc   r  )r   r  )NNN)d__name__
__module____qualname____firstlineno____doc__r  propertyr  staticmethodrd  rf  r[  r  r  r  r  r   r$  r*  r.  r5  r:  r?  rF  r_  rm  rt  rw  r|  r  r  r  r  r  r  r
  r  r  rL  r'  r]  rX  r~  r  rt  r  r  r  r  r  r  r  r  r  r  r  r$  r(  r1  r  rr  r  rG  rJ  rM  rQ  rX  r  r  r  r  rs  r  r  r  r  r.  rh  r  r  r  r  r  r  r  r  r8  r  r  r  r  r  r(  r  r  r9  r  r:  __static_attributes____classdictcell__)__classdict__s   @r3   r   r     s    
b>H . . & &  " L# L#\4& 
D
4!
F
0
6
0
@
<"
H3 j  , "
 "
H  
&8
v.tUn	.%IN^@C*:&<"C>JD:L*X)DV:(x8@H+%DN
\,{,z
"HT7.rHRT..*;B.	
+2&T D" ,1f',T*0(4&V5$n6It$( 9 9.4`#
"B$'!'F32nn/d\@6t-2bH
 H
r  r   c                	  "   VP                  R4      pVR8X  d8   V P                  \        P                  ! RRR\        /4      4      G Rj  xL
  R# VR8X  EdE   VP                  RR4      P                  4       pVP                  RR4      pV'       d	   V'       g4   V P                  \        P                  ! RR	R
R/4      4      G Rj  xL
  R# \        RV R24        \        P                  ! \        RR\         2RR/R\        RRRR\        RVRRV///^R7      pVP                  4       pVP                  ^8X  d   RV9   d   VR,          R,          pVR,          P                  R\        4      pRVRVRVR\        P                  ! 4       P!                  R4      /p	\        P#                  V	4       \%        \        4       \        RV 24       V P                  \        P                  ! RR RV	/4      4      G Rj  xL
  R# VP                  R
4      ;'       g7    VP                  R!/ 4      P                  R
\        P                  ! V4      4      p
\        R"V
 24       V P                  \        P                  ! RR	R
\'        V
4      /4      4      G Rj  xL
   R# VR$8X  EdO   VP                  R%R4      pV'       g4   V P                  \        P                  ! RR&R
R'/4      4      G Rj  xL
  R# \+        \        4      p\         Uu. uF  qR,          V8w  g   K  VNK  	  ups\+        \        4      V8  d   \%        \        4       \        R(V 24        \        P                  ! \        RR\         2RR/R\        RRR)RV//^
R7       V P                  \        P                  ! RR*R%V/4      4      G Rj  xL
  R# V P                  \        P                  ! RR&R
R+/4      4      G Rj  xL
  R# R#  EL EL1 EL ELi  \(         dU   p\        R#T 24       T P                  \        P                  ! RR	R
\'        T4      /4      4      G Rj  xL 
   Rp?R# Rp?ii ; i ELxu upi   \(         d     Li ; i L L5i),zEHandle voice clone/list/delete over a temporary WebSocket connection.r   
voice_listr   Nvoice_cloner   r6   r  voice_clone_errorr  zName and audio are required.z[VoiceClone] Cloning voice: "z"...r  r  r  r  r#  inputrq  rB  rT  preferred_namer=  )r  r   r  rc  r  rm   createdr  z[VoiceClone] Success: voice_clone_okr  z[VoiceClone] API error: z[VoiceClone] Error: voice_deletevoice_idvoice_delete_errorzvoice_id is required.z[VoiceClone] Deleted: deletevoice_delete_okzVoice not found.)rT   r  r   r  rU  r(   r6  r  r  VOICE_ENROLLMENT_URLr  VOICE_ENROLLMENT_MODELrV  r  r   rX   rY   ra  r   r`  rW   r   )r.  r   msg_typer   
audio_datar  rD  r  rT  r  errrZ  beforer2   s   &&            r3   handle_voice_managementr  L  sX     wwvH<ggdjj&,-!PQRRR= wwvr"((*WWWb)
:''$**f.A&/1O&Q R S S S-dV489&	X==$#wwi%8"$6
 3 (&($&*!5	 D" YY[F3&8v+=!(+G4%h/33NLQ(D"Lx||~667JK	 $$U+#M2.xj9:ggdjj&2BGU)STUUU 	 jj+iivzz'2/F/J/J9VZV`V`agVh/i067ggdjj&2EyRUVYRZ)[\]]] 	>!77:r*''$**f.B&/1H&J K L L L ]#$1IMqtW5HMI}&.*8*56('77))<&(:
  !7(Hgx!H  ''$**f.?X%VWXXX 	 ''$**f.B&/1C&E F G G GC "k 	SSH V ^ 	X(,-''$**f.A9cRSf%UVWWW	XL J$  XGs  A	RO6ARR,RO9	RDP =O<>P RP A:P O?P $R ,R,Q$-R
Q'Q'$4R5Q, ,R:Q=;2R-Q?.	R9R<P ?P Q!AQQQRQ!!R'R,Q:7R9Q::R?Rc                   "   V P                   p\        R V 24       / p \        P                  ! V P	                  4       ^
R7      G Rj  xL
 p\
        P                  ! V4      pVP                  R4      R?9   d   \        W4      G Rj  xL
  R# VP                  R4      R8X  Ed   RV9   d   VR,          p\        V\        4      pVf]   \        RV 24       V P                  \
        P                  ! RRRR	V 2/4      4      G Rj  xL
  V P                  4       G Rj  xL
  R# VP                  4        F  w  rgVR@9  g   K  WrV&   K  	  WRR
&   \        RV 24       MTp\        RVP                  RR4       24       VP                  R/ 4      pV'       d   \        RV 24       VP                  R. 4      p	V	'       dK   V	 U
u. uF  qP                  RR4      NK  	  pp
\        R\        V4       RRP!                  V4       24       M\        R4       \        VP                  R. 4      4      p\        VP                  RR4      4      p\        RVP                  R\"        4       RV 24       V'       d   \        RV R24       VP                  R 4      '       d    \        R!VP                  R"R#4       R$24       VP                  R%/ 4      pVP                  R&4      '       d   \        R'VP                  R(R4       24       VP                  R)/ 4      pVP                  R&4      '       d   \        R*VP                  R+R,4       24       VP                  R
R4      p\        R-V: R.\%        VP'                  4       4       24       V'       Ed   / pVP                  4        EF  w  ppVRA9   d   K  \)        V\$        \*        34      '       Ed   VR/8X  d   \)        V\$        4      '       d   . pV Fm  p\)        V\*        4      '       g   K  VP-                  4        Uu. uF  pV'       g   K  \/        V4      NK  	  ppVP1                  R0P!                  V4      4       Ko  	  V'       d   R1P!                  V4      MR2\        V4       R32VV&   VVR4&   MVR58X  d   \)        V\$        4      '       d   . pV Fx  p\)        V\*        4      '       g   K  VP                  4        UUu. uF  w  ppV'       g   K  V R6V 2NK  	  pppV'       g   KX  VP1                  RP!                  V4      4       Kz  	  V'       d   R1P!                  V4      MRVV&   VVR7&   EK  Ve   \/        V4      MRVV&   EK  	  V\2        V&   \        R8\        V4       R9V: R6\%        VP'                  4       4       24       M\        R:4       \9        V \        P:                  ! 4       V4      p\<        P?                  V4       \A        4         VPC                  4       G Rj  xL
  \<        PE                  V4       \A        4        \        R<V R=\        \<        4       R>24       R#  EL EL ELO EL:u up
i u upi u uppi   \        P4                  \
        P6                  3 d    \        R;4        Li ; i L  \<        PE                  T4       \A        4        i ; i5i)Bz
[Client] Connected: r  Nr   r  r  z[Config] Profile not found: r  r  zProfile not found: r  z[Config] Profile: z[Config] Agent A: r   r   r   z[Config] Voice map: r   r   rd  z[Config] Transfer targets (r  r   z[Config] Transfer targets: noner   r   r6   z[Config] LLM: r   z	, tools: z[Config] Agent data: r  r   z [Config] Barge-in: enabled (min r   r   r%  r  r  u   [Config] ACRS: enabled → r  r%  u(   [Config] Emotion Detection: enabled → r&  r'  z[ConfigVars] _profile_name=z, config keys=r   r   r   rQ  z	 entries)_raw_extensionsr   r   _raw_Outgoingz[ConfigVars] Stored z vars for profile u<   [ConfigVars] No _profile_name in config — snapshot skippedz[Config] Using defaultsz	[Client] z disconnected (active: r  )r  r  r  )r   r  )r   r  )#remote_addressr6  r0  r  recvr   r&  rT   r  r   PROFILES_COLLECTIONr  r  r  rm  r   r"   rY  r   r_  r2  r^  r  r`  ra  _LAST_CONFIG_VARSr   r   r   get_event_loopr   addr   r  discard)r.  addrr  r<  r   profile_namer0   r2   vmr   r   r8  tools_countdata_lenacrs_cfgr  _pname	_snapshotr  r  r  r  _evr  r  r  _ok_ovr  s   &                            r3   handle_clientr    s    D	"4&
)*F[)$$RWWY;;jjo 776?KK)"222776?h&C"9~,\;NO>8GH''$**!%8#G. #    ((*$$IIKDA 33$%q	 ( +7'*<.9: &vzz..'Q&RSTK,B,RD12$jj):B?O5DE_vs+_E3CJ<s499UCSBTUV79fjj<=K6::lB78HN6::k9#E"F G'=* +-hZv>?zz,-- $jj)CSIJ#O Pzz&"-H||I&&3HLLB4O3PQR **Y3Ky))@Q]_tAu@vwxZZ4F/zV[[]H[G\]^v	$llnFB66 !"tTl33-*R2F2F)+J&(#-b$#7#7BD))+-U+3QThc#h+F-U$.$5$5ejj6H$I ') FPDIIj,AWXY\]_Y`XaajUkIbM;=I&78:-*R2F2F)+J&(#-b$#7#7NPhhj-`j(#s\_oRuojF-`'-v(2(9(9$))F:K(L	 ')
 FPDIIj,AUWIbM9;Io6 /1~CG2IbM- -. -6!&),S^,<<NvjXZ[_`i`n`n`p[qZrstTU
 b'"8"8":FCG  kkm(	IdV233G2H
JKI <
 3 %$ F@ .V .a   $"6"67 )'() 	(s9  [)Y, 	Y
>Y, Y	Y, [A8Y, YY, Y Y, $[&Y, A<Y, Y, YB?Y, AY, 'AY, .CY, Y, 
Y!,Y!;-Y, )A Y, Y, !Y&
3Y&
>Y, +Y, 7A5Y, ,[-Y, 8?[8Z$ Z"Z$ A [Y, Y, Y, Y, Y, ,0Z[Z["Z$ $![[
recordings)exist_okc                      \        \        \        \        \        \
        \        \        \        \        \        \        R 7       \        R\        3\        4      p V P                  4        R# ))http_dirrecordings_dirprofiles_collectionconversations_collectionr  llm_baser   r  tts_vc_modelr  cloned_voices_ref0.0.0.0N)r   HTTP_DIRr  r  r  r  r  rY  rW  rV  r  rU  r   	HTTP_PORTr   serve_forever)httpds    r3   
start_httpr    sK    %/!9!' 	9-/BCE	r  c            	        "   \         P                  ! \        R \        ^^
RR7      ;_uu_4       GRj  xL
  \	        R\         24       \	        R\
         R24       \	        R4       \	        R\         24       \	        R\         R	24       \	        R
\         24       \	        R4       \        P                  ! 4       G Rj  xL
  RRR4      GRj  xL
  R#  L L L
  + GRj  xL 
 '       g   i     R# ; i5i)r  )r  r  r  Nz  WebSocket : ws://localhost:z  Test page : http://localhost:z/qwen_pipeline_test.htmlz
  Pipeline:z
    STT : z
    LLM : z (with function calling)z
    TTS : z
  Waiting for browser...
i   )r:  server  WS_PORTr6  r  r  rY  rW  r0  Futurer   r  r3   mainr  2  s     y'rJ   	-gY78/	{:RST
9+&'
9+%=>?
9+&',.nn   	   s]   1C<CC<BCCCC<CC<CC<C9	%C(&
C9	1C9	3	C<__main__u(     Qwen Pipeline — STT + LLM + TTS Testz  With Call Transfer Demo)rE  daemon>
   MiaMaiaRyanr   AidenCindyr   HarveySerenaJennifer>	   r#  r  r  r  r=  r-  r'  r1  r8  z2==================================================)r  r0  r   r    r  sysr7  	threadingconcurrent.futuresr  r   	functoolsurllib.parseurllibhttp.serverr   r)  r/  r2  r  r  r   r   r   r   r   r	   r
   r   r   r   	callbacksr   r   r   _CB_OMNIri  rW   profile_configr   r   acrs_dispatchr   r   http_routesr   r   urllib3disable_warningsr  InsecureRequestWarninggenerated_handlersr   
_gen_countr6  ImportErrorr:  exitopenair   !dashscope.audio.qwen_tts_realtimer   r   	dashscopedashscope.audio.qwen_omnir   OmniAudioFormatr   r4   getenvr  r  r7   rY  r  r  r  r  r  rS  r  rY  rW  rV  r  r  r!   r"   r#   r$   r%   r   r7  r  r  	frozensetr  r  r  _DAY_MAPrb   r  chromadbPersistentClientCHROMA_CLIENTget_or_create_collectionr  r  r   _profile_count_convo_countrZ  r   r   rU  r   rc  r   r   r   r  r  r  r  makedirsr  r  r  ThreadrR   r  r   r  r3   <module>rG     s     	 	 
       "       P O B E =    ++BB C	:(*J!*-BCD
:6A Y    D 	

))'
,	
/0	
GHHHQK	 +R0 bii*F3
4		.78	99^%[\&	J% C	1	10 d WW\\"''//"''//(2K"LNbc  *
B	
 !c=$# "dM3$	            1eQq%E1eQqQ:)9&*G*H&*L 	&  ',[ 	)	 8	 &*8	
 	)
 <
 *.y 	( '
$--WW\\"''//"''//(*CDkRTM'@@  A ",EE   F  "(..0N+113L	!.!1\N.
YZ' $%=	 ]!3 44D
EF %	vL vL|Y\~jL\ 77??277??845h5 NT *( z	(O	
45	
%&	(OJt4::<KK qh    		  :	
+,chhqk:
  6	
'(#((1+6  A	
23SXXa[A  Y	
WXYT  $	
VW# $	+A3.B
CD#$s   *Q 1Q Q Q# R R3 ,S 5B6S3 	QQQ Q #!RR!R0/R03!SSS0/S03T*	T*T*T%%T*