+
    i                     ~   R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ]P                  ! ]
4      t]P                  ! R4      t]P                  ! R4      t0 R<mt0 R=mt0 R>mtRR0t]P                  ! R]P&                  4      t]P                  ! R]P&                  4      tR	 R
 ltR R lt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. //tR  tR! tR" tR# R$ ltR% tR& tR' R( ltR?R) lt R?R* lt!R+ t"R, t#R- t$R. t%R/ t&R0 t'R1 t(R2 t)R3 t*R4 t+R5 t,R?R6 lt-R7 t.^ R8I/H0t0 ]0Pb                  ! RR9]]].R:R;7       R# )@a$  Send Message Tool -- cross-channel messaging via platform APIs.

Sends a message to a user or channel on any connected messaging platform
(Telegram, Discord, Slack). Supports listing available targets and resolving
human-friendly channel names to IDs. Works in both CLI and gateway contexts.
N)redact_sensitive_textz^\s*(-?\d+)(?::(\d+))?\s*$zD^\s*((?:oc|ou|on|chat|open)_[-A-Za-z0-9]+)(?::([-A-Za-z0-9_]+))?\s*$.ogg.opuszP([?&](?: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   "4/home/ubuntu/hermes-agent/tools/send_message_tool.py__annotate__r   #   s      #     c                x    \        V 4      p\        P                  R V4      p\        P                  R V4      pV# )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>&   s    QWWQZL2Dr   c                 *    V P                  ^4       R2# )r   z=***r   r   s   &r   r   r   '   s    !''!*T7Jr   )r   _URL_SECRET_QUERY_REsub_GENERIC_SECRET_ASSIGN_RE)textredacteds   & r   _sanitize_error_textr   #   s7    $T*H#''(DhOH(,,-JHUHOr   c                0    V ^8  d   QhR\         R\        /# )r   messager   )r	   dict)r
   s   "r   r   r   +   s     4 4C 4D 4r   c                    R\        V 4      /# )z9Build a standardized error payload with redacted content.error)r   )r   s   &r   _errorr#   +   s    )'233r   namesend_messagedescriptiona  Send a message to a connected messaging platform, or list available targets.

IMPORTANT: When the user asks to send to a specific channel or person (not just a bare platform name), call send_message(action='list') FIRST to see available targets, then send to the correct one.
If the user just says a platform name like 'send to telegram', send directly to the home channel without listing first.
parameterstypeobject
propertiesactionstringenumsendlistzAction to perform. 'send' (default) sends a message. 'list' returns all available channels/contacts across connected platforms.targeta  Delivery target. Format: 'platform' (uses home channel), 'platform:#channel-name', 'platform:chat_id', or Telegram topic 'telegram:chat_id:thread_id'. Examples: 'telegram', 'telegram:-1001234567890:17585', 'discord:#bot-home', 'slack:#engineering', 'signal:+15551234567'r   zThe message text to sendrequiredc                ^    V P                  RR4      pVR8X  d   \        4       # \        V 4      # )z-Handle cross-channel send_message tool calls.r+   r.   r/   )get_handle_list_handle_send)argskwr+   s   &, r   send_message_toolr8   P   s-    XXh'F~r   c                      ^ RI Hp  \        P                  ! RV ! 4       /4      #   \         d-   p\        P                  ! \        RT 24      4      u Rp?# Rp?ii ; i)z5Return formatted list of available messaging targets.)format_directory_for_displaytargetsz"Failed to load channel directory: N)gateway.channel_directoryr:   jsondumps	Exceptionr#   )r:   es     r   r4   r4   Z   sQ    LJzz9&B&DEFF Lzz&#EaS!IJKKLs   "% A!AAAc                \
   V P                  RR4      pV P                  RR4      pV'       d	   V'       g   \        P                  ! RR/4      # VP                  R^4      pV^ ,          P	                  4       P                  4       p\        V4      ^8  d   V^,          P	                  4       MRpRpRpV'       d   \        WE4      w  rgpMRpV'       dN   V'       gF    ^ R	IH	p	 V	! WE4      p
V
'       d   \        WJ4      w  rgpM\        P                  ! RR
V RV R2/4      # ^ RIHp V! 4       '       d   \        P                  ! RR/4      #  ^ RIHpHp V! 4       pRTP"                  RTP$                  RTP&                  RTP(                  RTP*                  RTP,                  RTP.                  RTP0                  RTP2                  RTP4                  RTP6                  RTP8                  RTP:                  /pTP                  T4      pT'       g>   RP=                  TP?                  4       4      p\        P                  ! RR T R!T 2/4      # TP@                  P                  T4      pT'       d   TPB                  '       g   \        P                  ! RR"T R#2/4      # ^ R$I"H#p TPI                  T4      w  ppTP	                  4       ;'       g    \K        T4      pRpT'       gY   TPM                  T4      pT'       d   TPN                  pR%pM0\        P                  ! RR&T R'T R(TPQ                  4        R)2/4      # \S        YFT4      pT'       d   \        P                  ! T4      #  ^ R*I*H+p T! \Y        TTTTTTR+7      4      pT'       d:   \[        T\\        4      '       d$   TP                  R,4      '       d   R-T R.T R/2TR0&   \[        T\\        4      '       dU   TP                  R,4      '       d>   T'       d6    ^ R1I/H0p \b        Pd                  ! R2R34      pT! YFTTTR47      '       d   R%TR5&   \[        T\\        4      '       d   RT9   d   \g        TR,          4      TR&   \        P                  ! T4      #   \         d#    \        P                  ! RR
T RT R2/4      u # i ; i  \         d-   p\        P                  ! \!        RT 24      4      u Rp?# Rp?ii ; i  \         d     Li ; i  \         d-   p\        P                  ! \!        R6T 24      4      u Rp?# Rp?ii ; i)7z$Send a message to a platform target.r0    r   r"   z;Both 'target' and 'message' are required when action='send':NF)resolve_channel_namezCould not resolve 'z' on z;. Use send_message(action='list') to see available targets.z). Try using a numeric channel ID instead.)is_interruptedInterrupted)load_gateway_configPlatformzFailed to load gateway config: telegramdiscordslackwhatsappsignalmatrix
mattermosthomeassistantdingtalkfeishuwecomemailsmsz, zUnknown platform: z. Available: z
Platform 'zZ' is not configured. Set up credentials in ~/.hermes/config.yaml or environment variables.BasePlatformAdapterTzNo home channel set for zQ to determine where to send the message. Either specify a channel directly with 'z=:CHANNEL_NAME', or set a home channel via: hermes config set z_HOME_CHANNEL <channel_id>)
_run_async)	thread_idmedia_filessuccesszSent to z home channel (chat_id: )note)mirror_to_sessionHERMES_SESSION_PLATFORMcli)source_labelrY   mirroredzSend failed: )4r3   r=   r>   splitstriplowerlen_parse_target_refr<   rD   r?   tools.interruptrE   gateway.configrG   rH   r#   TELEGRAMDISCORDSLACKWHATSAPPSIGNALMATRIX
MATTERMOSTHOMEASSISTANTDINGTALKFEISHUWECOMEMAILSMSjoinkeys	platformsenabledgateway.platforms.baserW   extract_media_describe_media_for_mirrorget_home_channelchat_idupper_maybe_skip_cron_duplicate_sendmodel_toolsrX   _send_to_platform
isinstancer    gateway.mirrorr^   osgetenvr   ) r6   r0   r   partsplatform_name
target_refr   rY   is_explicitrD   resolved_rE   rG   rH   configr@   platform_mapplatformavailpconfigrW   rZ   cleaned_messagemirror_textused_home_channelhomeduplicate_skiprX   resultr^   ra   s    &                               r   r5   r5   c   s   XXh#Fhhy"%Gzz7$abccLLa E!HNN$**,M%(Z!^q!JGI*;M*V'K +	F+MFH(9-(R%Azz2:,eM? SP Q#   /zz7M233I@$&
 	H%%8##H%%(//(//h))//H%%(//x||L .H		,++-.zz7&8}UZT[$\]^^""8,G'///zz7j  @Z  %[  \  ]  	]:#6#D#DW#M K!'')TT-G-TK&&x0llG $::3M? C;;H/ J@@M@S@S@U?VVpr   5]YWNzz.))7*#'	
 FD!9!9fjj>S>S'6NwiWXYF6N fd##

9(=(=+<!yy)BEJ$][Wcoxyy)-F:& fd##6(926'?CF7Ozz&!!s  	::.zl% O: ;  	  Izz&#B1#!FGHHIN    7zz&=!45667s   $Q9  Q9 R) )AS4 ;8S4 4S4 =4S# 1AS4 9*R&%R&)S 4!SS S #S1.S4 0S11S4 4T+?!T& T+&T+c                0    V ^8  d   QhR\         R\         /# )r   r   r   r   )r
   s   "r   r   r      s      S c r   c                v   V R8X  dA   \         P                  V4      pV'       d$   VP                  ^4      VP                  ^4      R3# V R8X  dA   \        P                  V4      pV'       d$   VP                  ^4      VP                  ^4      R3# VP	                  R4      P                  4       '       d   VRR3# R# )zFParse a tool target into chat_id/thread_id and whether it is explicit.rI   TrR   -N)NNF)_TELEGRAM_TOPIC_TARGET_RE	fullmatchr   _FEISHU_TARGET_RElstripisdigit)r   r   matchs   && r   rg   rg      s    
")33J?;;q>5;;q>477 !++J7;;q>5;;q>477%%''4%%r   c                N   V '       g   R# \        V 4      ^8X  d~   V ^ ,          w  r\        P                  P                  V4      ^,          P	                  4       pV'       d   V\
        9   d   R# V\        9   d   R# V\        9   d   R# V\        9   d   R# R# R\        V 4       R2# )	zJReturn a human-readable mirror summary when a message only contains media.rB   z[Sent voice message]z[Sent image attachment]z[Sent video attachment]z[Sent audio attachment]z[Sent document attachment]z[Sent z media attachments])	rf   r   pathsplitextre   _VOICE_EXTS_IMAGE_EXTS_VIDEO_EXTS_AUDIO_EXTS)rZ   
media_pathis_voiceexts   &   r   r}   r}      s    
;1*1~
ggz*1-335{*)+,+,+,+C$%%899r   c                 D   \         P                  ! RR4      P                  4       P                  4       p \         P                  ! RR4      P                  4       pV '       d	   V'       g   R# \         P                  ! RR4      P                  4       ;'       g    RpRV RVRV/# )	zMReturn the cron scheduler's auto-delivery target for the current run, if any.!HERMES_CRON_AUTO_DELIVER_PLATFORMrB    HERMES_CRON_AUTO_DELIVER_CHAT_IDN"HERMES_CRON_AUTO_DELIVER_THREAD_IDr   r   rY   )r   r   rd   re   )r   r   rY   s      r   _get_cron_auto_delivery_targetr     s    yy<bAGGIOOQHii:B?EEGG7		>CIIKSStIH7Y r   c                J    V ^8  d   QhR\         R\         R\         R,          /# )r   r   r   rY   Nr   )r
   s   "r   r   r     s(      3  QTW[Q[ r   c                (   \        4       pV'       g   R# VR,          V 8H  ;'       d;    \        VR,          4      \        V4      8H  ;'       d    VP                  R4      V8H  pV'       g   R# V  RV 2pVe   VRV 2,          pRRRRR	R
RVRRV R2/# )zRSkip redundant cron send_message calls when the scheduler will auto-deliver there.Nr   r   rY   rC   r[   Tskippedreason#cron_auto_delivery_duplicate_targetr0   r]   zSkipped send_message to z. This cron job will already auto-deliver its final response to that same target. Put the intended user-facing content in your final response instead, or use a different target if you want an additional message.)r   r	   r3   )r   r   rY   auto_targetsame_targettarget_labels   &&&   r   r   r     s    02K 	J=0 	6 	6I&'3w<7	6 	6OOK(I5 
 #_AgY/L!I;' 	447,&|n 5h h
 
r   c           	     
  "   ^ RI Hp ^ RIHp ^ RIHp ^ RIHp	 ^ RIH	p
  ^ RI
Hp RpT;'       g    . pVP                  VP                  VP                  V	P                  VP                   V
P                  /pV'       d   XP                  WP"                  &   VP%                  V 4      pV'       d   VP'                  W>4      pMV.pWP                  8X  d   R	p\)        V4       Fz  w  ppV\+        V4      ^,
          8H  p\-        VP.                  TTV'       d   TM. VR
7      G R	j  xL
 p\1        V\2        4      '       d   VP%                  R4      '       d   Vu # TpK|  	  V# V'       d)   VP5                  4       '       g   RRV P6                   R2/# R	pV'       d   RV P6                   R2pR	pV EF  pWP                  8X  d"   \9        VP.                  VV4      G R	j  xL
 pEM?WP                   8X  d"   \;        VP.                  VV4      G R	j  xL
 pEMWP<                  8X  d"   \?        VP@                  VV4      G R	j  xL
 pEMWPB                  8X  d"   \E        VP@                  VV4      G R	j  xL
 pEMWPF                  8X  d"   \I        VP@                  VV4      G R	j  xL
 pEM{WPJ                  8X  d"   \M        VPN                  VV4      G R	j  xL
 pEMJWPP                  8X  d-   \S        VP.                  VP@                  VV4      G R	j  xL
 pEMWPT                  8X  d,   \W        VP.                  VP@                  VV4      G R	j  xL
 pMWPX                  8X  d,   \[        VP.                  VP@                  VV4      G R	j  xL
 pMWP\                  8X  d!   \_        VP@                  VV4      G R	j  xL
 pMhWP"                  8X  d   \a        WVVR7      G R	j  xL
 pMAWPb                  8X  d!   \e        VP@                  VV4      G R	j  xL
 pMRRV P6                   2/p\1        V\2        4      '       d   VP%                  R4      '       d   Vu # TpEK  	  V'       d_   \1        V\2        4      '       dI   VP%                  R4      '       d2   \g        VP%                  R. 4      4      pVPi                  V4       VVR&   V#   \         d    Rp ELi ; i EL EL EL EL ELs ELE EL EL EL ELm EL@ EL L5i)zRoute a message to the appropriate platform sender.

Long messages are automatically chunked to fit within platform limits
using the same smart-splitting algorithm as the gateway adapters
(preserves code-block boundaries, adds part indicators).
)rH   rV   )TelegramAdapter)DiscordAdapter)SlackAdapter)FeishuAdapterTFN)rZ   rY   r"   zMsend_message MEDIA delivery is currently only supported for telegram; target z had only media attachmentsz#MEDIA attachments were omitted for zM; native send_message media delivery is currently only supported for telegram)rY   z'Direct sending not yet implemented for r[   warnings)5ri   rH   r{   rW   gateway.platforms.telegramr   gateway.platforms.discordr   gateway.platforms.slackr   gateway.platforms.feishur   ImportErrorrj   MAX_MESSAGE_LENGTHrk   rl   rs   r3   truncate_message	enumeraterf   _send_telegramtokenr   r    rd   value_send_discord_send_slackrm   _send_whatsappextrarn   _send_signalru   _send_emailrv   	_send_smsapi_keyrp   _send_mattermostro   _send_matrixrq   _send_homeassistantrr   _send_dingtalk_send_feishurt   _send_wecomr/   append)r   r   r   r   rY   rZ   rH   rW   r   r   r   r   _feishu_available_MAX_LENGTHSmax_lenchunkslast_resultichunkis_lastr   warningr   s   &&&&&&                 r   r   r   .  s	     (::84":  ##K 	?==.;;77L
 (5(H(H__% x(G$55gG $$$!&)HAuCK!O+G)+2K# F &$''FJJw,?,? K *  7==??"..))DF
 	
 G1(..1A BZ Z 	
 K'''(GGF'&w}}guEEF***)'--%HHF('wFFF'&w}}guEEF%$W__guEEF,,,+GMM7=='SXYYF('w}}guUUF///.w}}gmmWV[\\F***)'--%HHF('%9UUF'&w}}guEEF!HHXYZFfd##

7(;(;M= @ :k400[__Y5O5O
B78 "*Jw  "!"6< HEHFEEYU\HUEsJ  TS TAT0T3A4T'S(0TT-TTAT!S"0TS!0TS$0T4S'50T%S*&0TS-;TS0;TS3:T	S6
/T9S9:&T S<!/TS?ATT',T3TSTSTT!T$T'T*T-T0T3T6T9T<T?Tc           
       "    ^ RI Hp ^ RIHp \	        \
        P                  ! RV4      4      pV'       d   TpVP                  p	M7 ^ RIH	p
H
p V
P                  V
4      pVP                  V4      pVP                  p	V! V R7      p\        V4      pT;'       g    . p/ pVe   \        V4      VR&   Rp. pVP!                  4       '       d"    VP"                  ! R#RVR	VR
V	/VB G Rj  xL
 pV EFy  w  pp\.        P0                  P3                  V4      '       g.   RV 2p\(        P+                  V4       VP5                  V4       KY  \.        P0                  P7                  V4      ^,          P'                  4       p \9        VR4      ;_uu_ 4       pV\:        9   d    VP<                  ! R#RVRV/VB G Rj  xL
 pMV\>        9   d    VP@                  ! R#RVRV/VB G Rj  xL
 pMzV\B        9   d(   V'       d    VPD                  ! R#RVRV/VB G Rj  xL
 pMHV\F        9   d    VPH                  ! R#RVRV/VB G Rj  xL
 pMVPJ                  ! R#RVRV/VB G Rj  xL
 pRRR4       EK|  	  Vf   RpV'       d   RVRV/# RV/# RRRRRVR \%        VPN                  4      /pV'       d   VVR&   V#   \         d    Tp ELOi ; i EL  \         d   pR\%        T4      P'                  4       9   g=   R\%        T4      P'                  4       9   g   R\%        T4      P'                  4       9   du   \(        P+                  RT	\-        T4      4       T'       g$    ^ RIH
p T! T4      pM  \         d    Tp Mi ; iTpTP"                  ! R#RTR	TR
R/TB G Rj  xL 
 p Rp?ELh Rp?ii ; i EL EL EL ELw EL[  + '       g   i     EK  ; i  \         dD   p\-        RT RT 24      p\(        PM                  T4       TP5                  T4        Rp?EK(  Rp?ii ; i  \P         d    RR!/u # \         d   p\S        R"T 24      u Rp?# Rp?ii ; i5i)$u0  Send via Telegram Bot API (one-shot, no polling needed).

Applies markdown→MarkdownV2 formatting (same as the gateway adapter)
so that bold, links, and headers render correctly.  If the message
already contains HTML tags, it is sent with ``parse_mode='HTML'``
instead, bypassing MarkdownV2 conversion.
)Bot)	ParseModez<[a-zA-Z/][^>]*>)r   _strip_mdv2)r   Nmessage_thread_idr   r   
parse_modeparsemarkdownhtmlzFParse mode %s failed in _send_telegram, falling back to plain text: %s)r   z Media file not found, skipping: rbphotovideovoiceaudiodocumentzFailed to send media z: ANo deliverable text or media remained after processing MEDIA tagsr"   r   r[   Tr   rI   
message_idzGpython-telegram-bot not installed. Run: pip install python-telegram-botzTelegram send failed:  )*rI   r   telegram.constantsr   boolresearchHTMLr   r   r   __new__format_messager?   MARKDOWN_V2intrd   r%   r	   re   loggerr   r   r   r   existsr   r   openr   
send_photor   
send_videor   
send_voicer   
send_audiosend_documentr"   r   r   r#   )r   r   r   rZ   rY   r   r   	_has_html	formattedsend_parse_moder   r   _adapterbotint_chat_idthread_kwargslast_msgr   md_errorplainr   r   r   r   fr@   r"   r   s   &&&&&                       r   r   r     s    r4 0 #6@A	I'nnO$S*22?C$33G<	 (33O'l!''R 14YM-.??!$!1!1 "'".7"."2?" 6 %0 J77>>*--<ZLIw'(''"":.q1779C)*d++qk)), *$/*78*<I* $ +), *$/*78*<I* $ +), *$/*78*<I* $ +), *$/*78*<I* $ *-):): *$/*:;*?L* $% ,+ %0F WE
H==U## t
w#h112	
 !)F:{  $#	$"  c(m1133zS]EXEXEZ7Z^dhklthuh{h{h}^}NN`',X6
 %,N$/	$:E( ,$+E, !(%(%5%5 & +&27&#'&+8&    H
 +D$$$$$% ,++*  ).1FzlRTUVTW/XYW%(()(  dbcc 4.qc2334s  QAP *J1 2(P 0P K (K)K -BP =O%N96N*
7)N9 N-
!N99N9N0
)N9<N3
=N9N6
N9 O(P ;P  QP Q+P 0Q1K>P KP K N'BN"M%$N"%M52N"4M55 N"NN"P !N""N''P *N9-N90N93N96N99OOP OP7PP PP Q.Q0Q9Q:QQQQQc           
     ^  "    ^ RI p RT R2pRRT  2RR	/pTP                  TP                  ^R
7      R7      ;_uu_4       GRj  xL
 pTP	                  YERT/R7      ;_uu_4       GRj  xL
 pTP
                  R9  dX   TP                  4       G Rj  xL
 p\        RTP
                   RT 24      uuRRR4      GRj  xL
  uuRRR4      GRj  xL
  # TP                  4       G Rj  xL
 p	RRR4      GRj  xL
  RRR4      GRj  xL
  RRRRRTRX	P                  R4      /#   \         d    RR/u # i ; i L L L L Ls L\ LN  + GRj  xL 
 '       g   i     Le; i L\  + GRj  xL 
 '       g   i     Ls; i  \         d   p
\        RT
 24      u Rp
?
# Rp
?
ii ; i5i)zSend a single message via Discord REST API (no websocket client needed).

Chunking is handled by _send_to_platform() before this is called.
Nr"   /aiohttp not installed. Run: pip install aiohttpz%https://discord.com/api/v10/channels/z	/messagesAuthorizationzBot Content-Typeapplication/jsontotaltimeoutcontentheadersr=   zDiscord API error (): r[   Tr   rJ   r   r   idzDiscord send failed:       )aiohttpr   ClientSessionClientTimeoutpoststatusr   r#   r=   r3   r?   )r   r   r   r!  urlr  sessionrespbodydatar@   s   &&&        r   r   r     s    
L35gYiH"d5'NNDVW((1F1FR1F1P(QQQU\||C	7?S|TTTX\;;j0!%,D!$7}Cv"NO UTT RQQ
 "YY[(	 UT RQ 4Y	7LZ^ZbZbcgZhii  LJKKL
 RT, U R
 )	 UTTT RQQQ  3-aS1223sM  F-D* =F D?F 
"E+,E-E+0%E	EE	4E+E
E+F EF F-E	,E	-E	1E+<E=E+F E)F )F-*D<9F-;D<<F-?F E+E	E+F 	E	E+E&E
E&E&!E+)F +F	1E42
F	=F	?F F*F%F* F-%F**F-c                h  "    ^ RI p RpRRT  2RR/pTP                  TP                  ^R	7      R
7      ;_uu_4       GRj  xL
 pTP	                  YERTRT/R7      ;_uu_4       GRj  xL
 pTP                  4       G Rj  xL
 pTP                  R4      '       d>   RRRRRTRTP                  R4      /uuRRR4      GRj  xL
  uuRRR4      GRj  xL
  # \        RTP                  RR4       24      uuRRR4      GRj  xL
  uuRRR4      GRj  xL
  #   \         d    RR/u # i ; i L L L Lt Ld L6 L&  + GRj  xL 
 '       g   i     M; iRRR4      GRj  xL 
  R#   + GRj  xL 
 '       g   i     R# ; i  \         d   p	\        RT	 24      u Rp	?	# Rp	?	ii ; i5i)zSend via Slack Web API.Nr"   r  z&https://slack.com/api/chat.postMessager  Bearer r  r  r  r  channelr   r  okr[   Tr   rK   r   r   tszSlack API error: unknownzSlack send failed: )	r!  r   r"  r#  r$  r=   r3   r#   r?   )
r   r   r   r!  r&  r  r'  r(  r*  r@   s
   &&&       r   r   r   1  s    L
16"geW$5~GYZ((1F1FR1F1P(QQQU\||C	7TZ\c?d|eeeim!YY[(88D>>%tZ)WVbdhdldlmqdrs fee RQQ
  1$((7I2N1OPQ	 fee RQQ  LJKKL
 Re( f Re Reeee RQQQQQ  1+A3/001se  F2D 9F D2F $E/*D4+E/.E 	D6E 	E 	6E/D8
E/F D:F F2E 	8E/D<
E/
F D>F F2D/,F2.D//F22F 4E/6E 	8E/:F <E/>F  EE	
EEE/F 'E*(F -F2/F		5E86
F		F		F F2	F F/F*$F/%F2*F//F2c                  "    ^ RI p T P                  RR4      pTP                  4       ;_uu_4       GRj  xL
 pTP	                  RT R2RTR	T/TP                  ^R
7      R7      ;_uu_4       GRj  xL
 pTP                  ^8X  dV   TP                  4       G Rj  xL
 pRRRRRTRTP                  R4      /uuRRR4      GRj  xL
  uuRRR4      GRj  xL
  # TP                  4       G Rj  xL
 p\        RTP                   RT 24      uuRRR4      GRj  xL
  uuRRR4      GRj  xL
  #   \         d    RR/u # i ; i EL L L L Lz Lc L9 L)  + GRj  xL 
 '       g   i     M; iRRR4      GRj  xL 
  R#   + GRj  xL 
 '       g   i     R# ; i  \         d   p	\        RT	 24      u Rp	?	# Rp	?	ii ; i5i)z,Send via the local WhatsApp bridge HTTP API.Nr"   r  bridge_porti  zhttp://localhost:z/sendchatIdr   r  )r=   r  r[   Tr   rL   r   r   	messageIdzWhatsApp bridge error (r  zWhatsApp send failed: )r!  r   r3   r"  r$  r#  r%  r=   r   r#   r?   )
r   r   r   r!  r2  r'  r(  r*  r)  r@   s
   &&&       r   r   r   D  s    L4iit4((***g||#K=6G<--B-7 $    ;;#%!%,D!4"J!7$dhh{&;	   +** "YY[( 7}CvNO   +**	  LJKKL + - + ) +    +*****   4.qc2334sn  GD6 .F( EF( 9F4E5F8%E	EE	:FE
FF( EF( GE	2E3E	FE
F#F( 0E1F( 5G6EGEGF( FE	FF( E	FF( E5"E%#
E5.E50F8F( FF( 	GF%	F
F%	F%	F( #G%F( (G3G GGGGc                f  "    ^ RI p T P                  RR4      P                  R4      pT P                  RR4      pT'       g   RR	/# RTR
T/pTP	                  R4      '       d   TR,          TR&   MT.TR&   RRRRRTRR\        \        P                  ! 4       R,          4       2/pTP                  RR7      ;_uu_4       GRj  xL
 pTP                  T R2TR7      G Rj  xL
 p	T	P                  4        T	P                  4       p
RT
9   d(   \        RT
R,           24      uuRRR4      GRj  xL
  # RRRRR T/uuRRR4      GRj  xL
  #   \         d    RR/u # i ; i L L L8 L   + GRj  xL 
 '       g   i     R# ; i  \         d   p\        R!T 24      u Rp?# Rp?ii ; i5i)"z!Send via signal-cli JSON-RPC API.Nr"   httpx not installedhttp_urlzhttp://127.0.0.1:8080/accountrB   zSignal account not configuredr   zgroup::   NNgroupId	recipientjsonrpcz2.0methodr.   paramsr  send_        >@r  z/api/v1/rpcr=   zSignal RPC error: r[   Tr   rM   r   zSignal send failed: )httpxr   r3   rstrip
startswithr   timeAsyncClientr$  raise_for_statusr=   r#   r?   )r   r   r   rD  r7  r9  r?  payloadclientr(  r*  r@   s   &&&         r   r   r   `  s    0299Z)@AHHM))Ir*<==Wi9h'' 'F9#*)F; uffE#diikD0123	
 $$T$222fz%=GLLD!!#99;D$ 24=/BC 322 tZ9gN 322+  0.//0* 3L 3222  2,QC0112s   F1E :F F F1F %A!F E&F 
E.$E(%?E.$F 1E*2F 6F17E.>F E,F F1E# F1"E##F1&F (E.*F ,F .F	4E75
F	 F	F F1F F.F)#F.$F1)F..F1c                  "   ^ RI p^ RIHp V P                  R4      ;'       g    \        P
                  ! RR4      p\        P
                  ! RR4      pV P                  R4      ;'       g    \        P
                  ! RR4      p\        \        P
                  ! R	R
4      4      p\        WVV.4      '       g   RR/#  V! VRR4      p	WYR&   WR&   RV	R&   VP                  Wx4      p
V
P                  \        P                  ! 4       R7       V
P                  WV4       V
P                  V	4       V
P                  4        RRRRRV/#   \         d   p\!        RT 24      u Rp?# Rp?ii ; i5i)z:Send via SMTP (one-shot, no persistent connection needed).N)MIMETextaddressEMAIL_ADDRESSrB   EMAIL_PASSWORD	smtp_hostEMAIL_SMTP_HOSTEMAIL_SMTP_PORT587r"   zNEmail not configured (EMAIL_ADDRESS, EMAIL_PASSWORD, EMAIL_SMTP_HOST required)r  zutf-8FromTozHermes AgentSubject)contextr[   Tr   rT   r   zEmail send failed: )smtplibemail.mime.textrM  r3   r   r   r   allSMTPstarttlssslcreate_default_contextloginr%   quitr?   r#   )r   r   r   rY  rM  rN  passwordrQ  	smtp_portmsgserverr@   s   &&&         r   r   r     s8    (ii	"DDbii&DGyy)2.H		+&JJ"))4Er*JIBII/78I9-..ijj1w1FD	'Ii3 : : <=W'C 4WiII 1+A3/001s>   A)E),AE)<BE E)E&E!E&E)!E&&E)c                  "    ^ RI p^ RIp\        P                  ! RR4      p\        P                  ! RR4      pT'       d   T '       d	   T'       g   RR/# \
        P                  ! RR	T\
        P                  R
7      p\
        P                  ! RR	T\
        P                  R
7      p\
        P                  ! RR	T\
        P                  R
7      p\
        P                  ! RR	T\
        P                  R
7      p\
        P                  ! RRT4      p\
        P                  ! RR	T4      p\
        P                  ! RRT\
        P                  R
7      p\
        P                  ! RR	T4      p\
        P                  ! RRT4      pTP                  4       p T RT  2pTP                  TP                  R4      4      P                  R4      pRT R2p	RRT 2/p
TP                  TP                  ^R7      R7      ;_uu_4       GRj  xL
 pTP                  4       pTP!                  RT4       TP!                  RT4       TP!                  RT4       TP#                  YT
R7      ;_uu_4       GRj  xL
 pTP%                  4       G Rj  xL
 pTP&                  R 8  d[   TP)                  R!\+        T4      4      p\-        R"TP&                   R#T 24      uuRRR4      GRj  xL
  uuRRR4      GRj  xL
  # TP)                  R$R4      pR%R&R'R(R)TR*T/uuRRR4      GRj  xL
  uuRRR4      GRj  xL
  #   \         d    RR/u # i ; i ELG L L Ls Lc L7 L'  + GRj  xL 
 '       g   i     M; iRRR4      GRj  xL 
  R#   + GRj  xL 
 '       g   i     R# ; i  \.         d   p\-        R+T 24      u Rp?# Rp?ii ; i5i),zSend a single SMS via Twilio REST API.

Uses HTTP Basic auth (Account SID : Auth Token) and form-encoded POST.
Chunking is handled by _send_to_platform() before this is called.
Nr"   r  TWILIO_ACCOUNT_SIDrB   TWILIO_PHONE_NUMBERzXSMS not configured (TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_PHONE_NUMBER required)z\*\*(.+?)\*\*z\1)flagsz	\*(.+?)\*z	__(.+?)__z_(.+?)_z```[a-z]*\n?z`(.+?)`z
^#{1,6}\s+z\[([^\]]+)\]\([^\)]+\)z\n{3,}z

rC   asciiz+https://api.twilio.com/2010-04-01/Accounts/z/Messages.jsonr  zBasic r  r  rU  rV  Body)r*  r  i  r   zTwilio API error (r  sidr[   Tr   rU   r   r   zSMS send failed: )r!  r   base64r   r   r   r   DOTALL	MULTILINErd   	b64encodeencodedecoder"  r#  FormData	add_fieldr$  r=   r%  r3   r	   r#   r?   )
auth_tokenr   r   r!  rm  account_sidfrom_numbercredsencodedr&  r  r'  	form_datar(  r)  	error_msgmsg_sidr@   s   &&&               r   r   r     s    L ))0"5K))126Kjstt ff%ugRYYGGff\5'CGff\5'CGffZryyAGff_b'2GffZ0Gff]Br||DGff.w?GffY0GmmoG/-q-""5<<#89@@I;K=W"fWI$67((1F1FR1F1P(QQQU\((*I4g.0||C|IIIT!YY[(;;#% $CI >I!$6t{{m3yk"RS	 JII RQQ ((5"-!4UIwP\^ef JII RQQ9  LJKKL8 R J( J R J R JIII RQQQQQ  /)!-../s{  OL2 9OO
OD<OA1N"  MN" A&N*M
+N.M	MA
M	NM
NN" ,M-N" 1O2M	NM
NN" ,M-N" 1O2MOMON" 
NM	NN" NN" M/M
M/(M/*N2N" =N >N" ON	N
N	N	N" ON" "O-O :O;O OOc           
     H  "    ^ RI p TP                  R4      ;'       g    \        P                  ! RR4      P                  R4      pT ;'       g    \        P                  ! RR4      p T'       d	   T '       g   RR	/# T R
2pRRT  2RR/pTP                  TP                  ^R7      R7      ;_uu_4       GRj  xL
 pTP                  YgRTRT/R7      ;_uu_4       GRj  xL
 p	T	P                  R9  dX   T	P                  4       G Rj  xL
 p
\        RT	P                   RT
 24      uuRRR4      GRj  xL
  uuRRR4      GRj  xL
  # T	P                  4       G Rj  xL
 pRRR4      GRj  xL
  RRR4      GRj  xL
  RRRRRTRXP                  R4      /#   \         d    RR/u # i ; i L L L L Ls L\ LN  + GRj  xL 
 '       g   i     Le; i L\  + GRj  xL 
 '       g   i     Ls; i  \         d   p\        RT 24      u Rp?# Rp?ii ; i5i)zSend via Mattermost REST API.Nr"   r  r&  MATTERMOST_URLrB   r8  MATTERMOST_TOKENzEMattermost not configured (MATTERMOST_URL, MATTERMOST_TOKEN required)z/api/v4/postsr  r,  r  r  r  r  
channel_idr   r  zMattermost API error (r  r[   Tr   rO   r   r   r  zMattermost send failed: r  )r!  r   r3   r   r   rE  r"  r#  r$  r%  r   r#   r=   r?   )r   r   r   r   r!  base_urlr&  r  r'  r(  r)  r*  r@   s   &&&&         r   r   r     s    L6IIe$GG		2BB(GOOPST::#5r:udee
-("geW$5~GYZ((1F1FR1F1P(QQQU\||CgW`bi?j|kkkos;;j0!%,D!$:4;;-s4&"QR lkk RQQ
 "YY[(	 lk RQ 4\9g|]a]e]efj]kll  LJKKL Rk, l R
 )	 lkkk RQQQ  604556sp  H"F G< /G< G< 1G< 9G< <H"=<G< 9F4:G< =$G !F6"G %%G	
F8G	)G 6F:
7G ;G< F<	G< H"G	!F>"G	&G 1G 2G 6G< GG< H"F1.H"0F11H"4G< 6G 8G	:G <G< >G	 G GG	
GGG G<  G9	&G)'
G9	2G9	4G< <HHHH"HH"c           
       "    ^ RI p TP                  R4      ;'       g    \        P                  ! RR4      P                  R4      pT ;'       g    \        P                  ! RR4      p T'       d	   T '       g   RR	/# R
\        \        P                  ! 4       R,          4       R\        P                  ! ^4      P                  4        2pT RT RT 2pRRT  2RR/pRRRT/p	 ^ RI
p
T
P                  TRR.R7      p\        P                  ! RRT4      pRT	R&   YR&   TP                  TP                  ^R7      R7      ;_uu_4       GRj  xL
 pTP                  YxT	R 7      ;_uu_4       GRj  xL
 pTP                   R+9  dX   TP#                  4       G Rj  xL
 p\%        R!TP                    R"T 24      uuRRR4      GRj  xL
  uuRRR4      GRj  xL
  # TP'                  4       G Rj  xL
 pRRR4      GRj  xL
  RRR4      GRj  xL
  R#R$R%R&R'TR(XP                  R)4      /#   \         d    RR/u # i ; i  \         d     EL3i ; i EL	 L L L L Lo La  + GRj  xL 
 '       g   i     Lx; i Lo  + GRj  xL 
 '       g   i     L; i  \(         d   p\%        R*T 24      u Rp?# Rp?ii ; i5i),zSend via Matrix Client-Server API.

Converts markdown to HTML for rich rendering in Matrix clients.
Falls back to plain text if the ``markdown`` library is not installed.
Nr"   r  
homeserverMATRIX_HOMESERVERrB   r8  MATRIX_ACCESS_TOKENzGMatrix not configured (MATRIX_HOMESERVER, MATRIX_ACCESS_TOKEN required)hermes_rA  r   z/_matrix/client/v3/rooms/z/send/m.room.message/r  r,  r  r  msgtypezm.textr)  fenced_codetables)
extensionsz<h[1-6]>(.*?)</h[1-6]>z<strong>\1</strong>zorg.matrix.custom.htmlr
   formatted_bodyr  r  r  zMatrix API error (r  r[   Tr   rN   r   r   event_idzMatrix send failed: r  )r!  r   r3   r   r   rE  r   rG  urandomhexr   r   r   r"  r#  putr%  r   r#   r=   r?   )r   r   r   r   r!  r  txn_idr&  r  rJ  _mdr   r'  r(  r)  r*  r@   s   &&&&             r   r   r     s    L2ii-SS;NPR1S[[\_`
==#8"=fgg3tyy{T1231RZZ]5F5F5H4IJ5gY>STZS[\"geW$5~GYZ h8	"<<]H4M<ND6635KTRD 8GH(,$% ((1F1FR1F1P(QQQU\{{3g{FFF$;;j0!%,D!$6t{{m3tf"MN GFF RQQ
 "YY[(	 GF RQ 4Xy'<Y]YaYablYmnn;  LJKKL(  		 RF, G R
 )	 GFFF RQQQ  2,QC0112s  KH. J /J J 1J 9J <K=A&J $:I .J IJ  J0I1J4%I$	II$	8JI
J
J IJ KI$	0I 1I$	5J I"JJ J J -K.I =K?I  KIJ IJ JI$	JJ  I$	"J$I=*I-+
I=6I=8J J J	J	
J	J	J K)J<6K7K<KKc           
       "    ^ RI p TP                  R4      ;'       g    \        P                  ! RR4      P                  R4      pT ;'       g    \        P                  ! RR4      p T'       d	   T '       g   RR	/# T R
2pRRT  2RR/pTP                  TP                  ^R7      R7      ;_uu_4       GRj  xL
 pTP                  YgRTRT/R7      ;_uu_4       GRj  xL
 p	T	P                  R9  dX   T	P                  4       G Rj  xL
 p
\        RT	P                   RT
 24      uuRRR4      GRj  xL
  uuRRR4      GRj  xL
  # RRR4      GRj  xL
  RRR4      GRj  xL
  RRRRRT/#   \         d    RR/u # i ; i L L L LZ LJ L;  + GRj  xL 
 '       g   i     LR; i LI  + GRj  xL 
 '       g   i     L`; i  \         d   p\        RT 24      u Rp?# Rp?ii ; i5i)z'Send via Home Assistant notify service.Nr"   r  r&  HASS_URLrB   r8  
HASS_TOKENz=Home Assistant not configured (HASS_URL, HASS_TOKEN required)z/api/services/notify/notifyr  r,  r  r  r  r  r   r0   r  zHome Assistant API error (r  r[   Tr   rP   r   zHome Assistant send failed: r  )r!  r   r3   r   r   rE  r"  r#  r$  r%  r   r#   r?   )r   r   r   r   r!  hass_urlr&  r  r'  r(  r)  r@   s   &&&&        r   r   r     s    L:IIe$AA		*b(AII#N44<4u\]]
56"geW$5~GYZ((1F1FR1F1P(QQQU\||C	7T\^e?f|gggko;;j0!%,D!$>t{{m3tf"UV hgg RQQgg RQ
 4_iQQ  LJKKL Rg, h Rgggg RQQQ  :4QC899:sX  G7E6 G /G G 1G 9G <G7=<G 9F:G =$F5!F"F5%%F	
FF	)F56F
7F5;G F	G G7F5FF5G )F3*G 5G76FG7FG7G F5F	F5G F5F0F 
F0)F0+F53G 5G	;F><
G	G		G G4G/)G4*G7/G44G7c           
       "    ^ RI p T P                  R4      ;'       g    \        P                  ! RR4      pT'       g   RR/# TP                  RR	7      ;_uu_4       GRj  xL
 pTP                  TR
RRRT//R7      G Rj  xL
 pTP                  4        TP                  4       pTP                  R^ 4      ^ 8w  d1   \        RTP                  RR4       24      uuRRR4      GRj  xL
  # RRR4      GRj  xL
  RRRRRT/#   \         d    RR/u # i ; i L L L6 L'  + GRj  xL 
 '       g   i     L>; i  \         d   p\        RT 24      u Rp?# Rp?ii ; i5i)aY  Send via DingTalk robot webhook.

Note: The gateway's DingTalk adapter uses per-session webhook URLs from
incoming messages (dingtalk-stream SDK).  For cross-platform send_message
delivery we use a static robot webhook URL instead, which must be
configured via ``DINGTALK_WEBHOOK_URL`` env var or ``webhook_url`` in the
platform's extra config.
Nr"   r6  webhook_urlDINGTALK_WEBHOOK_URLrB   zkDingTalk not configured. Set DINGTALK_WEBHOOK_URL env var or webhook_url in dingtalk platform extra config.rB  r  r  r   r  rC  errcodezDingTalk API error: errmsgr0  r[   Tr   rQ   r   zDingTalk send failed: )rD  r   r3   r   r   rH  r$  rI  r=   r#   r?   )	r   r   r   rD  r  rK  r(  r*  r@   s	   &&&      r   r   r   /  sY    04ii.WW"))<RTV2W  K  L  L$$T$222f)W1EF %  D !!#99;Dxx	1%* 4TXXh	5R4STU 32222 4ZGLL  0.//0 3 3222  4.qc2334s   E'D E E E E'E #D$E 'D%DAD%E *D!+E /E'0E ;D#<E E'DE'DE'E D%!E #E %D>	+D.,
D>	7D>	9E E$EE$E'E$$E'c                  "    ^ RI HpHp V! 4       '       g   RR/#   ^ RIHp T! T R7      pT! T4      pTP                  4       G Rj  xL
 pT'       g#   \        RTP                  ;'       g    R	 24      #  TP                  Y4      G Rj  xL
 p	T	P                  '       g1   \        R
T	P                   24      TP                  4       G Rj  xL
  # RRRRRTRT	P                  /TP                  4       G Rj  xL
  #   \         d    RR/u # i ; i L L LJ L   TP                  4       G Rj  xL 
  i ; i  \         d   p
\        R
T
 24      u Rp
?
# Rp
?
ii ; i5i)z;Send via WeCom using the adapter's WebSocket send pipeline.)WeComAdaptercheck_wecom_requirementsr"   z?WeCom requirements not met. Need aiohttp + WECOM_BOT_ID/SECRET.zWeCom adapter not available.)PlatformConfig)r   NzWeCom: failed to connect - zunknown errorzWeCom send failed: r[   Tr   rS   r   r   )gateway.platforms.wecomr  r  r   ri   r  connectr#   fatal_error_messager.   r[   r"   
disconnectr   r?   )r   r   r   r  r  r  r   adapter	connectedr   r@   s   &&&        r   r   r   N  sN    9R'))^__ *
11 u-w'!//++	78S8S8f8fWf7ghii	'"<<99F>>> 3FLL>BC $$&&& tZ)Wl\b\m\mn$$&&&!  97889 , :
 ''$$&&& 1+A3/001s   E!D  E!*D; 	D
D; D; /D; 7E!9D DD $D ;D; DD; E!D 'D; :D;D; ?E! DE!DE!D; D D; D; D81D42D88D; ;EEEE!EE!c                ,  "    ^ RI HpHp V'       g   RR/# ^ RI HpHp T;'       g    . p T! T 4      p	\        T	RR4      p
T
R8w  d   TMTpT	P                  T4      T	n        T'       d   RT/MR	pR	pTP                  4       '       dF   T	P                  YTR
7      G R	j  xL
 pTP                  '       g   \        RTP                   24      # T EFZ  w  r\        P                  P!                  T4      '       g   \        RT 24      u # \        P                  P#                  T4      ^,          P%                  4       pT\&        9   d   T	P)                  YTR
7      G R	j  xL
 pMT\*        9   d   T	P-                  YTR
7      G R	j  xL
 pMqT\.        9   d%   T'       d   T	P1                  YTR
7      G R	j  xL
 pMBT\2        9   d   T	P1                  YTR
7      G R	j  xL
 pMT	P5                  YTR
7      G R	j  xL
 pTP                  '       d   EKC  \        RTP                   24      u # 	  Tf   RR/# RRRRRTRTP6                  /#   \
         d    RR/u # i ; i EL EL L L L Lr  \8         d   p\        RT 24      u R	p?# R	p?ii ; i5i)z7Send via Feishu/Lark using the adapter's send pipeline.)r   FEISHU_AVAILABLEr"   zJFeishu dependencies not installed. Run: pip install 'hermes-agent[feishu]')FEISHU_DOMAINLARK_DOMAIN_domain_namerR   larkrY   N)metadatazFeishu send failed: zMedia file not found: zFeishu media send failed: r   r[   Tr   r   r   )r   r   r  r  r  r   getattr_build_lark_client_clientrd   r.   r[   r#   r"   r   r   r   r   re   r   send_image_filer   r  r   r  r   r  r   r?   )r   r   r   rZ   rY   r   r  r  r  r  domain_namedomainr  r   r   r   r   r@   s   &&&&&             r   r   r   i  su    gLijjG ##K*2(g~x@"-"7[!44V</8K+d==?? 'W QQK&&& 4[5F5F4GHII$/ J77>>*-- 6zlCDD''"":.q1779Ck!$+$;$;GZb$;$cc#$+$6$6wU]$6$^^#$+$6$6wU]$6$^^#$+$6$6wU]$6$^^$+$9$9'X`$9$aa&&& :;;L;L:MNOO# %0& `aa tw+00	
 	
Q  geffg R d^^^a  2,QC0112s   JI JI JJ=I. +I. 	I. I  I. 6I. J<I. 
JAI.  I#!&I. I&I.  I. 6I(7&I. I*I. 9I,:I. I. ,J-	I. 6J7I. 
JIJIJ I. #I. &I. (I. *I. ,I. .J9JJJJJc                     \         P                  ! RR4      p V '       d
   V R8w  d   R#  ^ RIHp V! 4       #   \         d     R# i ; i)zOGate send_message on gateway running (always available on messaging platforms).r_   rB   localT)is_gateway_runningF)r   r   gateway.statusr  r?   )r   r  s     r   _check_send_messager    sC    yy2B7HH'5!## s   7 AA)registry	messagingu   📨)r$   toolsetschemahandlercheck_fnemoji>   .gif.jpg.png.jpeg.webp>   .3gp.avi.mkv.mov.mp4>   .m4a.mp3r   .wavr   )NN)2__doc__r=   loggingr   r   r^  rG  agent.redactr   	getLogger__name__r   compiler   r   r   r   r   r   
IGNORECASEr   r   r   r#   SEND_MESSAGE_SCHEMAr8   r4   r5   rg   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  tools.registryr  registerr   r   r   <module>r     s     	 	 
  .			8	$JJ'DE JJfg 867wzzWMM  JJQMM 4 N	5 (   a
    p 9
 	B# @Ly7x:&>l^z4z3.1&48!2H1:2/j60'2T:.4>1662r	 $   	 
r   