
    4i}                         d dl mZmZmZmZ d dlmZ d dlZd dlm	Z	 d dl
mZ d dlmZ d dlmZmZ d dlmZ  e	e          Z G d	 d
          ZdS )    )OptionalListDictAny)	WebClientN)setup_logger)	GeminiLLM)ContextStorage)TOOLS_SCHEMATOOL_FUNCTIONS)get_tool_presetc                      e Zd ZdZddee         dee         deee                  defdZdd
edededee         dedeee                  ddfdZ	ddede
dee         fdZddedede
defdZdee         dedeeeef                  fdZdS ) MessageDispatcherz<Routes incoming Slack messages to Gemini and executes tools.Nlight	bot_tokensystem_instructiontools	tool_modec                    t          |          | _        ||| _        t          | _        n~|dk    r)d| _        i | _        t
                              d           nOt          |          \  | _        | _        t
                              d| dt          | j                   d           |pt          j
                            d          | _        t          | j        	          | _        t
                              d
           dS )a  
        Initialize dispatcher.
        Args:
            bot_token: Optional specific Slack token
            system_instruction: Custom system prompt (e.g. for Shell Bot)
            tools: specific tools list to use (if None, uses preset based on tool_mode)
            tool_mode: 'none' (no tools), 'light' (5 tools), 'standard' (10 tools), 'full' (15 tools), 'all' (21 tools)
        )r   Nnonez$Running in NO-TOOLS mode (pure text)zUsing tool preset:  (z tools)SLACK_BOT_TOKEN)tokenz"Dispatcher initialized with Gemini)r	   llmr   r   tool_functionsloggerinfor   lenosenvirongetr   r   client)selfr   r   r   r   s        -/root/projects/butler/slack_bot/dispatcher.py__init__zMessageDispatcher.__init__   s     0BCCC DJ"0D&  DJ"$DKK>????.=i.H.H+DJ+KKSiSS3tz??SSSTTT #Gbjnn5F&G&Gdn555899999    N/Amessage_text
channel_iduser_idresponse_ts
request_idfilesreturnc                 L"  C ddl }|                                 }d| d}	t                              |	 d| d|            |r-t                              |	 dt          |           d           t	          |          }
|                                                                d	v r2|
                                 | j        	                    |d
           dS |

                    d|           g }d}|rO|                     ||	          }t          |          dk    r&d}t                              |	 d           ||z  }d}	 |
                                }t                              |	 dt          |                      |rdn| j        }t                              |	 d           t                              |	 d| j                                         d|rt          |          nd dt          |          dz
   d           |                                 }| j                            ||dd         ||          \  }}| t                              |	 d           d}n1|                                st                              |	 d           |g }t                              |	 dt          |           d|rt          |          nd            |st                              |	 d           |                                Ct)          Cfd d!D                       r(t)          Cfd"d#D                       rt                              |	 d$           dd%lm}m} dd&lm} t)          Cfd'd(D                       r* |             |d)          z
                                  }nat)          Cfd*d+D                       r* |             |d,)          z
                                  }n |                                            }t                              |	 d-|            |                    d.d/|id0           nt)          Cfd1d2D                       r}dd3lm} dd4lm}m} t)          Cfd5d6D                       }| ot)          Cfd7d8D                       }|rddl} |            }|                    d9          }d:}|                    d;C          rft?          |                    d;C                               d          p(|                    d;C                               d,                    }|d:z  }n|                    d<C          rft?          |                    d<C                               d          p(|                    d<C                               d,                    }|d=z  }n|                    d>C          r`t?          |                    d>C                               d          p(|                    d>C                               d,                    }n|                    d?C          ret?          |                    d?C                               d          p(|                    d?C                               d,                    } | d@z  }ndACv sdBCv rdC}n
dDCv sdECv rdF}dd3lm} | ||)          z
                      d9          }!dG}"t)          CfdHdID                       rdJ}"nYt)          CfdKdLD                       rdM}"n;t)          CfdNdOD                       rdP}"nt)          CfdQdRD                       rdS}"t                              |	 dT|" dU|! dV| dW           |                    dX|"|!|dYd0           n |            }t)          CfdZd[D                       r#| |d)          z
                      d9          }#nSt)          Cfd\d]D                       r#| |d,)          z
                      d9          }#n|                    d9          }#t)          Cfd^d_D                       r;t                              |	 d`|#            |                    da|#|#dbd0           nt                              |	 dc|#            |                    ddd/|#id0           nTt)          CfdedfD                       r9|}$t                              |	 dg           |                    dhdi|$id0           g dj}%g dk}&t)          CfdldmD                       }'t)          Cfdn|&D                       }(t)          Cfdo|%D                       })|'r|)s|(r&t                              |	 dp|' dq|( dr|)            n;t                              |	 ds           nt                              |	 dt           |rt          |          nd}*t                              |	 du|                                 |z
  dvdwt          |           dx|* dy           g }+|rt                              |	 dzt          |           dy           |D ]}},|,d{         }-|,d|         }.|-d.k    rdd&lm} dd}lm!}/m} d/|.v r|.d/         r	 |/"                    |.d/                   }0 |            }1|0|1k     r9t                              |	 d~|0 dV|1            |1                                |.d/<   n{# tF          $ rO}2t                              |	 d|.d/          d            |                                            |.d/<   Y d}2~2n'd}2~2ww xY w |                                            |.d/<   t                              |	 d|- d|.            |                                 }3|-| j$        v r
	 |-dk    r||.d<    | j$        |-         di |.}4tK          |4          }5t          |5          dk    r|5dd         dz   }5|+                    |-|.|5d           t                              |	 d|- d|                                 |3z
  dvd           # tF          $ r[}2d|- dtK          |2           }6t                              |	 d|6            |+                    |-|.d|6 d           Y d}2~2Vd}2~2ww xY wt                              |	 d|-            t                              |	 d           d&                    d |+D                       }7d&                    d |+D                       }8|

                    dd|7 d           d|8 d}9|
                                }:|                                 };| j                            |9|:d          \  }}<t                              |	 d|                                 |;z
  dvd           |r|                                s$t                              |	 d           |rd}nd}d}=| '                    ||+|=          }>| (                    |>d          }?t          |?          dk    r|?dd         }?|?dxx         dz  cc<   |r	 | j        )                    |||?d                    t                              |	 d|            nX# tF          $ rK}2t                              |	 d|2            | j        	                    ||?d                    Y d}2~2nd}2~2ww xY w|?dd         D ]P}@|*                    d           | j        	                    ||@           t                              |	 d           QnytW          |?          D ]<\  }A}@|Adk    r|*                    d           | j        	                    ||@           =t                              |	 dt          |?           d           |

                    d|>d           t                              |	 d|                                 |z
  dvd           dS # tF          $ r}2t                              |	 d|2 d           	 | j        	                    |dtK          |2                      t                              d           n6# tF          $ r)}Bt                              d|B d           Y d}B~Bnd}B~Bww xY wY d}2~2dS Y d}2~2dS d}2~2ww xY w)z:
        Process a message and trigger responses.
        r   N[]z Processing message in z from z Message contains z files)clearresetu   清除u-   🧹 Context cleared. (对话历史已清除))channeltextuserFz
[SYSTEM WARNING: User uploaded an image but it FAILED to download/process. You CANNOT see the image. DO NOT GUESS. Inform the user that the image access failed.]z1 Image download failed! Appending warning to LLM.Tz Context size: z' Calling Gemini for initial response...z Request config: model=z, tools=z
, context=   z msgs)messagecontextr   imagesz( Gemini returned None for response_text! zO Gemini returned empty response_text! (This usually means the proxy has issues)z Gemini response: text=z chars, tool_calls=zA No tool calls from Gemini - checking SAFETY OVERRIDE keywords...c              3       K   | ]}|v V  	d S N .0k	lower_msgs     r$   	<genexpr>z-MessageDispatcher.dispatch.<locals>.<genexpr>~   s'      ii!qI~iiiiiir&   )syncupdatefetchu   同步u   拉取u   更新c              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'      VV!qI~VVVVVVr&   )garminu   佳明datau   数据u/    🔧 SAFETY OVERRIDE: Forcing sync_garmin tool)datetime	timedelta)get_cst_todayc              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'      mma1	>mmmmmmr&   )   昨天   昨晚   昨日	yesterday
last night)daysc              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'      XXQ)^XXXXXXr&   )   前天day before yesterday   u(    🔧 SAFETY OVERRIDE: sync target_date=sync_garmintarget_date)nameargsc              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s?        d  dAi  d  d  d  d  d  dr&   )   睡眠sleep   步数stepsu   心率hearthrv   运动activityworkout   锻炼rO   rR      今天todayu   上午u   下午morning	afternoonu   查询query   变化   趋势trend)rL   )get_cst_nowrM   c              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s7       1 1Ai 1 1 1 1 1 1r&   )rO   rP   rQ   rS   rR   rh   u   今晚u   今日ri   tonightrV      前晚rW   u	   大前天zthree days agoc              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s@       J J]^!y. J J J J J Jr&   )u   过去u   最近u   近pastrecentrm   rn   ro   changeu   历史historyu   个月monthu   周weeku   年yearz%Y-%m-%d   u   (\d+)\s*个?月|(\d+)\s*monthu   (\d+)\s*周|(\d+)\s*week   u   (\d+)\s*天|(\d+)\s*dayu   (\d+)\s*年|(\d+)\s*yearim  u   半年z	six month   u	   三个月zthree monthZ   rhrc              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'      OO!qI~OOOOOOr&   )rc   u   心率变异rc   c              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   '       M MAi M M M M M Mr&   )r^   r_   r_   c              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   r   r&   )r`   ra   ra   c              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'       N NAi N N N N N Nr&   )u   压力stressr   u6    🔧 SAFETY OVERRIDE: Forcing get_metric_history for r    to )get_metric_history)metric_type
start_dateend_datec              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'      qq!qI~qqqqqqr&   )rO   rP   rQ   rS   rR   c              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'       f fAi f f f f f fr&   )rV   rs   rW   c              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'      cc!qI~ccccccr&   )rd   re   rf   rg   u8    🔧 SAFETY OVERRIDE: Forcing get_activity_history for get_activity_history)r   r   u<    🔧 SAFETY OVERRIDE: Forcing get_daily_detailed_stats for get_daily_detailed_statsc              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'      rrAirrrrrrr&   )u   搜索searchu	   查一下zlook upu   最新latestu)    🔧 SAFETY OVERRIDE: Forcing search_web
search_webrl   )u   鸡u   肉u   菜u   蛋u   饭u   面u   粉u   汤u   鱼u   虾u   蟹u   牛u   猪u   羊u   豆u   奶)	u   晚餐u   午餐u   早餐u   夜宵u   零食	breakfastlunchdinnersnackc              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'      %d%da9n%d%d%d%d%d%dr&   )u   吃了ateu   吃的eatingc              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'      (Q(QAi(Q(Q(Q(Q(Q(Qr&   c              3       K   | ]}|v V  	d S r>   r?   r@   s     r$   rD   z-MessageDispatcher.dispatch.<locals>.<genexpr>   s'      #G#GqAN#G#G#G#G#G#Gr&   z# Detected diet logging intent: ate=z, meal=z, food=zD No SAFETY OVERRIDE match found - will return empty response or textzH Tool calls successfully generated by Gemini (no SAFETY OVERRIDE needed)z Gemini response in z.2fzs: z chars, z toolsz Executing r[   r\   )daterL   u*    🔧 Fixing sync_garmin target_date from u    🔧 Invalid target_date: z, using todayz Tool: z Args: execute_shellr)   i@  ... (truncated))toolr\   resultu    ✓ z finished in szError executing z:  u   ❌ z Unknown tool: z Requesting final analysis..., c                     g | ]
}|d          S )r   r?   rA   trs     r$   
<listcomp>z.MessageDispatcher.dispatch.<locals>.<listcomp>H  s    'J'J'Jr6
'J'J'Jr&   
c           	      H    g | ]}d |d          d|d          d|d           S )zTool 'r   z	' (Args: r\   z) returned:
r   r?   r   s     r$   r   z.MessageDispatcher.dispatch.<locals>.<listcomp>K  sM     / / / ZRZYY"V*YY2h<YY/ / /r&   	assistantzI checked: gemini)modelz/Here are the execution results from the tools:
ai  

CRITICAL INSTRUCTION: You represent the 'Butler' bot. You must now answer the user's original question based ONLY on the above results.
1. Summarize the key data points found (e.g., steps, sleep score).
2. Provide direct, natural language insights.
3. If the tool indicated an error, explain it to the user.

Do NOT output raw JSON. Write a helpful paragraph.)r9   r:   r   z Final analysis received in z Empty analysis received!u   ⚠️ 图片已接收，但 AI 模型未能返回描述。这可能是由于网络波动或模型暂时无法识别该图像，请稍后重试。uj   ✅ 数据已同步，但我似乎暂时无法生成文字分析。请参考上方的工具执行结果。i.  )
max_length  )max_chunk_size   z!
...(remaining content truncated))r4   tsr5   u    📤 Message updated z Update failed, posting new: g      ?u!    📤 Continuation message postedu    📤 z message(s) postedz Dispatch completed in z Dispatch failed: )exc_infou   ⚠️ Internal Error: zError message posted to Slackz'Failed to post error message to Slack: r?   ),timer   r   r   r
   striplowerr2   r"   chat_postMessageadd_message_download_fileswarningget_contextdebugr   r   get_model_namegenerate_responseerroranyrK   rL   health.utils.time_utilsrM   	isoformatappendrp   restrftimer   intgroupr   fromisoformat	Exceptionr   strjoin_format_response_split_textchat_updater_   	enumerate)Dr#   r(   r)   r*   r+   r,   r-   r   t0prefixstorageimage_data_listdownload_failedfailure_msgr:   current_toolst_llm_startresponse_text
tool_callsrK   rL   rM   
_sync_daterp   has_single_day_keywordis_trend_queryr   	today_cstr   days_agomonthsweeksyearsr   r   targetrl   
food_itemsmeal_indicatorshas_ate_patternhas_meal_indicatorhas_food_item
tool_counttool_results	tool_call	tool_name	tool_argsr   target_date_objri   et_tool_startr   
str_result	error_msg
tool_namestool_results_textanalysis_promptfinal_contextt_llm_2_start_	APP_LIMITfull_responsechunkschunkislack_errorrC   sD                                                                      @r$   dispatchzMessageDispatcher.dispatch.   s    	YY[["Z"""vQQjQQQQRRR 	IKK6GGSZZGGGHHH !,, %%''+GGGMMOOOK((Bq(rrrFFL111  	'"225&AAO?##q(( D&[[[\\\+"&S	e))++GLLFAA3w<<AABBB %4CDDMKK6JJJKKKKK6  i  i$(:Q:Q:S:S  i  i  tA  ^H]`an]o]o]o  GH  i  i  TW  X_  T`  T`  ab  Tb  i  i  i  j  j  j))++K(,(B(B$#&	 )C ) )%M: $PPPQQQ ""((** {&yyyzzz !
 KK6  H  H#m:L:L  H  Ht~  bFadeoapapap  EF  H  H  I  I  I  Gqvhhhiii(..00	 iiii/hiiiii sVVVV/UVVVVVsNNf#]#]#]^^^<<<<<<<<EEEEEEmmmm3lmmmmm A&3moo		q8I8I8I&I%T%T%V%V

XXXX5WXXXXX A&3moo		q8I8I8I&I%T%T%V%V

%2]__%>%>%@%@
NNf#b#bV`#b#bccc%% -!.
 ;' '       d  d  d  d  2c  d  d  d  d  d `222222RRRRRRRR .1 1 1 1 1 J 1 1 1 . .* +A&@ &c J J J J c J J J G GN & D!			$1MOO	#,#5#5j#A#A#%99%EyQQ *%(3SU^)_)_)e)efg)h)h  *llnlulu  wW  Yb  mc  mc  mi  mi  jk  ml  ml  &m  &mF'-{HHYY'BINN *$'		2My(Y(Y(_(_`a(b(b  )afhfofo  qL  NW  gX  gX  g^  g^  _`  ga  ga  %b  %bE',qyHHYY'A9MM *'*2995OQZ+[+[+a+abc+d+d  ,bhjhqhq  sM  OX  iY  iY  i_  i_  `a  ib  ib  (c  (cHHYY'BINN *$'		2My(Y(Y(_(_`a(b(b  )afhfofo  qL  NW  gX  gX  g^  g^  _`  ga  ga  %b  %bE',s{HH%22kY6N6N'*HH(I55)9S9S')H666666&/))2J2J2J&J%T%TU_%`%`
 ',OOOO7NOOOOO 3*/KK  M M M M9L M M MMM 3*1KK  M M M M9L M M MMM 3*1KK  N N N N9M N N NNN 3*2K&  (S  (Shs  (S  (S  xB  (S  (S  HP  (S  (S  (S  T  T  T"))$8/:.8,4% %+ +     %2MOO	qqqq7pqqqqq D&/))2C2C2C&C%M%Mj%Y%YFF  f f f f9e f f fff D&/))2C2C2C&C%M%Mj%Y%YFF%.%7%7
%C%CF cccc7bccccc "NNf+v+vnt+v+vwww&--(>7=6(R(R/ /    
 #NNf+z+zrx+z+z{{{&--(B)6(?/ /     rrrr1qrrrrr (ENNf#W#W#WXXX%% ,!(% 0' '    N  N  N
"}"}"}"%%d%d%d%d>c%d%d%d"d"d%((Q(Q(Q(Q(Q(Q(Q%Q%Q" ##G#G#G#GJ#G#G#G G G# q q:L qNNf  $T  $TQ`  $T  $Ti{  $T  $T  ER  $T  $T  U  U  U  U KK6 o o oppppvoooppp -7=ZAJKK6  F  Ftyy{{;7N  F  F  FWZ[hWiWi  F  Fs}  F  F  F  G  G  G L gUvII#j//IIIJJJ!+ 8N 8NI )& 1I )& 1I !M11IIIIII<<<<<<<<(I55)M:R5	W262D2DY}E]2^2^(5#2U#:#:$*NNf  4E  4Ehw  4E  4E  ~C  4E  4E  %F  %F  %F?D?P?PIm$<#, W W W &&/|/|U^_lUm/|/|/| } } };H=??;T;T;V;V	- 8 8 8 8 8 8W
 8E}7P7P7R7RIm4KK6 O O) O OI O OPPP#'99;;L D$777(O;;:D	, 7%CT%8%C%P%Pi%P%PF *-VJ":55-7->AR-R
(//(1(1*41 1   
 #KK6(o(o	(o(oPTPYPYP[P[\hPh(o(o(o(opppp(   (P9(P(PA(P(PI"LLF)@)@Y)@)@AAA(//(1(1*<*<*<1 1         &'L'L'L'LMMMM vDDDEEE!YY'J'J\'J'J'JKK
 %)II / /*/ / / % %! ##K1Kz1K1KS[#\\\JGX J J J   !( 3 3 5 5 $		#'8#=#=+) $> $ $ q
 vcc499;;}C\ccccddd % UM,?,?,A,A UNNf#G#G#GHHH U )} )U I 11-Zc1ddM %%mD%IIF 6{{Qr


BB


  NUK++J;U[\]U^+___KK6 N N N NOOOO  U U UNNf#N#N1#N#NOOOK00&QR)0TTTTTTTTU
 $ABBZ N NEJJsOOOK00%0PPPKK6 L L LMMMM	N !*& 1 1 Q QHAu1uudjjoooK00%0PPPPvLLS[[LLLMMM ](KKKKK6OO$))++b.OOOOPPPPP 		e 		e 		eLLF99a99DLIIIe,,&;3q66;; -    ;<<<< e e eT{TT_cdddddddde =<<<<<dddddd		es   fAA) 	A$l.-AA) .
n8An=AA) nA"AA) *Br	AA) 
s0As+%AA) +s00F8AA) )A{, +AA) ,
}6A|<7AA) <}D&AA) A)
AD#A3!ADBAACCADC
ADC&AD
DADD
ADDADDAD#r   r5   r   c                    t          |          |k    r|gS g }d}|                    d          }d}|D ]}|                                                    d          r| }t          |          t          |          z   dz   |k    r%|r|dz  }|                    |           d}|r|dz  }|r|dz  }||z  }|r|                    |           |S )zASplit text into chunks avoiding breaking code blocks if possible.r<   r   Fz```r7   z
```z```
(...continued)
)r   splitr   
startswithr   )r#   r5   r   r   current_chunklinesin_code_blocklines           r$   r   zMessageDispatcher._split_text  s   t99&&6M

4   	" 	"Dzz||&&u-- 2$1 1 =!!CII-1NBB  -!W,Mm,,, !#  B!%AAM &%T!MM 	)MM-(((r&   ܛ  r   r   c           	         g }|r|                     d           |D ]}d                    d |d                                         D                       }t          |d                   }d}t	          |          |k    r|d|         dz   }|                     d	|d
          d| d|            |                     d           |rkddlm}	 |	                    |          }
t          	                    dt	          |           dt	          |
           d           |                     |
           |rd                    |          }n[t          
                    d           dt	          |           dt	          |           d| j                                         }d|z   }t	          |          |k    rOd}|t	          |          z
  }|d|         |z   }t          
                    dt	          |           d| d           |S )a`  
        Format the response with tool execution results.

        Args:
            text: The main response text
            tool_results: List of tool execution results
            max_length: Maximum allowed message length (default for new messages)

        Returns:
            Formatted response string, guaranteed to be under max_length
        u   🛠️ *Tool Executions:*r   c              3   *   K   | ]\  }}| d | V  dS )=Nr?   )rA   rB   vs      r$   rD   z5MessageDispatcher._format_response.<locals>.<genexpr>  s0      $O$ODAqZZAZZ$O$O$O$O$O$Or&   r\   r   i  Nr   u   • `r   (z)`: r<   r   )SlackFormatterzFormatted text (len z -> r   r   z>No response text and no tool results - returning error messageu+   

🔍 调试信息:
- 响应文本长度: u    字符
- 工具调用数: u   
- 模型: u   ⚠️ 抱歉，我似乎没有理解你的请求。请尝试更具体的描述，或者直接说明你想查询什么数据（例如：今天的步数、昨天的睡眠、上午的运动等）。u7   

⚠️ (Response truncated due to Slack length limit)zFinal response truncated from r   z chars)r   r   itemsr   r   slack_bot.utils.mrkdwnr  convertr   r   r   r   r   )r#   r5   r   r   partsr   args_str
result_strmax_per_toolr  formatted_textr   
debug_infotruncation_msgallowed_lengths                  r$   r   z"MessageDispatcher._format_response  s      	LL5666" N N99$O$OBvJ<L<L<N<N$O$O$OOO !H..
#z??\11!+M\M!:=N!NJLRZLL(LL
LLMMMMLL  	)======+33D99NKKTs4yyTTc.>Q>QTTTUUULL(((  	 IIe,,MM NN[\\\ l#d))  l  lqt  vB  rC  rC  l  l  QU  QY  Qh  Qh  Qj  Qj  l  lJ W  }
**XN'#n*=*==N)/>/:^KMNNfC<N<NffT^fffgggr&   r   c                 v	   ddl }| j        }ddlm} ddl}g }|D ]}t
                              | d|                    d           d|                    d           dt          |                    d	                                d|v r*|d         	                    d
          r|                    d          p|                    d	          }	|	sdd| i}
|r|dd          d|dd          nd}t
                              | d|	 d|            |                    d	          }|s|
                                }|j                            dd| i           |r|dd          d|dd          nd}t
                              | d|	 d| d           	 |                    |	d          }|j        |	k    r$t
                              | d|j                    |j        dk    rc|j                            dd          }d|                                v rt
                              | d           -	 |                    |                    |j                            }nD# t(          $ r7}t
                              | d|j        dd                    Y d}~d}~ww xY w|j        dv s|j        d k    rwd!|j        v rn|                    d"|j        d#          }|j        d$k    r|                    d$          }|                    ||                                d%         &           |}n |j        d"k    r|                    d"          }d'}t7          |j                  |k    r"|                    ||f|j        j                   |                                }|                    |d(d)*           |                                 }t
                              | d+|                    d           d,tC          |j                  d'z  d-d.tC          |          d'z  d-d/           |"                    d0|d1           n$t
                              | d2|j                    f# t(          $ r*}t
                              | d3|            Y d}~d}~ww xY w|S )4zDownload files from Slack.r   N)Imagez found file: r[   z Type: mimetypez URL_P: url_privatezimage/url_private_downloadAuthorizationzBearer    z...Nonez Attempting download from z with token z using Session (Token: r   
   )timeoutz Redirected to:    zContent-TypeunknownhtmlzJ Download returned HTML (likely Login Page) instead of image. Auth failed.z$ PIL Open Failed! Content preamble: )RGBALAPtransparencyRGB)   r-  r-  r(  r   )maski   JPEGU   )formatqualityz! Downloaded and optimized image: r   z.1fzKB -> zKB)z
image/jpeg)	mime_typerJ   z! Failed to download file: status z Error downloading file: )#requestsr   PILr  ior   r   r!   boolr  SessionheadersrF   urlstatus_coder   r   openBytesIOcontentr   modenewsizer  paster  max	thumbnail
ResamplingLANCZOSsavegetvaluer   r   )r#   r-   r   r4  r   r  r6  downloaded_files	file_infor:  r9  token_maskedbase_urlsessionresponsectimgimg_errbgmax_dimbufoptimized_datar   s                          r$   r   z!MessageDispatcher._download_files  s   			 N	J N	JIKK6  V  V	f0E0E  V  Vimm\fNgNg  V  Vquv  wD  wD  ER  wS  wS  rT  rT  V  V  W  W  WY&&9Z+@+K+KH+U+U&mm$:;;[y}}]?[?[ *,=e,=,=>@EQ%)<<bcc
<<<6v````R^``aaa %==77  #**,,&&9J59J9J'KLLL AFQ%)<<bcc
<<<6vllll]illlmmm3J&{{3{;;H  |s**v$M$Mx|$M$MNNN+s22%-11.)LL!RXXZZ//"LLF)~)~)~$%"'**RZZ8H-I-I"J"JCC( % % %"LLF)r)rX`XhimjmimXn)r)rsss$HHHH%
 8~55#(c//n`c`hNhNh!&5#(O!L!LB"x611&)kk&&9&9HHSsyy{{1~H>>>"$CC X.."%++e"4"4C #'sx==722MM7G*<e>N>VWWW !jjllVR@@@),v %n %nPYP]P]^dPePe %n %n&)(*:&;&;D&@"m%n %nLOP^L_L_`dLd"m%n %n %n o o o )//)5$21 1    
 %g%gQYQe%g%ghhh  J J JLLF!H!HQ!H!HIIIIIIIIJ  sD   %B R -I65R 6
J7 ,J2,R 2J77GR  
R4
R//R4)NNNr   )Nr'   N)r   )r  )__name__
__module____qualname____doc__r   r   r   r   r%   r   r   r   listr   r   r   r?   r&   r$   r   r      s       FF: :(3- :HUXM :iqrvw{r|i} :  RU : : : ::ve veS vec veC veV^_bVc vex{ ve  MU  VZ  [_  V`  Ma ve  mq ve ve ve vep% % %S %DI % % % %N< <S < <# <Z] < < < <|Z T$Z Z  Z d3PS8nAU Z  Z  Z  Z  Z  Z r&   r   )typingr   r   r   r   	slack_sdkr   r   health.utils.logging_configr   slack_bot.llm.geminir	   slack_bot.context.storager
   slack_bot.tools.registryr   r   slack_bot.tools.groupsr   rV  r   r   r?   r&   r$   <module>rb     s    , , , , , , , , , , , ,       				 4 4 4 4 4 4 * * * * * * 4 4 4 4 4 4 A A A A A A A A 2 2 2 2 2 2	h		W	  W	  W	  W	  W	  W	  W	  W	  W	  W	 r&   