+
    iP)                    B  a  0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIH	t	 ^ RI
HtHt ]P                  ! R4      t/ tR]R&   ]! ]P$                  ! RR	4      4      tR
 R ltR R ltR R ltRRRRRRRR/R R lltRRRRRRRR/R R lltRRRRRRRR/R R lltR# )ak  
Load runtime settings from cluster DB table `business_id_agents` (livekitvoicebot_cluster).

Schema varies by deployment: some rows use only `business_id`, `name`, and JSON `config`;
others add `role`, `agent_id`, `user_id`, `email`, etc. We introspect columns and merge
`config` JSON over scalar columns so all values stay dynamic (no hard-coded column lists).
)annotationsN)Any)unquoteurlparsezmcube.business_id_agentsz:dict[tuple[Any, ...], tuple[float, dict[str, Any] | None]]_CACHEBUSINESS_ID_AGENTS_CACHE_TTL_S120c                    V ^8  d   QhRRRR/# )   urlstrreturndict[str, Any] | None )formats   "dE:\live-kit-agent\livekit_voicebot\backend\agent_runtime\src\mcube_integration\business_id_agents.py__annotate__r      s      # *?     c                X   T ;'       g    R P                  4       p V '       g   R# \        V 4      pVP                  R9  d#   \        P	                  RVP                  4       R# \        VP                  ;'       g    R 4      p\        VP                  ;'       g    R 4      pVP                  ;'       g    Rp\        VP                  ;'       g    R4      pVP                  ;'       g    R P                  R4      P                  R^4      ^ ,          pV'       g   R# RVRVR	VR
VRVRRRR/# ) Nz>business_id_agents: unsupported DATABASE_CLUSTER_URL scheme=%s	localhosti  /?hostportuserpassworddatabasecharsetutf8mb4cursorclass)mysqlmysql2mariadb)stripr   schemelogwarningr   usernamer   hostnameintr   pathlstripsplit)r   parsedr   r   r   r   dbs   &      r   _parse_mysql_cluster_urlr0      s    99"


Cc]F}}::TV\VcVcd6??((b)Dv,,"-H??))kDv{{""d#D
++

	#	#C	(	.	.sA	6q	9BHB9t r   c                    V ^8  d   QhRRRR/# )r
   rowdict[str, Any]r   r   )r   s   "r   r   r   2   s      n  r   c                   / pV P                  R4      p\        V\        \        34      '       d   VP	                  RRR7      p/ p\        V\
        4      '       dG   VP                  4       '       d1    \        P                  ! V4      p\        V\        4      '       d   TpM\        V\        4      '       d   TpV P                  4        F  w  rVVR8X  d   K  WaV&   K  	  VP                  4        F	  w  rVWaV&   K  	  W1R&   V P                  4        Uu0 uF  qUR8w  g   K  VkK  	  upVR&   V#   \         d     Li ; iu upi )z?Flatten table row + JSON config (config wins on key collision).configutf-8replaceerrors_config_table_columns)get
isinstancebytes	bytearraydecoder   r$   jsonloadsdict	Exceptionitemskeys)r2   outraw_cfgcfgr.   kvs   &      r   _merged_agent_recordrL   2   s   CgghG'E9-.....;C'3GMMOO	ZZ(F&$'' 
GT	"	"		=A  		A 	N(+
D
18mQQ
DCJ  		 Es   2.D- D>D>-D;:D;c                    V ^8  d   QhRRRR/# )r
   flatr3   r   dict[str, str]r   )r   s   "r   r   r   N   s     > >> >n >r   c                
  a  V 3R lpV! RRR4      ;'       g    RP                  RR4      p/ pV'       d   W#R&   R V 3R	 llpR
 F  pV! V4      pV'       g   K  WcV&   K  	  RpV F  w  rV! V	!  p
V
'       g   K  WV&   K  	  V# )z
Map merged agent row + JSON `config` into Redis / RabbitMQ keys for MCube runtime.
Accepts MCUBE_* aliases and plain names (same as mcube_defaults / cluster bot exports).
c                 0   < \        V3R  lV  4       R4      # )c              3     <"   T Fe  pSP                  V4      R9  g   K  \        SV,          4      P                  4       '       g   KC  \        SV,          4      P                  4       x  Kg  	  R # 5i)N)Nr   )r<   r   r$   ).0rJ   rN   s   & r   	<genexpr>=_runtime_mcube_overrides.<locals>.<lambda>.<locals>.<genexpr>S   sS     y$Q$((1+U_B_0dghlmnhodpdvdvdx0CQL..00$s   A0#A0(A0r   )next)rF   rN   s   *r   <lambda>*_runtime_mcube_overrides.<locals>.<lambda>S   s    dy$y{}~r   system_promptMCUBE_SYSTEM_PROMPTpromptr   z\n
c                    V ^8  d   QhRRRR/# )r
   keyr   r   r   )r   s   "r   r   ._runtime_mcube_overrides.<locals>.__annotate__a   s      c c r   c                  < SP                  V 4      pVf   R# \        V\        \        34      '       d   VP	                  RRR7      p\        V\
        4      '       d   VP                  4       pV# \        V\        \        34      '       d    \        P                  ! VRR7      # \        V4      P                  4       #   \         d     R# i ; i)Nr   r6   r7   r8   F)ensure_ascii)r<   r=   r>   r?   r@   r   r$   rC   listrA   dumpsrD   )r^   rK   srN   s   &  r   _jsonish*_runtime_mcube_overrides.<locals>._jsonisha   s    HHSM9a%+,,3Aa	AHa$&&zz!%88 1v||~  s   B> >CC)message_inboundmessage_outboundplatform_settingsconversation_behavior))first_message)rk   MCUBE_FIRST_MESSAGErh   )	llm_model)rm   MCUBE_LLM_MODEL)llm_provider)ro   MCUBE_LLM_PROVIDER)stt_provider)rq   MCUBE_STT_PROVIDER)stt_language_code)rs   MCUBE_STT_LANGUAGE_CODE)stt_model_id)ru   MCUBE_STT_MODEL_ID)tts_provider)rw   MCUBE_TTS_PROVIDER)	tts_model)ry   MCUBE_TTS_MODEL)tts_voice_id)r{   voice_idMCUBE_TTS_VOICE_ID)tts_encoding)r~   MCUBE_TTS_ENCODING)tts_chunk_ms)r   MCUBE_TTS_CHUNK_MS)tts_gain)r   MCUBE_TTS_GAIN)playback_pace_factor)r   MCUBE_PLAYBACK_PACE_FACTOR)checkpoint_every)r   MCUBE_CHECKPOINT_EVERY)r7   )rN   grY   rG   re   rJ   svpairsout_key
alias_keysrK   s   f          r   _runtime_mcube_overridesr   N   s    
 	A 	
/0(; 	 	geT 
 C,O
 " ca[2F c
E   %zN1L  %
 Jr   agent_iduser_idemailnamec               0    V ^8  d   QhRRRRRRRRRRRR	/# )
r
   business_idr*   r   r   r   r   r   r   r   r   )r   s   "r   r   r      sN     c cc c 	c
 c c cr   c          	        \        \        P                  ! RR4      4      pV'       g   \        P	                  R4       R#  ^ RIp^ RIHp TP                  4        UU	u/ uF  w  rTR8w  g   K  YbK  	  p
pp	YzR&    TP                  ! R/ T
B p TP                  4       ;_uu_ 4       pTP                  R	4       TP!                  4       pT'       d   T Uu0 uF  qR
,          kK  	  upM	\#        4       pT'       gW   TP                  R4       TP!                  4        Uu0 uF+  p\%        T\&        4      '       d
   TR,          MT^ ,          kK-  	  ppT'       g2   \        P                  R4        RRR4        TP)                  4        R# R R lpT! R4       R2.pT .pRT3RT3RT3RT3RT33 F^  w  ppTe   \+        T4      P-                  4       R8X  d   K*  TT9  d   K3  TP/                  T! T4       R24       TP/                  T4       K`  	  RRP1                  T4       R2pTP                  TT4       TP3                  4       pT'       d'   \'        T4      uuRRR4        TP)                  4        # RT9   d   RT9   d   RT! R4       R2MRpTP                  RT! R4       RT R2T .4       TP3                  4       pT'       d=   \        P5                  RT 4       \'        T4      uuRRR4        TP)                  4        # RRR4        TP)                  4        R#   \         d    \        P                  R4        R# i ; iu up	pi   \         d    \        P                  R4        R# i ; iu upi u upi   \         d     R# i ; i  \         d     # i ; i  \         d     # i ; i  + '       g   i     L; i  \         d>    \        P                  RT 4         TP)                  4        R#   \         d     R# i ; ii ; i  \         d     R# i ; i   TP)                  4        i   \         d     i i ; i; i) z^
SELECT matching row from business_id_agents. Uses dynamic WHERE only for columns that exist.
DATABASE_CLUSTER_URLr   z?business_id_agents: DATABASE_CLUSTER_URL not set; skip DB fetchN)
DictCursorz)business_id_agents: pymysql not installedr    z%business_id_agents: DB connect failedz
                SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
                WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'business_id_agents'
                COLUMN_NAMEz&SHOW COLUMNS FROM `business_id_agents`FieldzFbusiness_id_agents: table business_id_agents not found or empty schemac                    V ^8  d   QhRRRR/# )r
   nr   r   r   )r   s   "r   r   2fetch_business_id_agents_row.<locals>.__annotate__   s     G G3 G3 Gr   c                    R \        V 4      P                  \        ^`4      \        ^`4      \        ^`4      ,           4       R 2# )`)r   r7   chr)r   s   &r   q_ident-fetch_business_id_agents_row.<locals>.q_ident   s1    3q6>>#b'3r73r7?CDAFFr   r   z = %sr   r   r   r(   r   z)SELECT * FROM `business_id_agents` WHERE z AND z LIMIT 1idz
 ORDER BY z ASCzObusiness_id_agents: using first agent row for business_id=%s (no tighter match)z/business_id_agents: query failed business_id=%sr   )r0   osgetenvr&   debugpymysqlpymysql.cursorsr   ImportErrorr'   rE   connectrD   	exceptioncursorexecutefetchallsetr=   rC   closer   r$   appendjoinfetchoneinfo)r   r   r   r   r   params_baser   r   rJ   rK   conn_kwconncurcol_rowsrcolsr   
conditions
sql_paramsr^   valsqlr2   orders   &$$$$                   r   fetch_business_id_agents_rowr      s    +2995KR+PQK		ST.
 !, 1 1 3J 3qM7Itqt 3GJ'M))
A[[]]cKK ||~H;Ch7hm$$h7DDEMP\\^\^jD&9&9'
qtC^\de z	JJL[G %]34E:;J%0MJ X&G$% U#S ;#c(.."2b"8d?!!WS\N%"89!!#& >gll:>V=WW_`CKKZ(,,.CCyS ]z	JJL% $<@DL*WT]O48b?@V?WW\]b\cckl M llnHHi#  9q ]z	JJL} z	JJL a  ?@ K
  => 8 ]h  		y 		y 		 ]r  GU	JJL 		  			JJL 		sL  
L" M	.M	<M O '.N4M6&N4;#N41M;	N4N4/O 8N  
CN4
N4
O &N7AN4 N4+
O 6N#O P " MM M32M36
N4 NNN N #N10N14O	?O P$ O !P(P$ *O< <P
PPP$ P! P!$Q&P76Q7QQQQc               0    V ^8  d   QhRRRRRRRRRRRR	/# )
r
   r   
int | Noner   r   r   r   r   r   rO   r   )r   s   "r   r   r      sF     + ++ + 	+
 + + +r   c               2   V f   / #  \        V 4      pYQY#T3p\        P                  ! 4       p\        P                  T4      pT'       d7   Yx^ ,          ,
          \        8  d   T^,          p	T	'       d   \        T	4      # / # \        TTTTTR7      p
T
'       d   \        T
4      M/ pYz'       d   TMR3\        T&   T
'       g   / # \        T4      pT'       d/   \        P                  RT\        TP                  4       4      4       T#   \         d    / u # i ; i)z@Returns only ai_worker-relevant string overrides (may be empty).Nr   r   r   r   z?business_id_agents: loaded overrides for business_id=%s keys=%s)r*   rD   time	monotonicr   r<   _CACHE_TTL_Sr   r   rL   r&   r   rb   rF   )r   r   r   r   r   bid	cache_keynowhitmergedr2   rN   	overridess   &$$$$        r   'get_runtime_overrides_from_agents_tabler      s    	+ 5I
..
C
**Y
C
sV|l*Q39'/ArA
&C ),$Dcdt4F9	(.IM!"	

 =  	s   D DDc               0    V ^8  d   QhRRRRRRRRRRRR	/# )
r
   r   r   r   r   r   r   r   r   r3   r   )r   s   "r   r   r   #  sF     % %% % 	%
 % % %r   c                   V f   / #  \        V 4      p\        TTTTTR7      pT'       g   / # \        T4      #   \         d    / u # i ; i)zn
Full merged agent record for debugging / future use (all columns + config),
excluding raw duplicate storage.
r   )r*   rD   r   rL   )r   r   r   r   r   r   r2   s   &$$$$  r   get_full_agent_contextr   #  sd     	+ 'C 	$$  	s   8 AA)__conditional_annotations____doc__
__future__r   rA   loggingr   r   typingr   urllib.parser   r   	getLoggerr&   r   __annotations__floatr   r   r0   rL   r   r   r   r   )r   s   @r   <module>r      s    #   	   *23EGB GRYY?GH48>Bc c 	c
 c cL+ + 	+
 + +\% % 	%
 % % %r   