+
    lHàj\c  ã                   ó  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
 ]P                  ! R4      t0 R/mt0 R0mt0 R1mtRR0tRR0t]],          0 R2m,          tR	tR
tR t]P,                  ! R]P.                  4      t]P,                  ! R]P.                  4      tR R ltR R ltR3R R lltRtR4tR R ltR^/R R llt R R lt!R t"R t#R t$R5R lt%R  t&R! t'R" t(R# t)R6R$ lt*R%R/R& lt+R'RR(R)/R* lt,R3R+ lt-R, t.R7R- lt/R. t0R# )8zCStandalone per-platform senders and error helpers for send_message.)Úinstall_hintN)Úredact_sensitive_textztools.send_message_toolú.oggú.opusú.mp3ú.m4ai   é   c               óp  € T ;'       g    RP                  4       pT;'       g    . pV'       d‚   \        V4      ^8w  gr   \        V4      V8”  gb   V^ ,          ^,          '       gL   \        P                  P	                  V^ ,          ^ ,          4      ^,          P                  4       \        9  d   RV 3# VR3# )u·  Single chokepoint deciding whether text rides on the media bubble as its caption:
``(caption, "")`` only for exactly one captionable file (not a voice/audio note) whose
text fits ``max_caption_len``, else ``(None, text)`` â€” multi-file captionâ†’file association
is ambiguous. Length is codepoints (never under-counts Telegram's UTF-16 units for BMP
text); the Telegram sender re-checks the *formatted* caption since escaping inflates it.Ú N)ÚstripÚlenÚosÚpathÚsplitextÚlowerÚ_CAPTIONABLE_EXTS)ÚtextÚmedia_filesÚmax_caption_lenÚstrippedÚmedias   &&$  Ú?/home/ubuntu/.hermes/hermes-agent/tools/send_message_senders.pyÚ_media_caption_splitr      s�   € ð —
�
˜×!Ñ!Ó#€HØ×Ð˜2€Eßœ˜E›
 aœ¬3¨x«=¸?Ô+JÈeÐTUÍhÐWXÏkÌkÜ�w‰w×Ñ  a¥¨¥Ó,¨QÕ/×5Ñ5Ó7Ô?PÔPØ�TˆzÐØ�Rˆ<Ðó    zP([?&](?:access_token|api[_-]?key|auth[_-]?token|token|signature|sig)=)([^&#\s]+)zJ\b(access_token|api[_-]?key|auth[_-]?token|signature|sig)\s*=\s*([^\s,;]+)c                ó$   € V ^8„  d   QhR\         /# )é   Úreturn)Ústr)Úformats   "r   Ú__annotate__r   /   s   € ÷ Rñ R¤#ñ Rr   c                óp   € \         P                  R \        V 4      4      p\        P                  R V4      # )zCRedact secrets from error text before surfacing it to users/models.c                 ó*   € V P                  ^4       R2# )é   z***©Úgroup©Úms   &r   Ú<lambda>Ú&_sanitize_error_text.<locals>.<lambda>1   s   € °Q·W±W¸Q³Z°LÀÑ2Dr   c                 ó*   € V P                  ^4       R2# )r"   z=***r#   r%   s   &r   r'   r(   2   s   € °a·g±g¸a³j°\ÀÑ3Fr   )Ú_URL_SECRET_QUERY_REÚsubr   Ú_GENERIC_SECRET_ASSIGN_RE)r   Úredacteds   & r   Ú_sanitize_error_textr.   /   s0   € ä#×'Ñ'Ñ(DÔF[Ð\`ÓFaÓb€HÜ$×(Ñ(Ñ)FÈÓQÐQr   c                ó0   € V ^8„  d   QhR\         R\        /# )r   Úmessager   ©r   Údict)r   s   "r   r   r   5   s   € ÷ 4ñ 4”Cð 4œDñ 4r   c                ó   € R\        V 4      /# )z9Build a standardized error payload with redacted content.Úerror)r.   )r0   s   &r   Ú_errorr5   5   s   € àÔ)¨'Ó2Ð3Ð3r   c                ó0   € V ^8„  d   QhR\         R\        /# )r   Úplatformr   r1   )r   s   "r   r   r   :   s   € ÷ <ñ <”sð <Äñ <r   c                ó4   € RRRV RV/VCV'       d   RV/C# / C# )zGStandard success payload; ``warnings`` is only included when non-empty.ÚsuccessTr7   Úchat_idÚwarnings© )r7   r:   r;   Úfieldss   &&&,r   Ú_successr>   :   s<   € à�t˜Z¨°9¸gð <Èð <ß)1�
˜HÐ%ð<ð <Ø79ð<ð <r   zANo deliverable text or media remained after processing MEDIA tagsc                óJ   € V ^8„  d   QhR\         R\        R\        R,          /# )r   ÚexcÚattemptr   N)Ú	ExceptionÚintÚfloat)r   s   "r   r   r   F   s*   € ÷ jñ jœyð j´3ð j¼5À4½<ñ jr   c                óŒ  a€ \        V RR4      pVe    \        \        V4      R4      # \        V 4      P                  4       oRS9   g   RS9   d   R# \        ;QJ d#    V3R l\         4       F  '       g   K   RM	  R	M! V3R l\         4       4      '       d   \        ^V,          4      # R#   \        \        3 d     R# i ; i)
z¡Retry delay in seconds, or None when final: honours ``retry_after``; timeouts are
never retried (the send may have gone through); 5xx/429 back off exponentially.Úretry_afterNg        g      ð?z	timed outÚtimeoutc              3   ó,   <"  € T F	  qS9   x € K  	  R # 5i©Nr<   )Ú.0Úmarkerr   s   & €r   Ú	<genexpr>Ú(_telegram_retry_delay.<locals>.<genexpr>R   s   øé € Ð%_ÑC^¸°¦nÓC^ùs   ƒTF)	ÚgetattrÚmaxrD   Ú	TypeErrorÚ
ValueErrorr   r   ÚanyÚ_TELEGRAM_TRANSIENT_MARKERS)r@   rA   rF   r   s   && @r   Ú_telegram_retry_delayrT   F   s¤   ø€ ô ˜#˜}¨dÓ3€KØÒð	Ü”u˜[Ó)¨3Ó/Ð/ô ˆs‹8�>‰>Ó€DØ�dÔ˜i¨4Ô/Ùß"%£#Ô%_ÕC^Ó%_§#§#¢#Ô%_ÕC^Ó%_×"_Ò"_Œ5��g•ÓÐiÐeiÐiøô œ:Ð&ô 	Úð	ús   ”B. Â.CÃCÚattemptsc                ó$   € V ^8„  d   QhR\         /# )r   rU   )rC   )r   s   "r   r   r   U   s   € ÷ 'ñ '¼cñ 'r   c             ‹  óf  "  € \        V4       F  p V P                  ! R/ VB G Rj  x€L
 u # 	  R#  L
  \         dp   p\        YC4      pTe   Y1^,
          8¼  d   h \        P                  RT^,           Y\        T4      4       \        P                  ! T4      G Rj  x€L 
   Rp?K›  Rp?ii ; i5i)z@``bot.send_message`` with bounded retries on transient failures.NzFTransient Telegram send failure (attempt %d/%d), retrying in %.1fs: %sr<   )	ÚrangeÚsend_messagerB   rT   ÚloggerÚwarningr.   ÚasyncioÚsleep)ÚbotrU   ÚkwargsrA   r@   Údelays   &$,   r   Ú!_send_telegram_message_with_retryra   U   s�   é € ä˜–?ˆð	'Ø×)Ò)Ñ3¨FÑ3×3Ò3ó #á3øÜô 	'Ü)¨#Ó7ˆEØŠ} °a­<Ô 7ØÜ�N‰NÐcØ" Q�;¨Ô9MÈcÓ9RôTä—-’- Ó&×&×&ûð	'üsC   ‚B1’4§2¨4«B1²4´B.¿AB)ÂB ÂB)Â#B1Â)B.Â.B1c                ó0   € V ^8„  d   QhR\         R\        /# )r   r4   r   )rB   Úbool)r   s   "r   r   r   c   s   € ÷ 4ñ 4¬ð 4´tñ 4r   c                ó:   € R\        V 4      P                  4       9   # )z¹Mirror of the gateway adapter's ``_is_thread_not_found_error``.

Matches the gateway adapter's ``_is_thread_not_found_error`` for the standalone ``_send_telegram`` path
(issue #27012).
zthread not found)r   r   )r4   s   &r   Ú_is_telegram_thread_not_foundre   c   s   € ð ¤ U£×!1Ñ!1Ó!3Ñ3Ð3r   c                ó*  € ^ RI Hp  ^ RIHp V! RR.R7      pV'       g
   V! V R7      # ^ RIHp \        P                  RV4       V! W! VR	7      V! VR	7      R
7      #   \         d!   p\        P                  RT4        Rp?MRp?ii ; iT! T R7      # )z~Bot honouring TELEGRAM_PROXY (standalone sends time out where api.telegram.org is
blocked); falls back to a direct connection.)ÚBot)Úresolve_proxy_urlÚTELEGRAM_PROXYzapi.telegram.org)Útarget_hosts)Útoken)ÚHTTPXRequestz>send_message: standalone Telegram send routed through proxy %s)Úproxy)rk   ÚrequestÚget_updates_requestzUsend_message: failed to attach Telegram proxy (%s), falling back to direct connectionN)
Útelegramrg   Úgateway.platforms.baserh   Útelegram.requestrl   rZ   ÚinforB   r[   )rk   rg   rh   rm   rl   Ú	proxy_errs   &     r   Ú_telegram_botru   l   s�   € õ ð	{Ý<Ù!Ð"2ÐBTÐAUÔVˆßÙ˜UÔ#Ð#Ý1Ü�‰ÐTÐV[Ô\Ù˜¨¸5Ô(AÑWcÐjoÔWpÔqÐqøÜô {Ü�‰ÐnÐpy×zÑzûð{úá�UÔÐs!   ˆA ¡A ª3A ÁB	Á)BÂB	c                óÀ   € V f   / #  ^ RI Hp VP                  \        V 4      4      pVf   / # RV/#   \         d!    \        T 4      R8X  d   RM
\        T 4      p L4i ; i)u­   Topic id -> ``message_thread_id`` kwargs. Forum "General" is thread "1" inbound but
the Bot API rejects message_thread_id=1, so it maps to no thread â€” same as the adapter.N©ÚTelegramAdapterÚ1Úmessage_thread_id)Ú"plugins.platforms.telegram.adapterrx   Ú_message_thread_id_for_sendr   rB   rC   )Ú	thread_idrx   Ú	effectives   &  r   Ú_telegram_thread_kwargsr   }   sm   € ð ÒØˆ	ðFÝFØ#×?Ñ?ÄÀIÃÓOˆ	ð Ò"ˆ2ÐHÐ)<¸iÐ(HÐHøô ô FÜ 	›N¨cÔ1‘D´s¸9³~Š	ðFús   ˆ 2 ²(AÁAc                óF   €  ^ RI Hp V! V 4      #   \         d    T u # i ; i)zNStrip MarkdownV2 escapes for the plain-text fallback; identity if unavailable.)Ú_strip_mdv2)r{   r�   rB   )r   r�   s   & r   Ú_strip_mdv2_safer‚   Š   s)   € ðÝBÙ˜4Ó Ð øÜô ØŠðús   ‚ � Ÿ c                ób   € V'       d   R# V \         9   d   R# V \        9   d   R# V'       d   R# R# )z�``(adapter method, kind)``: document when forced, else image / video / voice by
extension (``voice`` already folds in the caller's audio rule).)Úsend_documentÚdocument)Úsend_image_fileÚimage)Ú
send_videoÚvideo)Ú
send_voiceÚaudio)Ú_IMAGE_EXTSÚ_VIDEO_EXTS)ÚextÚvoiceÚforce_documents   &&&r   Ú_adapter_media_methodr‘   “   s8   € ÷ Ø*Ð*Ø
ŒkÔØ)Ð)Ø
ŒkÔØ$Ð$ß&+Ð"ÐNÐ1NÐNr   c              ‹  óà   a"  € \        V3R lV'       d   R
M\        R3\        R3V'       d   \        MR
R3\        R33 4       R4      p\        V RV 24      ! R
RV/Wr/BVB G R	j  x€L
 #  L5i)z~Bot API media method by extension: photo (unless forced document), video, voice note,
sendAudio (MP3/M4A only), else document.c              3   ó>   <"  € T F  w  rSV9   g   K  Vx € K  	  R # 5irI   r<   )rJ   ÚextsÚkrŽ   s   &  €r   rL   Ú'_telegram_send_media.<locals>.<genexpr>¢   s)   øé € ð !ñ #v‘w�tà˜4‘K÷ ’ó #vùs   ƒ“
Úphotor‰   r�   r‹   r…   Úsend_r:   Nr<   )ÚnextrŒ   r�   Ú_VOICE_EXTSÚ_TELEGRAM_SEND_AUDIO_EXTSrN   )r^   r:   ÚfrŽ   Úis_voicer�   r_   Úkinds   &&&f&&, r   Ú_telegram_send_mediarŸ   Ÿ   s}   øé € ô ô !¯.¡B¼kÈ7Ð#SÔVaÐcjÐUkß4<¥[À"ÀgÐ$NÔQjÐlsÐPtñ#vó !à",ó.€Dô ˜  d V˜nÔ-ÑU°gÐUÀ$ÀÐUÈfÑU×UÐUÑUùs   ƒ*A.®9A.Á'A,Á(A.c              ƒ  ó  a aa"  € V VV3R lp V! W#4      G Rj  x€L
 #  L  \          dÞ   p\        T4      '       dO   SP                  R4      e<   \        P	                  RSP                  R4      4       T! Y#4      G Rj  x€L 
 u Rp?# \        T4      P                  4       pRT9   g   RT9   g   RT9   dK   \        P	                  RT\        T4      4       T! T'       d   TM
\        T4      R4      G Rj  x€L 
 u Rp?# h Rp?ii ; i5i)	z¹One text chunk with adapter-matching fallbacks: thread-not-found -> retry without
``message_thread_id`` (dropped from ``text_kwargs`` for later chunks too); parse failure
-> plain text.c           	   “   óD   <"  € \        S3R SRV RV/SB G Rj  x€L
 #  L5i)r:   r   Ú
parse_modeN)ra   )r   Úmoder^   r:   Útext_kwargss   &&€€€r   ÚsendÚ'_telegram_send_text_chunk.<locals>.send¬   s.   øé € Ü6°sÑwÀGÐwÐRVÐwÐcgÐwÐkvÑw×wÐwÑwùs   ƒ ™š Nrz   zIThread %s not found in _send_telegram, retrying without message_thread_idÚparseÚmarkdownÚhtmlzFParse mode %s failed in _send_telegram, falling back to plain text: %s)
rB   re   ÚgetrZ   r[   Úpopr   r   r.   r‚   )	r^   r:   Úchunkr¢   Úhas_htmlr¤   r¥   Úmd_errorÚerr_texts	   ff&&&f   r   Ú_telegram_send_text_chunkr°   ¨   sÞ   úé € ÷xðÙ˜%Ó,×,Ð,Ñ,øÜô ô )¨×2Ò2°{·±ÐGZÓ7[Ò7gÜ�N‰NÐfØ&Ÿ?™?Ð+>Ó?ôAá˜eÓ0×0Ð0Õ0Ü�x“=×&Ñ&Ó(ˆØ�hÔ *°Ô"8¸FÀhÔ<NÜ�N‰NÐcØ%Ô';¸HÓ'EôGá§x™eÔ5EÀeÓ5LÈdÓS×SÐSÕSØûðüsn   …	D�! š›! žDŸ! ¡D	¬ADÂ BÂDÂD	ÂDÂA-DÃ8C;Ã9DÃ=D	Ã>DÄDÄD	Ä	Dc             ƒ  óp	  "  € \         P                  P                  V4      ^,          P                  4       p	V	\        9   ;'       d    Tp
/ VCVe   V
'       g   RVRV/M/ CpV
'       g   V	\
        9   dX   \        P                  ! \        4      ;_uu_ 4        ^ RI	H
p \        P                  ! WÂ4      G Rj  x€L
 pVe   WÛR&   RRR4       RpV	\        9   d¦   \        P                  ! \        4      ;_uu_ 4        ^ RI	HpHp \        P                  ! Wò4      G Rj  x€L
 pV'       dM   VP!                  V4       \        P                  ! VVVP#                  R4      4      G Rj  x€L
 pV'       d   WëR&   RRR4        \%        VR4      ;_uu_ 4       p \'        WVW“V3/ VB G Rj  x€L
 uuRRR4       V'       dC   \        P                  ! \(        4      ;_uu_ 4        \         P*                  ! V4       RRR4       # #  ELI  + '       g   i     ELH; i Lù L³  + '       g   i     L­; i L†  + '       g   i     # ; i  \         EdŽ   p\-        T4      P                  4       p\/        T4      '       d>   TP#                  R	4      '       d'   \0        P3                  R
TP5                  R	4      4       MŒTP#                  R4      '       du   RT9   g   RT9   dg   \0        P3                  R\7        T4      4       TP5                  RR4       T'       g-   TP#                  R4      '       d   \9        TR,          4      TR&   Mh TP;                  ^ 4       \'        YTY“T3/ TB G Rj  x€L 
 u Rp?uuRRR4       T'       dV   \        P                  ! \(        4      ;_uu_ 4        \         P*                  ! T4       RRR4       #   + '       g   i     # ; i# Rp?ii ; i  + '       g   i     M; i T'       dX   \        P                  ! \(        4      ;_uu_ 4        \         P*                  ! T4       RRR4       R#   + '       g   i     R# ; iR#   T'       dV   \        P                  ! \(        4      ;_uu_ 4        \         P*                  ! T4       RRR4       i   + '       g   i     i ; ii ; i5i)z¡Upload one file with adapter-matching fallbacks (thread-not-found -> no
``message_thread_id``; caption parse failure -> plain caption); retries re-seek the file.NÚcaptionr¢   )Ú_probe_voice_duration_secondsÚduration)Ú_probe_video_geometryÚ_video_thumbnail_jpegÚ	thumbnailÚrbrz   zFThread %s not found for media send, retrying without message_thread_idr§   z7Caption parse failed for media send, retrying plain: %s)r   r   r   r   rš   r›   Ú
contextlibÚsuppressrB   r{   r³   r\   Ú	to_threadr�   rµ   r¶   Úupdaterª   ÚopenrŸ   ÚOSErrorÚremover   re   rZ   r[   r«   r.   r‚   Úseek)r^   r:   Ú
media_pathr�   r²   r¢   r­   Úthread_kwargsr�   rŽ   Ú
voice_noteÚmedia_kwargsr³   r´   Ú
thumb_pathrµ   r¶   Úgeometryrœ   Ú	media_errr¯   s   &&&&$$$$$            r   Ú_telegram_send_one_mediarÈ   ¿   s�  é € ô �'‰'×
Ñ
˜:Ó
& qÕ
)×
/Ñ
/Ó
1€CØœÑ#×0Ð0¨€Jð\�mð \Ø+2Ò+>Çzð *3°G¸\È:Ñ(VØWYð\€Lç�SÔ5Ô5Ü× Ò ¤×+Õ+ÝXÜ$×.Ò.Ð/LÓY×YˆHØÒ#Ø+3˜ZÑ(÷	 ,ð
 €JØ
ŒkÔô
 × Ò ¤×+Õ+ßgÜ$×.Ò.Ð/DÓQ×QˆHßØ×#Ñ# HÔ-Ü#*×#4Ò#4Ð5JÈJÐX`×XdÑXdÐeoÓXpÓ#q×q�
ßØ0: Ñ-÷ ,ð&Ü�*˜d×#Ô# qðrÜ1°#ÀÀ3ÐR`ÑqÐdpÑq×q÷ $Ñ#÷& Ü×$Ò$¤W×-Õ-Ü—	’	˜*Ô%÷ .Ð-ð òK Z÷ ,×+Ð+úñ Rñ r÷ ,×+úñ r÷$ .×-ûô# õ rÜ˜y›>×/Ñ/Ó1�Ü0°×;Ò;À×@PÑ@PÐQd×@eÒ@eÜ—N‘NÐ#kØ#/×#3Ñ#3Ð4GÓ#HõJà!×%Ñ% l×3Ò3¸ÀHÔ9LÐPYÐ]eÔPeÜ—N‘NÐ#\Ü#7¸	Ó#BôDà ×$Ñ$ \°4Ô8ß#¨×(8Ñ(8¸×(CÒ(CÜ2BÀ<ÐPYÕCZÓ2[˜ YÑ/øàØ—‘�q”	Ü1°#ÀÀ3ÐR`ÑqÐdpÑq×qÐqÔq÷# $Ñ#÷& Ü×$Ò$¤W×-Õ-Ü—	’	˜*Ô%÷ .×-×-Ð-úð ûð!rú÷ $×#úÐ#÷& Ü×$Ò$¤W×-Õ-Ü—	’	˜*Ô%÷ .×-×-Ò-úñ ø�:Ü×$Ò$¤W×-Õ-Ü—	’	˜*Ô%÷ .×-×-Ð-úð üsŽ  ‚AR6ÁR6Á*-R6Â HÂ7H Â8HÃ7R6Ã;"HÄHÄHÄ*;HÅ%HÅ&HÅ2HÅ6R6Å?Q ÆOÆIÆ'H.Æ(IÆ+
Q Æ5*R6ÇH0Ç6
R6È HÈH	È	R6ÈHÈHÈH+	È&R6È.IÈ0I È;R6ÉOÉA OÊ<OËAOÌ+:OÍ%M(
Í&OÍ*OÍ+OÍ/
Q Í9R6Î"R6Î#OÎ:	R6ÏOÏ	R6ÏOÏOÏO/	Ï*Q Ï3R6Ï;"R6ÐP>Ð4
R6Ð>Q	Ñ	R6Ñ+R3Ñ?R	Ò	R3ÒR/Ò*	R3Ò3R6c                ó
  € ^ RI Hp \        P                  ! RV 4      '       d   WP                  R3#  ^ RIHp VP                  V4      P                  V 4      VP                  R3#   \         d    YP                  R3u # i ; i)z ``(formatted, parse_mode, has_html)``: text already containing HTML tags is sent as
HTML; otherwise Markdown -> MarkdownV2 via the adapter's ``format_message``.)Ú	ParseModez<[a-zA-Z/][^>]*>Trw   F)Útelegram.constantsrÊ   ÚreÚsearchÚHTMLr{   rx   Ú__new__Úformat_messageÚMARKDOWN_V2rB   )r0   rÊ   rx   s   &  r   Ú_telegram_formatrÒ   ö   s{   € õ -Ü	‡y‚yÐ$ g×.Ò.ØŸ™¨Ð,Ð,ð5ÝFØ×&Ñ& Ó7×FÑFÀwÓOÐQZ×QfÑQfÐhmÐmÐmøÜô 5Ø×-Ñ-¨uÐ4Ò4ð5ús   ³2A& Á&BÂBc              ƒ  ó  "  €  \        V4      w  rxp	\        V 4      p
^ RIHp ^ RIHpHp V! V4      pT;'       g    . p\        V4      p/ VCV'       d   RR/M/ CpR. Rppp\        W#\        R7      w  ppVe   V! V4      \        8:  d   TRppVP                  4       '       d   VP                  VRVR	7      MR F  p\        W®VW‰V4      G Rj  x€L
 pK  	  V F�  w  pp\        P                  P                  V4      '       gX   VP!                  R
V 24       \"        P%                  VR,          4       Ve"   Vf    \'        V
3RVRVRV/VB G Rj  x€L
 pRpK‚   \-        W®VVVVWŸVR7	      G Rj  x€L
 pKŸ  	  Vf   R\0        /V'       d   RV/C# / C# \3        RVV\5        VP6                  4      R7      #  Lè Lf  \(         d*   p\"        P%                  R\+        T4      4        Rp?L‘Rp?ii ; i L€  \(         dI   pTP!                  \+        RT RT 24      4       \"        P/                  TR,          4        Rp?EKi  Rp?ii ; i  \8         d    RR\;        R4       2/u # \(         d   p\=        RT 24      u Rp?# Rp?ii ; i5i)zGOne-shot Telegram Bot API send; parse failures fall back to plain text.)Únormalize_telegram_chat_id)ÚBasePlatformAdapterÚ	utf16_lenÚdisable_web_page_previewTN)r   r
   r   )Úlen_fnz Media file not found, skipping: r:   r   r¢   z;Telegram caption-fallback send failed for missing media: %s)r²   r¢   r­   rÂ   r�   zFailed to send media z: r4   r;   rp   ©Ú
message_idz(python-telegram-bot not installed. Run: zTelegram send failed: r<   éÿÿÿÿ)rÒ   ru   Ú'plugins.platforms.telegram.telegram_idsrÔ   rq   rÕ   rÖ   r   r   Ú_TELEGRAM_CAPTION_LIMITr   Útruncate_messager°   r   r   ÚexistsÚappendrZ   r[   ra   rB   r.   rÈ   r4   Ú_NO_DELIVERABLEr>   r   rÚ   ÚImportErrorr   r5   )rk   r:   r0   r   r}   Údisable_link_previewsr�   Ú	formattedÚsend_parse_modeÚ	_has_htmlr^   rÔ   rÕ   rÖ   Úint_chat_idrÂ   r¤   Úlast_msgr;   Ú_tg_captionÚ_capÚ_r¬   rÁ   r�   Ú_cap_errÚes   &&&&&&&                    r   Ú_send_telegramrî     sÇ  é € ð14Ü0@ÀÓ0IÑ-ˆ	 IÜ˜EÓ"ˆÝVßIñ 1°Ó9ˆØ!×'Ð' RˆÜ/°	Ó:ˆàp˜Ðp×QfÐ,FÈÑ+MÐlnÐpˆØ*.°°D˜K�(ˆô ' wÔMdÔe‰ˆˆaØÒ¡	¨)Ó 4Ô8OÔ OØ%.°˜ˆKà`i×`oÑ`o×`qÒ`qÐ(×9Ñ9¸)ÀTÐR[Ð9Ô\ÐwyÒyˆEÜ6°sÈÐP_ÐlwÓx×xŠHñ zã$/Ñ ˆJ˜Ü—7‘7—>‘> *×-Ò-Ø—‘Ð"BÀ:À,Ð OÔPÜ—‘˜x¨�|Ô,àÒ*¨xÒ/?ðGÜ)JØñ*sØ)4ð*sØ;Fð*sØSbð*sØfqñ*s÷ $s˜à&*˜ñ ð+Ü!9Ø j°(ÀKÐ\kØ&ÐTbô"d÷ d’ñ %0ð* ÒØœ_Ð]Ï8°*¸hÐ1GÐ]Ð]ÐY[Ð]Ð]Ü˜
 G¨XÄ#Àh×FYÑFYÓBZÔ[Ð[ñ1 yñ$søô %ô GÜŸ™Ð'dÜ';¸HÓ'E÷Gñ GûðGúñ
døô ô +Ø—‘Ô 4Ð7LÈZÈLÐXZÐ[\ÐZ]Ð5^Ó _Ô`Ü—‘˜X b�\×*Ó*ûð+ûô ô /ØÐCÜ 
Ó+Ð,ð.ð /ò 	/äô 4ÜÐ.¨q¨cÐ2Ó3Õ3ûð4üsö   ‚J„B I Â%*I ÃF8ÃA-I Ä>F<ÅF:ÅF<ÅI ÅG5Å2G3Å3G5Å7I ÆI ÆJÆI ÆJÆ!I Æ7JÆ8I Æ:F<Æ<G0ÇG+Ç&I Ç+G0Ç0I Ç3G5Ç5IÈ <IÈ<I ÉIÉI ÉJ
É&JÉ(J
É1J
É2JÉ?J
Ê JÊJ
Ê
JÚlookup_failed_warningc               óV  €  ^ RI Hp V! 4       pVf   R#  \        VRR4      p\	        V4      '       g   W3P
                  P                  V 4      3# ^ RIHp W4! W! 4       4      3#   \         d    Rp Ldi ; i  \         d'    T'       d   \        P                  TRR7       TR3u # i ; i)uÏ  ``(runner, adapter)`` for the in-process gateway; ``(None, None)`` standalone (cron);
``(runner, None)`` when the lookup fails â€” logged when a warning is given, never silently
swallowed (a silent fall-through could recreate a reconnect storm).

Multiplex: the adapter is the ACTIVE PROFILE's (``_profile_adapters[profile]``), never a bare
``runner.adapters`` hit â€” that map holds the default profile's bots, so a secondary profile's turn
would post/react with the default bot's identity. A profile with no adapter for the platform
yields ``None`` (fail closed â†’ the caller's scoped standalone sender or an error), never the
default bot. Same resolver shape as ``hermes_cli/platform_actions.py::_resolve_adapter``.)Ú_gateway_runner_refNÚ_authorization_adapter)Úget_active_profile_nameT)Úexc_info©NN)Úgateway.runrñ   rB   rN   ÚcallableÚadaptersrª   Úhermes_cli.profilesró   rZ   r[   )r7   rï   rñ   ÚrunnerÚresolveró   s   &$    r   Ú_live_adapterrü   9  s³   € ðÝ3Ù$Ó&ˆð ‚~ØÐð	Ü˜&Ð":¸DÓAˆÜ˜× Ò ØŸ?™?×.Ñ.¨xÓ8Ð8Ð8Ý?Ø�w˜xÐ)@Ó)BÓCÐCÐCøô ô ØŠðûô ô ß Ü�N‰NÐ0¸4ˆNÔ@Ø�tˆ|Òðús.   ‚A$ –9A7 ÁA7 Á$A4Á3A4Á7B(Â
B(Â'B(ÚlabelÚdiscoverTc               óÀ   € ^ RI Hp V'       d   ^ RIHp V! 4        VP	                  V 4      pVe   VP
                  f   RRT;'       g    T  R2/3# VP
                  R3# )z‡``(standalone_sender_fn, None)`` for a registered plugin or ``(None, error_dict)``;
``discover`` runs the idempotent plugin scan first.)Úplatform_registry)Údiscover_pluginsNr4   z6 plugin not registered or missing standalone_sender_fn)Úgateway.platform_registryr   Úhermes_cli.pluginsr  rª   Ústandalone_sender_fn)Úplatform_namerý   rþ   r   r  Úentrys   &$$   r   Ú_plugin_standalone_senderr  V  se   € õ <ßÝ7ÙÔØ×!Ñ! -Ó0€EØ‚}˜×2Ñ2Ò:Ø�g %×"8Ð"8¨=Ð!9Ð9oÐpÐqÐqÐqØ×%Ñ% tÐ+Ð+r   c              ƒ  ó`   "  € \        V 4      w  rVT;'       g    V! WW4R7      G Rj  x€L
 #  L5i)z?One-shot text send through a plugin's ``standalone_sender_fn``.)r}   N)r  )r  Úpconfigr:   r0   r}   ÚsenderÚerrs   &&&&&  r   Ú_registry_standalone_sendr  c  s,   é € ä+¨MÓ:�K€FØ×NÐN™˜w°ÔN×NÐNÑNùs   ‚%.§,¨.c              ƒ  óð  aaa"  € VP                  R4      '       g   VP                  R4      '       g   VR3#  ^ RIp ^ RIHpHp T! T! 4       4      w  poRR	T  2R
R/oTP                  ! R)RTP                  ^R7      /TB ;_uu_4       GRj  x€L
 oTTT3R lpTP                  R4      '       Ed   T\        R4      R pTP                  4       P                  R4      P                  4       p. Rr©\        ^4       EF;  pT! RR^È/T
'       d   RT
/M/ C4      G Rj  x€L
 pTP                  R4      '       g5   R\        RTP                  RR4       24      3u uuRRR4      GRj  x€L
  # YœP                  R. 4       Uu. uFt  qÝP                  R4      '       d   K  TP                  R4      '       d   K4  \!        TP                  RR4      4      P                  4       P                  4       T8X  g   Kr  TNKv  	  up,          p	TP                  R4      ;'       g    / P                  R4      p
T
'       d   EK<   M	  T	'       g$   R\        RT R24      3uuRRR4      GRj  x€L
  # \        T	4      ^8”  d$   R\        RT R 24      3uuRRR4      GRj  x€L
  # RT	^ ,          P                  R!4       2pT! R"R#T\        R4      R /4      G Rj  x€L
 pTP                  R4      '       g4   R\        R$TP                  RR4       R%24      3uuRRR4      GRj  x€L
  # TP                  R&4      ;'       g    / P                  R!4      pT'       d   TR3MR\        R'4      3uuRRR4      GRj  x€L
  #   \         d    RRR\        R4       2/3u # i ; i EL EL} EL6u upi  ELC EL LÚ L“ L@  + GRj  x€L 
 '       g   i     R# ; i  \"         d   pR\        R(T 24      3u Rp?# Rp?ii ; i5i)*a  Resolve ``user:U...`` / ``user_name:<handle>`` to a D... DM conversation (chat.postMessage
needs a conversation ID); ``user_name:`` goes through users.list first (stable handle match
only); other ids pass through. ``(chat_id, None)`` or ``(None, error_dict)``.zuser:z
user_name:Nr4   zaiohttp not installed. Run: Ú	messaging)rh   Úproxy_kwargs_for_aiohttpÚAuthorizationzBearer zContent-Typezapplication/jsonrG   )Útotalc              “   óü   <"  € SP                   ! R V  23RSRV/SB ;_uu_4       GRj  x€L
 pVP                  4       G Rj  x€L
 uuRRR4      GRj  x€L
  #  L. L L	  + GRj  x€L 
 '       g   i     R# ; i5i)zhttps://slack.com/api/ÚheadersÚjsonN)Úpostr  )ÚmethodÚpayloadÚrespÚ_req_kwr  Úsessions   && €€€r   Úpost_apiÚ,_resolve_slack_user_target.<locals>.post_apiy  ss   øé € Ø"Ÿ<š<Ð*@ÀÀÐ(Iñ 3ÐSZð 3Ðahð 3Ø*1÷3÷ 3ò 3Ø6:Ø!%§¡£×,÷3÷ 3ô 3á,÷3÷ 3÷ 3ó 3üs\   ƒ'A<ªA«A<®AÁAÁAÁA<ÁAÁA<ÁAÁA<ÁA9	Á%A(Á&
A9	Á1A9	Á3	A<Ú@z
users.listÚlimitÚcursorÚokzSlack users.list error: ÚunknownÚmembersÚdeletedÚis_botÚnamer
   Úresponse_metadataÚnext_cursorzCould not resolve Slack user '@z'.zSlack user '@z<' matched multiple Slack users. Use a Slack user ID instead.Úidzconversations.openÚusersz Slack conversations.open error: z#. Check bot permissions (im:write).Úchannelz7Slack conversations.open did not return a DM channel IDzSlack DM resolution failed: r<   )Ú
startswithÚaiohttprâ   r   rq   rh   r  ÚClientSessionÚClientTimeoutr   r   Úlstripr   rX   rª   r5   r   rB   )rk   r:   r,  rh   r  Ú_sess_kwr  r%  ÚqueryÚmatchesr  Ú_pageÚdatar&   ÚopenedÚdm_idrí   r  r  r  s   &&               @@@r   Ú_resolve_slack_user_targetr7  i  sÁ  úé € ð ×Ñ˜w×'Ò'¨7×+=Ñ+=¸l×+KÒ+KØ˜ˆ}Ðð6Ûð$@ßVÙ4Ñ5FÓ5HÓIÑˆ�'Ø" g¨e¨WÐ$5°~ÐGYÐZˆØ×(Ò(Ñ]°×1FÑ1FÈRÐ1FÓ1PÐ]ÐT\×]×]Ò]Ðah÷-ð
 ×!Ñ! ,×/Ó/Øœs <Ó0Ð1Ð2�ØŸ
™
›×+Ñ+¨CÓ0×6Ñ6Ó8�Ø"$ d˜Ü" 2ŸY�EÙ!)¨,¸À#Ð8p×`fÈ8ÐU[ÑJ\ÐlnÐ8pÓ!q×q�DØŸ8™8 DŸ>š>Ø#¤VÐ.FÀtÇxÁxÐPWÐYbÓGcÐFdÐ,eÓ%fÐfÑf÷ ^×]Ò]ð ¯8©8°I¸rÔ+Bó  UÑ+B aÏ5É5ÐQZ×K[¤Ð_`×_dÑ_dÐem×_n¤Ü$'¨¯©¨f°bÓ(9Ó$:×$@Ñ$@Ó$B×$HÑ$HÓ$JÈeÑ$S÷ !" Ñ+Bñ  Uõ U�Gà"Ÿh™hÐ':Ó;×AÐA¸r×FÑFÀ}ÓU�Fß!š6Ùñ '÷ Ø¤Ð*IÈ$ÈÈrÐ(RÓ!SÐS÷+ ^×]Ò]ô, �w“< !Ô#Ø¤¨-¸°vÐ=yÐ(zÓ!{Ð{÷/ ^×]Ò]ð0 " '¨!¥*§.¡.°Ó"6Ð!7Ð8�Ù#Ð$8¸7ÀGÌCÐPWËLÈMÐDZÐ:[Ó\×\ˆFØ—:‘:˜d×#Ò#ØœVÐ&FÀvÇzÁzÐRYÐ[dÓGeÐFfð gHð %Hó Ið I÷7 ^×]Ò]ð: —Z‘Z 	Ó*×0Ð0¨b×5Ñ5°dÓ;ˆEß$)�E˜4‘=°´fÐ=vÓ6wÐ/x÷= ^×]Ò]øô ô 6Ø�gÐ=Ü% kÓ2Ð3ð 5ð 6ð 6ò 	6ð6úò ^ò rò ^ùò Uõ ^ñ2 ]÷3 ^×]×]Õ]ûô> ô @Ø”VÐ:¸1¸#Ð>Ó?Ð?Õ?ûð@üs´  ….O6´O6¹M4 ¾AO ÂNÂO ÂB
N1ÄN
ÄN1Ä9!N1ÅO Å'NÅ(O Å,O6Å-N1ÆN ÆN Æ79N Ç5N Ç; N1ÈN1È9N1ÉN1ÉO É"N%É#O É'O6É( N1ÊO ÊN(ÊO ÊO6Ê5N1ËN+ËN1Ë, N1ÌO ÌN-ÌO ÌO6ÌN1Ì7N1ÍN1Í!O Í.N/Í/O Í3O6Í4NÎO6ÎNÎO6ÎO ÎN1ÎO Î N1Î%O Î(O Î+N1Î-O Î/O Î1O	Î7N:Î8
O	ÏO	ÏO Ï	O6ÏO ÏO3ÏO.Ï(O3Ï)O6Ï.O3Ï3O6c           	   ƒ  óª  "  € T;'       g    . pV'       d   RV/MRp^ RI Hp \        VP                  RR7      w  rxVe   \	        W�W#V4      G Rj  x€L
 #  ^ RIHp	 T	! T 4      p
 T
P                  4       G Rj  x€L
 '       gO   \        R
4      \        P                  ! \        4      ;_uu_ 4        T
P                  4       G Rj  x€L
  RRR4       # \	        Y¡Y#T4      G Rj  x€L
 \        P                  ! \        4      ;_uu_ 4        T
P                  4       G Rj  x€L
  RRR4       #  LØ  \         d    RR\        R	4       2/u # i ; i LÓ LŠ  + '       g   i     # ; i L� LI  + '       g   i     # ; i  \         dp   p\        RT 24      u Rp?\        P                  ! \        4      ;_uu_ 4        T
P                  4       G Rj  x€L 
  RRR4       #   + '       g   i     # ; iRp?ii ; i  \        P                  ! \        4      ;_uu_ 4        T
P                  4       G Rj  x€L 
  RRR4       i   + '       g   i     i ; i; i5i)u.  Matrix adapter send (native media preserved). Prefer the live gateway adapter's persistent
olm/megolm session: ephemeral per-send connects re-init E2EE and claim one-time keys, which
under bursts exhausts recipient OTKs and silently drops messages â€” ephemeral is cron-only.

When a live gateway adapter is available (i.e. the tool runs inside a running gateway), the persistent
connection is reused â€” one olm/megolm session for all sends. This avoids per-message E2EE re-init storms
that exhaust recipient OTKs and silently drop messages (issue #46310).
r}   N)ÚPlatformzlMatrix: live gateway adapter lookup failed; falling back to an ephemeral connect (may re-init E2EE per send))rï   )ÚMatrixAdapterr4   z(Matrix dependencies not installed. Run: ÚmatrixzMatrix connect failedúMatrix send failed: )Úgateway.configr9  rü   ÚMATRIXÚ_matrix_send_coreÚ plugins.platforms.matrix.adapterr:  râ   r   Úconnectr5   r¹   rº   rB   Ú
disconnect)r	  r:   r0   r   r}   Úmetadatar9  rë   Úlive_adapterr:  Úadapterrí   s   &&&&&       r   Ú_send_matrix_via_adapterrF  œ  sÚ  é € ð ×#Ð# €Kß+4�˜YÑ'¸$€HÝ'Ü# H§O¡Oð	8ô:�O€Að Òä& |¸gÐT\Ó]×]Ð]ð-ÝBñ ˜GÓ$€Gð'Ø—_‘_Ó&×&Ö&ÜÐ1Ó2ô
 × Ò ¤×+Õ+Ø×$Ñ$Ó&×&Ð&÷ ,Ð+ô	 ' w¸ÈxÓX×Xô × Ò ¤×+Õ+Ø×$Ñ$Ó&×&Ð&÷ ,Ð+ñ ^øô ô -ØÐCÜ Ó)Ð*ð,ð -ò 	-ð-úñ
 'ñ '÷ ,×+úñ	 Yñ
 '÷ ,×+ûô ô 2ÜÐ,¨Q¨CÐ0Ó1Ô1ä× Ò ¤×+Õ+Ø×$Ñ$Ó&×&Ñ&÷ ,×+×+Ð+þð2ûô × Ò ¤×+Õ+Ø×$Ñ$Ó&×&Ñ&÷ ,×+×+Ð+ÿsN  ‚I—9IÁD)ÁIÁD+ ÁIÁ%E: Á8EÁ9	E: Â
E: Â"IÂ/EÃE
ÃEÃ	IÃE: Ã!E#Ã"E: Ã%"IÄE'ÄE%
ÄE'Ä 
IÄ+E	ÅIÅE	Å	IÅE: ÅEÅE ÅIÅ#E: Å%E'Å'E7Å2IÅ:G4ÆG/ÆG4ÆG7 Æ"IÆ9GÇG
ÇGÇ	IÇG,Ç'IÇ/G4Ç4G7 Ç7#IÈH=	È.H1È/H=	È4	IÈ=IÉIÉIc              ƒ  óè  "  € RpVP                  4       '       dF   V P                  WVR7      G Rj  x€L
 pVP                  '       g   \        RVP                   24      # V Fä  w  rg\
        P                  P                  V4      '       g   \        RV 24      u # \
        P                  P                  V4      ^,          P                  4       p\        Yˆ\        9   ;'       d    T;'       g
    V\        9   4      w  rš\        W	4      ! WVR7      G Rj  x€L
 pVP                  '       d   KÌ  \        RVP                   24      u # 	  Vf	   R\        /# \        RWP                   R7      #  EL< LZ5i)	z=Core send logic shared by live and ephemeral Matrix adapters.N)rC  r<  zMedia file not found: zMatrix media send failed: r4   r;  rÙ   )r   r¥   r9   r5   r4   r   r   rß   r   r   r‘   rš   Ú_AUDIO_EXTSrN   rá   r>   rÚ   )rE  r:   r0   r   rC  Úlast_resultrÁ   r�   rŽ   r  rë   s   &&&&&      r   r?  r?  ¿  sC  é € à€KØ‡}�}‡‚Ø#ŸL™L¨ÀH˜LÓM×MˆØ×"×"Ð"ÜÐ0°×1BÑ1BÐ0CÐDÓEÐEÛ +Ñˆ
Ü�w‰w�~‰~˜j×)Ò)ÜÐ2°:°,Ð?Ó@Ò@Ü�g‰g×Ñ˜zÓ*¨1Õ-×3Ñ3Ó5ˆÜ)¨#´{Ñ0B×0OÐ0OÀx×/fÐ/fÐTWÔ[fÑTfÓg‰	ˆÜ# GÔ4°WÐS[Ô\×\ˆØ×"×"Ò"ÜÐ6°{×7HÑ7HÐ6IÐJÓKÒKñ !,ð *5Ò)<ˆG”_Ð%ð  AÄ(È8ÐU\×iÑiô  CAð  Aò Nñ ]ùs;   ‚/E2±E-²E2ÁBE2Ã%	E2Ã/&E2ÄE0ÄE2Ä.A E2Å0E2>   ú.gifú.jpgú.pngú.jpegú.webp>   ú.3gpú.aviú.mkvú.movú.mp4ú.webm>   ú.m2ar   r   r   ú.wavú.flacr   >   ú.mdú.csvú.docú.pdfú.txtú.zipú.docxú.xlsxrI   )zbad gatewayÚ502ztoo many requestsÚ429zservice unavailableÚ503zgateway timeoutÚ504)F)NNFFrõ   )1Ú__doc__Úpmr   r\   r¹   Úloggingr   rÌ   ÚtimeÚagent.redactr   Ú	getLoggerrZ   rŒ   r�   rH  rš   r›   r   rÝ   Ú_DEFAULT_CAPTION_LIMITr   ÚcompileÚ
IGNORECASEr*   r,   r.   r5   r>   rá   rS   rT   ra   re   ru   r   r‚   r‘   rŸ   r°   rÈ   rÒ   rî   rü   r  r  r7  rF  r?  r<   r   r   Ú<module>rm     sR  ðÙ Iå Û Û Û Û 	Û 	Û å .à	×	Ò	Ð4Ó	5€â8€Ú?€ÚH€Ø�wÐ€Ø# VÐ,Ð à +Õ-Ò0qÕqÐ àÐ ØÐ òð —z’zØWÐY[×YfÑYfóhÐ àŸJšJØQÐSU×S`ÑS`óbÐ õRõ4÷
<ð V€ð9Ð õjð'ÀA÷ 'õ4òò"
Iòô	OòVòò.4&òn
5ô34ðl°Tô ð:
,°dð 
,ÀTô 
,ôOò/@ôf 'ôFAr   