
    ,jB             
          d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
mZ  ej        e          Z ej        d          Z ej        d          Z ej        d          Z ej        d          Z ej        d	          Z ej        d
          ZeZ eh d          Z ej        d          Z ej        d          ZddiZh dZh dZh dZddhZddhZ  ej        dej!                  Z" ej        dej!                  Z#de$fdZ%de$de&fdZ'de(de)de*dz  fdZ+d d!d"e)fd#Z,d$d%d&d'g d(d)d*d'd+d,d'd-d,d'd.d,d'd/d,d0g d1d2Z-d3 Z.d4 Z/dYd6Z0d7 Z1d8e$d9e$fd:Z2d; Z3d< Z4d8e$d=e$d>e$dz  fd?Z5ddd5d@dAZ6dZdBZ7dCe(de8fdDZ9d[dEZ:d\dFZ;dG Z<d\dHZ=dI Z>dJ Z?dK Z@d]dLZAdM ZBdN ZCd\dOZDdP ZEd]dQZFdR ZGdS ZHd\dTZIddUlJmKZKmLZL  eKjM        d$dVe-e.eGdWX           dS )^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)
formatdate)redact_sensitive_textz^\s*(-?\d+)(?::(\d+))?\s*$zD^\s*((?:oc|ou|on|chat|open)_[-A-Za-z0-9]+)(?::([-A-Za-z0-9_]+))?\s*$z^\s*([CGDU][A-Z0-9]{8,})\s*$z%^\s*([CGD][A-Z0-9]{8,}):([^\s:]+)\s*$zS^\s*((?:wxid|gh|v\d+|wm|wb)_[A-Za-z0-9_-]+|[A-Za-z0-9._-]+@chatroom|filehelper)\s*$z ^\s*((?:group|direct):[^:]+)\s*$>   smsphotonsignalwhatsappz^\s*\+(\d{7,15})\s*$z6^\s*[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\s*$emailEMAIL_HOME_ADDRESS>   .gif.jpg.png.jpeg.webp>   .3gp.avi.mkv.mov.mp4>   .wav.flac.m4a.mp3.ogg.opusr   r   r   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,;]+)returnc                     t          |           }t                              d |          }t                              d |          }|S )zCRedact secrets from error text before surfacing it to users/models.c                 2    |                      d           dS )N   z***groupms    </home/ubuntu/.hermes/hermes-agent/tools/send_message_tool.py<lambda>z&_sanitize_error_text.<locals>.<lambda>I   s    QWWQZZ2D2D2D     c                 2    |                      d           dS )Nr   z=***r   r!   s    r#   r$   z&_sanitize_error_text.<locals>.<lambda>J   s    !''!**7J7J7J r%   )r   _URL_SECRET_QUERY_REsub_GENERIC_SECRET_ASSIGN_RE)textredacteds     r#   _sanitize_error_textr,   F   sF    $T**H#''(D(DhOOH(,,-J-JHUUHOr%   messagec                 $    dt          |           iS )z9Build a standardized error payload with redacted content.error)r,   )r-   s    r#   _errorr0   N   s    )'2233r%   excattemptc                 R   t          | dd           }|6	 t          t          |          d          S # t          t          f$ r Y dS w xY wt          |                                           }d|v sd|v rd S d|v sd|v sd|v sd	|v sd
|v sd|v sd|v sd|v rt          d|z            S d S )Nretry_afterg        g      ?z	timed outtimeoutzbad gateway502ztoo many requests429zservice unavailable503zgateway timeout504   )getattrmaxfloat	TypeError
ValueErrorstrlower)r1   r2   r4   r*   s       r#   _telegram_retry_delayrB   S   s    #}d33K	u[))3///:& 	 	 	33	 s88>>Ddi4//tD==$&&D== D((D==$$D==Q'\"""4s   2 AA   )attemptsrD   c                N  K   t          |          D ]}	  | j        di | d {V c S # t          $ rn}t          ||          }|	||dz
  k    r t                              d|dz   ||t          |                     t          j        |           d {V  Y d }~d }~ww xY wd S )Nr   zFTransient Telegram send failure (attempt %d/%d), retrying in %.1fs: %s )	rangesend_message	ExceptionrB   loggerwarningr,   asynciosleep)botrD   kwargsr2   r1   delays         r#   !_send_telegram_message_with_retryrQ   l   s     ?? ' '	'))33F33333333333 	' 	' 	')#w77E}8a< 7 7NNX!$S))   -&&&&&&&&&&&&&&	'' 's   *
B"A$BB"rH   a  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.objectstring)sendlistreactunreacta  Action to perform. 'send' (default) sends a message. 'list' returns all available channels/contacts across connected platforms. 'react' attaches an emoji reaction to a message (platforms that support it, e.g. photon/iMessage tapbacks). 'unreact' retracts a previously-added reaction.)typeenumdescriptiona  Delivery target. Format: 'platform' (uses home channel), 'platform:#channel-name', 'platform:chat_id', or 'platform:chat_id:thread_id' for Telegram topics and Discord threads. Examples: 'telegram', 'telegram:-1001234567890:17585', 'discord:999888777:555444333', 'discord:#bot-home', 'slack:#engineering', 'signal:+155****4567', 'matrix:!roomid:server.org', 'matrix:@user:server.org', 'ntfy:alerts-channel' (explicit ntfy topic), 'yuanbao:direct:<account_id>' (DM), 'yuanbao:group:<group_code>' (group chat))rX   rZ   u   The message text to send. To send an image or file, include MEDIA:<local_path> (e.g. 'MEDIA:/tmp/report.pdf') in the message — the platform will deliver it as a native media attachment.u   For action='react': the emoji to react with (e.g. '❤️'). On iMessage, ❤️👍👎😂‼️❓ render as native tapbacks; other emoji use custom-emoji reactions.zFor action='react'/'unreact': id of the message to react to. Omit to target the most recent message received in that chat (usually the one being replied to).)actiontargetr-   emoji
message_id)rX   
propertiesrequired)namerZ   
parametersc                     |                      dd          }|dk    rt                      S |dk    rt          |           S |dk    rt          | d          S t          |           S )z-Handle cross-channel send_message tool calls.r[   rT   rU   rV   rW   T)remove)get_handle_list_handle_react_handle_send)argskwr[   s      r#   send_message_toolrk      so    XXh''F~~T"""T$////r%   c                      	 ddl m}  t          j        d |             i          S # t          $ r.}t          j        t          d|                     cY d}~S d}~ww xY w)z5Return formatted list of available messaging targets.r   )format_directory_for_displaytargetsz"Failed to load channel directory: N)gateway.channel_directoryrm   jsondumpsrI   r0   )rm   es     r#   rf   rf      s    LJJJJJJz9&B&B&D&DEFFF L L Lz&!Ia!I!IJJKKKKKKKKLs   #& 
A#AAAFc                 8   |                      dd          }|                      d          pd                                }|                      d          pd                                pd}|r|s|st          |sdnd          S |                    dd	          }|d
                                                                         }t          |          d	k    r|d	                                         nd}d}|r@t          ||          \  }}	}
|s*	 d
dlm}  |||          }n# t          $ r d}Y nw xY w|p|}	 d
dl
m}m}  ||          }n)# t          t          f$ r t          d|           cY S w xY w|sR	  |            }|                    |          }n# t          $ r d}Y nw xY w|st          d| d| d          S |j        }d}	 d
dlm}  |            }n# t          $ r d}Y nw xY w||j                             |          nd}|t          d| d          S |rdnd}t)          ||d          }t+          |          st          d| d          S 	 d
dlm} |r | |||                    }n | ||||                    }n;# t          $ r.}t1          j        t5          d|                     cY d}~S d}~ww xY wt7          |t8                    rt1          j        |          S t1          j        dt;          |          i          S )u  Attach (or with ``remove=True`` retract) an emoji reaction on a message
    via a live gateway adapter.

    Only adapters that expose ``add_reaction(chat_id, emoji, message_id)`` /
    ``remove_reaction(chat_id, message_id)`` coroutines support this (e.g.
    photon/iMessage tapbacks). Requires the gateway to be running in this
    process — there is no standalone fallback, since reacting needs the
    adapter's live message-id state.
    r\    r]   r^   Nz:Both 'target' and 'emoji' are required when action='react'z*'target' is required when action='unreact':r   r   resolve_channel_name)Platformload_gateway_configUnknown platform: z.No chat specified and no home channel set for z. Use 'z
:chat_id'._gateway_runner_refzReactions require a live zN adapter in the running gateway (not available from cron/standalone contexts).remove_reactionadd_reaction
Platform 'z%' does not support message reactions.
_run_async)chat_idr^   )r   r]   r^   zReaction failed: success)re   strip
tool_errorsplitrA   len_parse_target_refro   rw   rI   gateway.configrx   ry   r?   KeyErrorget_home_channelr   gateway.runr|   adaptersr;   callablemodel_toolsr   rp   rq   r0   
isinstancedictbool)ri   rd   r\   r]   r^   partsplatform_name
target_refr   
_thread_id_rw   resolvedrx   ry   platformconfighomerunnerr|   adapterfn_namereact_fnr   resultrr   s                             r#   rg   rg      sr    XXh##FXXg$"++--E((<((.B5577?4J 
& 
 
>HH=
 
 	
 LLa  E!HNN$$**,,M%(ZZ!^^q!!!JG -!2=*!M!MQ 		- JJJJJJ//zJJ       
 ,*G@@@@@@@@@8M**! @ @ @>}>>?????@  	((**F**844DD 	 	 	DDD	 	2 2 2%2 2 2   ,F333333$$&&   /5/Afo!!(+++tGE E E E
 
 	
 $*=~Gw..HH 
MMMM
 
 	
;****** 	ZZ@@@ FF  Z*MMM F  ; ; ;z&!8Q!8!899::::::::;&$ "z&!!!:y$v,,/000sf   D# #D21D2:E #E43E4:F F)(F)G G.-G.6J 
K#KKKc                 4  ) |                      dd          }|                      dd          }|r|st          d          S |                    dd          }|d                                                                         }t          |          dk    r|d                                         nd}d}d}|rt          ||          \  }}}nd	}|rw|su	 dd
lm}	  |	||          }
|
rt          ||
          \  }}}nt          j
        dd| d| di          S n-# t          $ r  t          j
        dd| d| di          cY S w xY wddlm}  |            rt          d          S 	 ddlm}m}  |            }n;# t          $ r.}t          j
        t#          d|                     cY d}~S d}~ww xY w	  ||          }n)# t$          t&          f$ r t          d|           cY S w xY w|j                             |          }|r|j        s|dk    rt-          j        dd                                          }t-          j        dd                                          }|re|rcddlm}  |d||t-          j        dd                                          t-          j        dd                                          d          }n&t          d| d          S t          d| d          S dd lm} d!|v }|                    |          \  }}|                    |          }|                                pt;          |          }d	}|s|                    |          }|sC|dk    r=t-          j        d"d                                          }|rdd#lm}  |||d$%          }|r
|j         }d}nPtB                               ||"                                 d&          }t          j
        dd'| d(| d)| d*i          S tG          |||          } | rt          j
        |           S |d+k    r|r|$                    d,          rz	 ddl%))fd-}!dd.l&m'}"  |" |!|j(        |                    }#|#r|#}nt          j
        dd/| d0i          S n0# t          $ r#}t          j
        dd1| i          cY d}~S d}~ww xY w	 dd.l&m'}"  |"tS          |||||||2                    }$|r6tU          |$tV                    r!|$                     d3          rd4| d5| d6|$d7<   tU          |$tV                    re|$                     d3          rP|rN	 dd8l,m-}% dd9l.m/}&  |&d:d;          }' |&d<d          pd}( |%||||'||(=          rd|$d><   n# t          $ r Y nw xY wtU          |$tV                    rd|$v rta          |$d                   |$d<   t          j
        |$          S # t          $ r.}t          j
        t#          d?|                     cY d}~S d}~ww xY w)@z$Send a message to a platform target.r\   rt   r-   z;Both 'target' and 'message' are required when action='send'ru   r   r   NFrv   r/   z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)ry   rx   zFailed to load gateway config: rz   weixinWEIXIN_TOKENWEIXIN_ACCOUNT_IDPlatformConfigTWEIXIN_BASE_URLWEIXIN_CDN_BASE_URL)
account_idbase_urlcdn_base_url)enabledtokenextrar   zZ' is not configured. Set up credentials in ~/.hermes/config.yaml or environment variables.)BasePlatformAdapterz[[as_document]]WEIXIN_HOME_CHANNEL)HomeChannelzWeixin Home)r   r   ra   _HOME_CHANNELz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 <channel_id>slackUc                 >  K   d}d|  dd}                                         d                    4 d {V }|                    ||d|gi	          4 d {V }|                                 d {V }|                    d
          r2|d         d         cd d d           d {V  cd d d           d {V  S 	 d d d           d {V  d d d           d {V  d S # 1 d {V swxY w Y   	 d d d           d {V  d S # 1 d {V swxY w Y   d S )Nz(https://slack.com/api/conversations.openBearer application/jsonAuthorizationzContent-Type
   totalr5   usersheadersrp   okchannelid)ClientSessionClientTimeoutpostrp   re   )r   user_idurlr   sessionrespdataaiohttps          r#   _open_slack_dmz$_handle_send.<locals>._open_slack_dm  s     @,=e,=,=Oabb"009N9NUW9N9X9X0YY $ $ $ $ $ $ $]d&||CRYQZG[|\\ $ $ $ $ $ $ $`d%)YY[[00000088D>> 9#'	?4#8$ $ $ $ $ $ $ $ $ $ $ $ $$ $ $ $ $ $ $ $ $ $ $ $ $ $
  $	$ $ $ $ $ $ $ $ $ $ $ $$ $ $ $ $ $ $ $ $ $ $ $ $ $$ $ $ $ $ $ $ $ $ $ $ $ $ $ $$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $sA   "D =C'DC'D'
C1	1D4C1	5D
DDr   z"Could not open DM with Slack user z#. Check bot permissions (im:write).zFailed to open Slack DM: 	thread_idmedia_filesforce_documentr   zSent to z home channel (chat_id: )note)mirror_to_sessionget_session_envHERMES_SESSION_PLATFORMcliHERMES_SESSION_USER_ID)source_labelr   r   mirroredzSend failed: )1re   r   r   r   rA   r   r   ro   rw   rp   rq   rI   tools.interruptr   r   ry   rx   r0   r?   r   	platformsr   osgetenvr   gateway.platforms.baser   extract_mediafilter_media_delivery_paths_describe_media_for_mirrorr   r   r   _HOME_CHANNEL_ENV_OVERRIDESupper_maybe_skip_cron_duplicate_send
startswithr   r   r   r   _send_to_platformr   r   gateway.mirrorr   gateway.session_contextr   r,   )*ri   r\   r-   r   r   r   r   r   is_explicitrw   r   r   r   ry   rx   r   rr   r   pconfigwx_token
wx_accountr   r   force_document_attachmentsr   cleaned_messagemirror_textused_home_channelr   wx_homer   home_envduplicate_skipr   r   
dm_channelr   r   r   r   r   r   s*                                            @r#   rh   rh     s   XXh##Fhhy"%%G Y YWXXXLLa  E!HNN$$**,,M%(ZZ!^^q!!!JGI *;M:*V*V'KK  + 	FFFFFF++M:FFH (9-(R(R%AAz Q: Q QM Q Q Q#    %&  	 	 	: ;z ; ; ; ; ;     	 /.....~ )-(((I@@@@@@@@$$&& I I Iz&!F1!F!FGGHHHHHHHHI
@8M**! @ @ @>}>>?????@ ""8,,G V'/ V H$$y44::<<H#6;;AACCJ ZJ Z999999(. "&0$&I.?$D$D$J$J$L$L(*	2G(L(L(R(R(T(T    "  #Y}  #Y  #Y  #Y  Z  Z  Z  U=  U  U  U  V  V  V:::::: "3g!=#6#D#DW#M#M K%AA+NNK!''))T-G-T-TK &&x00 	[11i 5r::@@BBG [666666"{HgMZZZ 	lG $266-"5"5"7"7FFF H : XM X X;HX X@HX X X    5]GYWWN *z.))) G0B0B30G0G	JNNN$ $ $ $ $ /.....#NN7='$J$JKKJ @$z7,}QX,},},}"~   	J 	J 	J:w(GA(G(GHIIIIIIII	J'7******#'9  

 

  	ZFD!9!9 	Zfjj>S>S 	ZYYYwYYYF6N fd## 	

9(=(= 	+ 	<<<<<<CCCCCC./H%PP)/*BBGGO4$$!!-'#   . *.F:&    fd## 	D6(9(926'?CCF7Oz&!!! 7 7 7z&!4!4!455666666667s   AD 'EE(E; ;
F3#F.(F3.F37G #G)(G)	AR 
R?R:4R?:R?B	W <V
 	W 

VW VAW 
X)#XXXr   r   c                     | dk    rGt                               |          }|r+|                    d          |                    d          dfS | dk    rGt                              |          }|r+|                    d          |                    d          dfS | dk    rGt                              |          }|r+|                    d          |                    d          dfS | dk    rt
                              |          }|r+|                    d          |                    d          dfS t                              |          }|r$|                    d          }|d         d	v}|d
|fS | dk    rG|                                }|                    d          }|dk    r|d
|         ||dz   d
         dfS | dk    r4t                              |          }|r|                    d          d
dfS | dk    rvt                              |          }|r|                    d          d
dfS |                                                                rd|                                 d
dfS dS | dk    r|                                }|r|d
dfS | dk    r3t                              |          }|r|                                d
dfS | t          v r3t                              |          }|r|                                d
dfS |                    d                                          r|d
dfS | dk    r/|                    d          s|                    d          r|d
dfS | dk    r	d|v r|d
dfS dS )zFParse a tool target into chat_id/thread_id and whether it is explicit.telegramr   r:   Tfeishudiscordr   r   >   r   WNmatrixz:$r   yuanbaogroup:NNFntfyr	   -!@xmpp)_TELEGRAM_TOPIC_TARGET_RE	fullmatchr    _FEISHU_TARGET_RE_NUMERIC_TOPIC_RE_SLACK_THREAD_TARGET_RE_SLACK_TARGET_REr   rfind_WEIXIN_TARGET_RE_YUANBAO_TARGET_REisdigit_EMAIL_TARGET_RE_PHONE_PLATFORMS_E164_TARGET_RElstripr   )r   r   matchr   r   trimmed	split_idxtopics           r#   r   r     s   
"")33J?? 	8;;q>>5;;q>>477  !++J77 	8;;q>>5;;q>>477	!!!++J77 	8;;q>>5;;q>>477'11*== 	8;;q>>5;;q>>477 **:66 	.kk!nnG "!*J6KD+--  ""$$MM$''	q==:I:&	A(@$FF  !++J77 	.;;q>>4--	!!",,Z88 	.;;q>>4--%%'' 	=0J,,..00$<<    "" 	%$$$ **:66 	2##%%tT11((())*55 	2 ##%%tT11%%'' &4%%  j&;&;C&@&@ JDYDYZ]D^D^ 4%%3*#4#44%%r%   c                 :   | sdS t          |           dk    rr| d         \  }}t          j                            |          d                                         }|r|t
          v rdS |t          v rdS |t          v rdS |t          v rdS dS d	t          |            d
S )zJReturn a human-readable mirror summary when a message only contains media.rt   r   r   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])	r   r   pathsplitextrA   _VOICE_EXTS_IMAGE_EXTS_VIDEO_EXTS_AUDIO_EXTS)r   
media_pathis_voiceexts       r#   r   r     s     r
;1*1~
Hgz**1-3355 	*{**))+,,+,,+,,++9C$$9999r%   c                     ddl m}   | dd                                                                          } | dd                                          }|r|sdS  | dd                                          pd}|||dS )	zMReturn the cron scheduler's auto-delivery target for the current run, if any.r   r   !HERMES_CRON_AUTO_DELIVER_PLATFORMrt    HERMES_CRON_AUTO_DELIVER_CHAT_IDN"HERMES_CRON_AUTO_DELIVER_THREAD_ID)r   r   r   )r   r   r   rA   )r   r   r   r   s       r#   _get_cron_auto_delivery_targetr'  $  s    777777BBGGMMOOUUWWHo@"EEKKMMG 7 t DbIIOOQQYUYI  r%   r   r   c                     t                      }|sdS |d         | k    o>t          |d                   t          |          k    o|                    d          |k    }|sdS |  d| }||d| z  }ddd|d| d	d
S )zRSkip redundant cron send_message calls when the scheduler will auto-deliver there.Nr   r   r   ru   T#cron_auto_delivery_duplicate_targetz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   skippedreasonr\   r   )r'  r@   re   )r   r   r   auto_targetsame_targettarget_labels         r#   r   r   3  s    022K t 	J=0 	6I&''3w<<7	6OOK((I5 
  t#//g//LI' 7h| h h h
 
 
r%   r   c                "  K   t          | d          r| j        nt          |           }d}	 ddlm}	  |	            }n# t
          $ r d}Y nw xY w|	 |j                            |           }
n# t
          $ r d}
Y nw xY w|
	 i }|r||d<   |dk    r|r||d<   |sd}|
                    |||           d{V }n-# t          j
        $ r  t
          $ r}d	d
| icY d}~S d}~ww xY w|j        r
d|j        dS d	d|j         iS d}	 ddlm} |                    |          }n# t
          $ r d}Y nw xY w||j        	 |                    ||||||           d{V }nJ# t          j
        $ r  t
          $ r.}t"                              d|d           d	d| icY d}~S d}~ww xY wt'          |t(                    r,|                    d          s|                    d	          r|S d	d| dt+          |          j         iS d	d| diS )a  Send a message via a live gateway adapter, with a standalone fallback
    for out-of-process callers (e.g. cron running separately from the gateway).

    Order of attempts:
      1. Live in-process adapter via ``_gateway_runner_ref()`` (the path that
         existed before this change).
      2. The plugin's ``standalone_sender_fn`` registered on its
         ``PlatformEntry`` (used when the gateway is not in this process, so
         the runner weakref is ``None``).
      3. A descriptive error explaining both options.
    valueNr   r{   r   r  publish_topic)r   contentmetadatar/   zPlugin platform send failed: T)r   r^   zAdapter send failed: platform_registryr   z$Plugin standalone send for %s raisedexc_infozPlugin standalone send failed: r   zPlugin standalone send for 'zR' returned an invalid result: expected a dict with 'success' or 'error' keys, got zNo live adapter for platform 'z'. Is the gateway running with this platform connected? For out-of-process delivery (e.g. cron in a separate process), the platform plugin must register a standalone_sender_fn on its PlatformEntry.)hasattrr0  r@   r   r|   rI   r   re   rT   rL   CancelledErrorr   r^   r/   gateway.platform_registryr5  standalone_sender_fnrJ   debugr   r   rX   __name__)r   r   r   chunkr   r   r   r   r   r|   r   r3  r   rr   entryr5  s                   r#   _send_via_adapterr@  R  s     * '.h&@&@SHNNc(mmMF333333$$&&    	o))(33GG 	 	 	GGG	F 6,5H[) F**w*07H_- $#H&||GUU]|^^^^^^^^)    F F F!D!D!DEEEEEEEF~ J#'v7HIIICV\CCDDE??????!%%m44    U7C	D 55#'- 6        FF % 	 	 	 	D 	D 	DLL?Y]L^^^BqBBCCCCCCC	D fd## 	I)>)> 	&**WBUBU 	M5} 5 5!&\\25 5
 	
 	E] E E E so   = AAA- -A<;A<8B; ;C%C C% C%D$ $D32D3 !E" "F);#F$F)$F)c           
      $  K   ddl m} |pg }| |j        k    rt          ||||           d{V S ddlm}m}	 ddlm}
 	 ddl	m
} d}n# t          $ r d	}Y nw xY w	 dd
lm} d}n# t          $ r d	}Y nw xY w| |j        k    rZ|rX	 |
                    |
          }|                    |          }n,# t"          $ r t$                              dd           Y nw xY w|j        |r|j        nd|j        |
j        i}|r|j        ||j        <   | |vrI	 ddlm} |                    | j                  }|r|j        dk    r
|j        || <   n# t"          $ r Y nw xY w|                    |           }|r(| |j        k    r|	nd}|                    |||          }n|g}| |j        k    rd}t;          t=          |di           o|j                            d                    }tA          |          D ]p\  }}|tC          |          dz
  k    }tE          |j#        |||r|ng |||           d{V }tI          |tJ                    r|                    d          r|c S |}q|S | |j&        k    rddlm} |                    d          }||j'        ddiS d}tA          |          D ]o\  }}|tC          |          dz
  k    }|'                    |||||r|ng            d{V }tI          |tJ                    r|                    d          r|c S |}p|S | |j(        k    r|r}d}tA          |          D ]i\  }}|tC          |          dz
  k    }tS          ||||r|ng |           d{V }tI          |tJ                    r|                    d          r|c S |}j|S | |j*        k    r|rd}tA          |          D ]m\  }}|tC          |          dz
  k    }tW          |j        |||r|ng            d{V }tI          |tJ                    r|                    d          r|c S |}n|S | |j,        k    r}|r{d}tA          |          D ]g\  }}|tC          |          dz
  k    }t[          |||r|nd           d{V }tI          |tJ                    r|                    d          r|c S |}h|S | |j        k    r|r}d}tA          |          D ]i\  }}|tC          |          dz
  k    }t]          ||||r|nd|           d{V }tI          |tJ                    r|                    d          r|c S |}j|S |r!|/                                sdd| j         diS d}|rd| j         d}d}|D ].}| |j        k    r ta          |j#        |||           d{V }n| |j1        k    rte          |j        ||           d{V }n| |j*        k    rtW          |j        ||           d{V }n~| |j3        k    rti          |j        ||           d{V }nU| |j5        k    rtm          |j7        ||           d{V }n,| |j(        k    r#tq          |j#        |j        ||           d{V }n| |j9        k    rtu          |j        ||           d{V }n| |j        k    rt]          ||||           d{V }n| |j;        k    rty          |j        ||           d{V }n| |j=        k    rt}          |j        ||           d{V }na| |j?        k    rt          |||           d{V }n>| |j,        k    rt[          ||           d{V }nt          | ||||||           d{V }tI          |tJ                    r|                    d          r|c S |}0|rgtI          |tJ                    rR|                    d           r=t          |                    d!g                     }|C                    |           ||d!<   |S )"a  Route 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).
    r   )rx   r   N)r   	utf16_len)SlackAdapterTelegramAdapterTF)FeishuAdapterz<Failed to apply Slack mrkdwn formatting in _send_to_platformr6  i   r4  )len_fnr   disable_link_previewsr   )r   r   rI  r   r/   r   z=Discord plugin not registered or missing standalone_sender_fn)r   r   )r   r   zsend_message MEDIA delivery is currently only supported for telegram, discord, matrix, weixin, signal, yuanbao and feishu; target z had only media attachmentsz#MEDIA attachments were omitted for z; native send_message media delivery is currently only supported for telegram, discord, matrix, weixin, signal, yuanbao and feishu)	thread_ts)r   r   r   warnings)Dr   rx   WEIXIN_send_weixinr   r   rC  gateway.platforms.slackrD  gateway.platforms.telegramrF  ImportErrorgateway.platforms.feishurG  SLACK__new__format_messagerI   rJ   r<  TELEGRAMMAX_MESSAGE_LENGTHFEISHUr:  r5  re   r0  max_message_lengthtruncate_messager   r;   r   	enumerater   _send_telegramr   r   r   DISCORDr;  MATRIX_send_matrix_via_adapterSIGNAL_send_signalYUANBAO_send_yuanbao_send_feishur   _send_slackWHATSAPP_send_whatsappEMAIL_send_emailSMS	_send_smsapi_key_send_matrixDINGTALK_send_dingtalkWECOM_send_wecomBLUEBUBBLES_send_bluebubblesQQBOT_send_qqbotr@  rU   append)r   r   r   r-   r   r   r   rx   r   rC  rD  rF  _telegram_availablerG  _feishu_availableslack_adapter_MAX_LENGTHSr5  r?  max_len_len_fnchunkslast_resultrI  ir>  is_lastr   rK   rK  s                                 r#   r   r     s      ('''''#K 8?""!'7GUUUUUUUUUUEEEEEEEE444444$>>>>>>" $ $ $#$"::::::  " " "!" 8>!!g!	h(00>>M#227;;GG 	h 	h 	hLLWbfLggggg	h 	AT^?==Z^7L  I(5(HX_% |##	CCCCCC%))(.99E B1A55).)AX& 	 	 	D	 x((G '8+<<<))$$55gww5WW 8$$$ $WWgr%B%B%qw}GXGXYpGqGq r r!&)) 	! 	!HAuCKK!O+G)+2:KK#&;-        F &$'' FJJw,?,?  KK 8###??????!%%i00=E6>\]]!&)) 	! 	!HAuCKK!O+G 55#+2:KK 6        F &$'' FJJw,?,?  KK 8?""{"!&)) 	! 	!HAuCKK!O+G3+2:KK#        F &$'' FJJw,?,?  KK 8?""{"!&)) 
	! 
	!HAuCKK!O+G'+2:KK	        F &$'' FJJw,?,?  KK 8####!&)) 		! 		!HAuCKK!O+G(+2<KK        F
 &$'' FJJw,?,?  KK 8?""{"!&)) 	! 	!HAuCKK!O+G'+2<KK#        F &$'' FJJw,?,?  KK  
7==?? 
F".F F F
 	
 G 
O(. O O O 	
 K ( (x~%%&w}guPYZZZZZZZZZFF***)'-%HHHHHHHHFF(('wFFFFFFFFFF''&w}guEEEEEEEEFF%%$W_guEEEEEEEEFF(('w}guUUUUUUUUFF***)'-%HHHHHHHHFF(('%9UUUUUUUUUFF''&w}guEEEEEEEEFF---,W]GUKKKKKKKKFF''&w????????FF)))(%88888888FF -#'-        F fd## 	

7(;(; 	MMM +:k400 +[__Y5O5O +
B7788   "*JsH    A	 	AAA% %A43A4*B0 0&CC7E 
EEr/   c                 H    dt          |                                           v S )zCheck if a Telegram error is a thread-not-found failure.

    Matches the gateway adapter's ``_is_thread_not_found_error`` for
    the standalone ``_send_telegram`` path (issue #27012).
    zthread not found)r@   rA   )r/   s    r#   _is_telegram_thread_not_foundr    s!     U!1!1!3!333r%   c           	      f  K   	 ddl m} ddlm} t	          t          j        d|                    }	|	r
|}
|j        }nK	 ddlm	} |
                    |          }|                    |          }
n# t          $ r |}
Y nw xY w|j        }	 ddlm}  |ddg	          }n# t          $ r d
}Y nw xY w|r	 ddlm} t$                              d|            ||  ||           ||                    }nJ# t          $ r1}t$                              d|            ||           }Y d
}~nd
}~ww xY w ||           }t+          |          }|pg }i }|e	 ddlm	} |                    t/          |                    }n4# t          $ r' t/          |          dk    rd
nt+          |          }Y nw xY w|||d<   t1          |          }|rd|d<   d
}g }|
                                rs	 t5          |f||
|d| d
{V }nY# t          $ rK}t7          |          r^|r\t$                              d|                    d                     |                    dd
           t5          |f||
|d| d
{V }ndt/          |                                          v sFdt/          |                                          v s#dt/          |                                          v rjt$                              d|t?          |                     |	s%	 ddlm }  ||
          }n# t          $ r |}Y nw xY w|}t5          |f||d
d| d
{V }n Y d
}~nd
}~ww xY w|D ]\  }}tB          j"        #                    |          s5d| }t$                              |           |$                    |           ZtB          j"        %                    |          d                                         }	 tM          |d          5 } t1          |          }!	 |tN          v r|s |j(        d/|| d|! d
{V }nx|tR          v r |j*        d/|| d |! d
{V }nX|tV          v r|r |j,        d/|| d!|! d
{V }n6|tZ          v r |j.        d/|| d"|! d
{V }n |j/        d/|| d#|! d
{V }n$# t          $ r}"t7          |"          r|!                    d          rt$                              d$|!d                    | 0                    d           |!                    dd
           |tN          v r|s |j(        d/|| d|! d
{V }nz|tR          v r |j*        d/|| d |! d
{V }nZ|tV          v r|r |j,        d/|| d!|! d
{V }n8|tZ          v r |j.        d/|| d"|! d
{V }n |j/        d/|| d#|! d
{V }n Y d
}"~"nd
}"~"ww xY wd
d
d
           n# 1 swxY w Y   # t          $ rO}#t?          d%| d&|#           }t$          1                    |           |$                    |           Y d
}#~#d
}#~#ww xY w|d'}$|r|$|d(S d)|$iS dd*|t/          |j2                  d+}%|r||%d,<   |%S # tf          $ r d)d-icY S t          $ r}#ti          d.|#           cY d
}#~#S d
}#~#ww xY w)0uD  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.
    r   )Bot)	ParseModez<[a-zA-Z/][^>]*>rE  )resolve_proxy_urlTELEGRAM_PROXYzapi.telegram.org)target_hostsN)HTTPXRequestz>send_message: standalone Telegram send routed through proxy %s)proxy)r   requestget_updates_requestzUsend_message: failed to attach Telegram proxy (%s), falling back to direct connection)r   1message_thread_idTdisable_web_page_preview)r   r*   
parse_modezIThread %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)_strip_mdv2z Media file not found, skipping: r   rb)r   photo)r   video)r   voice)r   audio)r   documentzFThread %s not found for media send, retrying without message_thread_idzFailed to send media : ANo deliverable text or media remained after processing MEDIA tags)r/   rK  r/   r   r   r   r   r^   rK  zGpython-telegram-bot not installed. Run: pip install python-telegram-botzTelegram send failed: rF   )5r   r  telegram.constantsr  r   researchHTMLrO  rF  rS  rT  rI   MARKDOWN_V2r   r  telegram.requestr  rJ   inforK   int_message_thread_id_for_sendr@   r   r   rQ   r  re   poprA   r,   r  r   r  existsru  r  openr  
send_photor  
send_videor  
send_voice_TELEGRAM_SEND_AUDIO_EXTS
send_audiosend_documentseekr/   r^   rP  r0   )&r   r   r-   r   r   rI  r   r  r  	_has_html	formattedsend_parse_moderF  _adapterr  	_tg_proxyr  rN   
_proxy_errint_chat_idthread_kwargseffective_thread_idtext_kwargslast_msgrK  md_errorr  plainr   r!  rK   r"  fmedia_kwargs	media_errrr   r/   r   s&                                         r#   r[  r[    s     U4      000000 #6@@AA	 	4I'nOO$FFFFFF*22?CC$33G<<		 $ $ $#			$ (3O	@@@@@@))*:J\I]^^^II 	 	 	III	 	#
'999999\^ghhhc(Ly999(49(E(E(E  
  ' ' 'v  yC  D  D  Dc&&&' #E"""C'll!'R 
FFFFFF&5&Q&Q	NN' '##      	NNc11DDs9~~ $## #.5H12 =))  	;6:K23?? *	)!B"'i." " 3>" "      
  # # # 1:: } NNc%))*=>>    OO$7>>>%F& +)#2& & 7B& &            HH
 H 3 3 5 555s8}}GZGZG\G\9\9\`fjmnvjwjwj}j}jj``NN`',X66  
 % (,NNNNNN$/K	$:$:EE( , , ,$+EEE, !(%F& +%#'& & ,7& &            HH G#J %0 D	) D	) J7>>*-- IZIIw'''((('"":..q17799C<)*d++ 7"q#'#6#6L5"+--n--;S^ .(31. .@L. . ( ( ( ( ( (HH !K//-;S^ .(31. .@L. . ( ( ( ( ( (HH !K//H/-;S^ .(31. .@L. . ( ( ( ( ( (HH !$===-;S^ .(31. .@L. . ( ( ( ( ( (HH .?S-> .(3a. .CO. . ( ( ( ( ( (H %  "  "  "8CC "HXHXYlHmHm " #NN h ,-@ A  
 FF1III(,,-@$GGG"k11.11? 2",7q2" 2"DP2" 2" ," ," ," ," ," ," "%!3!31? 2",7q2" 2"DP2" 2" ," ," ," ," ," ," "%!3!3!31? 2",7q2" 2"DP2" 2" ," ," ," ," ," ," "%(A!A!A1? 2",7q2" 2"DP2" 2" ," ," ," ," ," ," 2C1B 2",7!2" 2"GS2" 2" ," ," ," ," ," ," "A "/7" 7" 7" 7" 7" 7" 7" 7" 7" 7" 7" 7" 7" 7" 7"p  ) ) )./Xz/X/XUV/X/XYYW%%%(((((((()
 WE >!&H===U## "h122	
 
  	*!)F: d d dbcccc 4 4 42q22333333334s  :Y; 0A0 /Y; 0A?<Y; >A??
Y; 
B Y; B.+Y; -B..Y; 4AC8 7Y; 8
D3'D.)Y; .D33&Y; (F Y; .F41Y; 3F449Y; .H Y; MDML&%M&L52M4L55MY; MBY; 4W.W!BR1/W!1W<DWW!WW!W.!W%	%W.(W%	)W.,Y; .
Y8AY<Y; YY; Y; !Y; ;Z0	Z0Z+%Z0+Z0c           	      ^  K   	 ddl }n# t          $ r ddicY S w xY w	 ddlm}m}  |            } ||          \  }}	d}
d|  dd	} |j        dd
|                    d          i|4 d{V }||dd}|r||d<    |j        |
f||d|	4 d{V }|                                 d{V }|	                    d          r>dd||	                    d          dcddd          d{V  cddd          d{V  S t          d|	                    dd                     cddd          d{V  cddd          d{V  S # 1 d{V swxY w Y   	 ddd          d{V  dS # 1 d{V swxY w Y   dS # t          $ r}t          d|           cY d}~S d}~ww xY w)zSend via Slack Web API.r   Nr/   /aiohttp not installed. Run: pip install aiohttpr  proxy_kwargs_for_aiohttpz&https://slack.com/api/chat.postMessager   r   r   r5      r   T)r   r*   mrkdwnrJ  r   r   r   tsr  zSlack API error: unknownzSlack send failed: rF   )r   rP  r   r  r  r   r   r   rp   re   r0   rI   )r   r   r-   rJ  r   r  r  _proxy_sess_kw_req_kwr   r   r   payloadr   r   rr   s                    r#   rd  rd    s}     L L L LJKKKKL1VVVVVVVV""$$44V<<'6$5e$5$5GYZZ(7(]]1F1FR1F1P1P]T\]] 	R 	R 	R 	R 	R 	R 	Rah")7dKKG 1'0$#w|CRwRR'RR R R R R R R RVZ!YY[[((((((88D>> t'+Wdhdldlmqdrdrss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 P$((7I2N2NPPQQ	R R R R R R R R R R R R R		R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	RR R R R R R R R R R R R R R R		R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R  1 1 1/A//000000001s   	 AF 1%E3A	EE31F %E)E3;F 
E	E3E	E3 F 3
E==F  E=F 
F,F'!F,'F,c                 L  K   	 ddl }n# t          $ r ddicY S w xY w	 |                     dd          }|                                4 d{V }|                    d| d||d	|                    d
                    4 d{V 	 }|j        dk    rX|                                 d{V }dd||                    d          dcddd          d{V  cddd          d{V  S |                                 d{V }t          d|j         d|           cddd          d{V  cddd          d{V  S # 1 d{V swxY w Y   	 ddd          d{V  dS # 1 d{V swxY w Y   dS # t          $ r}	t          d|	           cY d}	~	S d}	~	ww xY w)z,Send via the local WhatsApp bridge HTTP API.r   Nr/   r  bridge_porti  zhttp://localhost:z/send)chatIdr-   r  r   )rp   r5      Tr   	messageIdr  zWhatsApp bridge error (): zWhatsApp send failed: )r   rP  re   r   r   r   statusrp   r*   r0   rI   )
r   r   r-   r   r  r   r   r   bodyrr   s
             r#   rf  rf    s?     L L L LJKKKKL4iit44((** 	P 	P 	P 	P 	P 	P 	Pg||6K666 'G<<--B-77 $   P P P P P P P P ;#%%!%,,,,,,D#'$.#*&*hh{&;&;	 P P P P P P P P P P P P P	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P "YY[[((((((NNNNNOOP P P P P P P P P P P P P	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	PP P P P P P P P P P P P P P P	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P   4 4 42q22333333334s   	 0E= :E*	?EE*E= -3E E*2E= 
E	E*E	E*E= *
E44E= 7E48E= =
F#FF#F#c                 Z
   !"#$%K   	 ddl %n# t          $ r ddicY S w xY wddlm}m m}m}m}m}m	!m
}	 	 |                     dd                              d          $|                     d	d
          ""sddiS |pg }
g #|
D ]U\  }}t          j                            |          r#                    |           :t"                              d|           V#r, #fdt'          dt)          #                     D             }ng g}!"$%fd}dt*          ddf"$%fd} |	            }t"                              d|                                t)          #          t)          |                     g }t1          |          D ]\  }}t)          |          }|dk    rO|                    |          }||k    r4 |d ||           d|dz    dt)          |           d           d{V  |dk    r|nd
}t'          d|dz             D ]}	 |                    |           d{V  t7          j                    } |||           d{V }t7          j                    |z
  }d|vr|                    ||           d{V   n|d         } ||          s,t=          d|dz    dt)          |           d|           c c S  ||          }|                    ||           ||k    rP|                    |dz              t"                               d|dz   t)          |          ||r|ddnd            nt"                              d|dz   t)          |          |||r|ddnd           l# tB          $ r}||k    rY|                    |dz              t"                               d|dz   t)          |          |t+          |                     Y d}~ nJt"                              d|dz   t)          |          ||t+          |                     Y d}~d}~ww xY wg }t)          #          t)          |
          k     r|                    d            |rF|                    d!t)          |           d"d#"                    d$ |D                        d%           |r@t)          |          t)          |          k    r t=          d&t)          |           d'          S d(d)d*}|r||d+<   |S # tB          $ r}t=          d,|           cY d}~S d}~ww xY w)-u  Send via signal-cli JSON-RPC API.

    Supports both text-only and text-with-attachments (images/audio/documents).
    Multi-attachment sends are chunked into batches of
    SIGNAL_MAX_ATTACHMENTS_PER_MSG and metered by the process-wide
    SignalAttachmentScheduler — same bucket the gateway adapter uses, so
    sends from this tool and inbound-driven replies share rate-limit state.
    r   Nr/   httpx not installed)$SIGNAL_BATCH_PACING_NOTICE_THRESHOLDSIGNAL_MAX_ATTACHMENTS_PER_MSGSIGNAL_RATE_LIMIT_MAX_ATTEMPTS_extract_retry_after_seconds_format_wait_is_signal_rate_limit_error_signal_send_timeoutget_schedulerhttp_urlzhttp://127.0.0.1:8080/accountrt   zSignal account not configuredz)Signal media file not found, skipping: %sc                 *    g | ]}||z            S rF   rF   ).0r~  r  attachment_pathss     r#   
<listcomp>z _send_signal.<locals>.<listcomp>  s9        !1'E#E!EF  r%   c                   K   |d}	                     d          r	dd          |d<   n	g|d<   | r| |d<   dd|d	t          t          j                    d
z             d} | rt          |           nd          }                    |          4 d {V }|                    
 d|           d {V }|                                 |                                cd d d           d {V  S # 1 d {V swxY w Y   d S )Nr  r-   r      groupId	recipientattachments2.0rT   send_  jsonrpcmethodparamsr   r   r   /api/v1/rpcrp   )r   r  timer   AsyncClientr   raise_for_statusrp   )batch_attachmentsbatch_messager  r  r5   clientr   r  r  r   r  httpxs          r#   _postz_send_signal.<locals>._post  s     !(]CCF!!(++ 0$+ABBKy!!'.i{#  :(9}% !  7c$)++"45577	 G +*EV+]3/@+A+A+A\]^^G(((99 # # # # # # #V#[[H)A)A)A[PPPPPPPP%%'''yy{{# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #s   AC77
DDr*   r   c                   K   | d}                     d          rdd         |d<   ng|d<   	                     d          4 d{V }|                     d	d
d|dt          t	          j                    dz             d           d{V  ddd          d{V  dS # 1 d{V swxY w Y   dS # t
          $ r&}t                              d|           Y d}~dS d}~ww xY w)z9Best-effort one-shot RPC for a user-facing pacing notice.r  r   r  Nr  r        >@r   r  r  rT   notice_r  r  r  z Signal: inline notice failed: %s)r   r  r   r  r  rI   rJ   rK   )r*   notice_params_client_er  r   r  r  s       r#   _send_inline_noticez)_send_signal.<locals>._send_inline_notice  s     (/DAAM!!(++ 7+2122;i((.5Yk*G ,,T,:: 	 	 	 	 	 	 	g!,,#000',&,&3"EC	d0B,C,C"E"E	  '         	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	  G G GA2FFFFFFFFFGs<   B? A
B,B? ,
B66B? 9B6:B? ?
C/	C**C/zIsend_message Signal: scheduler state=%s, %d attachment(s) in %d batch(es)u!   (More images coming — pausing ~z for Signal rate limit, batch r   z.)zSignal RPC error on batch r  z`Signal: rate-limit retries exhausted on batch %d/%d (%d attachments lost, server retry_after=%s)z.0fsr  ziSignal: rate-limited on batch %d/%d (attempt %d/%d, server retry_after=%s); scheduler will pace the retryz7Signal: send error on batch %d/%d after %d attempts: %szFSignal: transient error on batch %d/%d (attempt %d/%d): %s; will retryz1Some media files were skipped (not found on disk)zSignal rate-limited z batch(es) (#z, #c              3   4   K   | ]}t          |          V  d S N)r@   )r  bs     r#   	<genexpr>z_send_signal.<locals>.<genexpr>k  s(      ??1A??????r%   r   zSignal: every batch (z*) hit rate limit; no attachments deliveredTr   r   r   r   rK  zSignal send failed: )#r  rP  #gateway.platforms.signal_rate_limitr  r  r  r  r  r  r  r  re   rstripr   r  r  ru  rJ   rK   rG   r   r@   r  staterZ  estimate_waitacquirer  	monotonicreport_rpc_durationr0   feedbackr/   rI   join)&r   r   r-   r   r  r  r  r  r  r  valid_mediar   	_is_voiceatt_batchesr  r  	schedulerfailed_batchesidx	att_batchn	estimatedr  r2   _rpc_t0r   _rpc_durationerrserver_retry_afterrr   rK  r   r  r  r  r  r  r  s&    `                              @@@@@@r#   r`  r`    s     0 0 0 0.////0	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	Y299Z)@AAHHMM))Ir** 	><==!'R%0 	X 	X!J	w~~j)) X ''
3333JJWWWW
  	    q#&6"7"79WXX  KK
 $K	# 	# 	# 	# 	# 	# 	# 	# 	#*	GC 	GD 	G 	G 	G 	G 	G 	G 	G 	G 	G* "MOO	WOOs#344c+6F6F	
 	
 	
 %''44 :	 :	NCIA1uu%33A66	 DDD--WLL<S<S W W8;aW WBEkBRBRW W W        
 (+axxGGRM $BQ$FGG . .-#++A........."n..G!&y-!@!@@@@@@@D$(N$4$4w$>Md**';;M1MMMMMMMMMw-C66s;; h%&f37&f&fSQ\M]M]&f&fad&f&fggggggg)E)Ec)J)J&&&'91==="@@@&--cAg666K!GS%5%5q<N]188888T]	   NN8 a[!1!1!?8JY-44444PY    !   "@@@&--cAg666U!GS%5%5wA   NN`a[!1!17<Z\_`a\b\b          3{#3#333OOOPPP 	OOCs>':': C CZZ???????C C C  
  	c.11S5E5EEE,K(8(8 , , ,  
 "xGLL 	*!)F: 2 2 20Q00111111112s    !!AT >FT A6M?T :M?
T A5M?T 7M?=T ?
P/	AP*"T (<P*$T *P//CT 5T 
T*T%T*%T*c                 H  K   ddl }ddlm} |                     d          pt	          j        dd          }t	          j        dd          }|                     d          pt	          j        d	d          }	 t          t	          j        d
d                    }n# t          t          f$ r d}Y nw xY wt          |||g          sddiS 	  ||dd          }	||	d<   ||	d<   d|	d<   t          d          |	d<   |                    ||          }
|
                    t          j                               |
                    ||           |
                    |	           |
                                 dd|dS # t$          $ r}t'          d|           cY d}~S d}~ww xY w)z:Send via SMTP (one-shot, no persistent connection needed).r   N)MIMETextaddressEMAIL_ADDRESSrt   EMAIL_PASSWORD	smtp_hostEMAIL_SMTP_HOSTEMAIL_SMTP_PORT587iK  r/   zNEmail not configured (EMAIL_ADDRESS, EMAIL_PASSWORD, EMAIL_SMTP_HOST required)r  zutf-8FromTozHermes AgentSubjectT)	localtimeDate)contextr	   r  zEmail send failed: )smtplibemail.mime.textr   re   r   r   r  r?   r>   allr   SMTPstarttlssslcreate_default_contextloginrH   quitrI   r0   )r   r   r-   r.  r   r!  passwordr$  	smtp_portmsgserverrr   s               r#   rh  rh  |  s     NNN((((((ii	""Dbi&D&DGy)2..H		+&&J")4Er*J*JI	"3U;;<<			"   			 9-.. kijj1hw11FD	'I 4000Fi33 : < <===Wh'''C   WIII 1 1 1/A//000000001s1   7"B B0/B0
B0E; ;
F!FF!F!c                 6  K   	 ddl }n# t          $ r ddicY S w xY wddl}t          j        dd          }t          j        dd          }|r| r|sddiS t          j        d	d
|t
          j                  }t          j        dd
|t
          j                  }t          j        dd
|t
          j                  }t          j        dd
|t
          j                  }t          j        dd|          }t          j        dd
|          }t          j        dd|t
          j                  }t          j        dd
|          }t          j        dd|          }|	                                }	 ddl
m}m}  |            }	 ||	          \  }
}| d|  }|                    |                    d                                        d          }d| d}dd| i} |j        d,d|                    d          i|
4 d{V }|                                }|                    d|           |                    d |           |                    d!|            |j        |f||d"|4 d{V }|                                 d{V }|j        d#k    ra|                    d$t1          |                    }t3          d%|j         d&|           cddd          d{V  cddd          d{V  S |                    d'd          }d(d)||d*cddd          d{V  cddd          d{V  S # 1 d{V swxY w Y   	 ddd          d{V  dS # 1 d{V swxY w Y   dS # t4          $ r}t3          d+|           cY d}~S d}~ww xY w)-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.
    r   Nr/   r  TWILIO_ACCOUNT_SIDrt   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

r  ru   asciiz+https://api.twilio.com/2010-04-01/Accounts/z/Messages.jsonr   zBasic r5   r  r   r(  r)  Body)r   r   i  r-   zTwilio API error (r  sidTr   r  zSMS send failed: rF   )r   rP  base64r   r   r  r(   DOTALL	MULTILINEr   r   r  r  	b64encodeencodedecoder   r   FormData	add_fieldr   rp   r  re   r@   r0   rI   )
auth_tokenr   r-   r   rB  account_sidfrom_numberr  r  r  r  r  credsencodedr   r   r   	form_datar   r  	error_msgmsg_sidrr   s                          r#   rj  rj    s=     L L L LJKKKKL MMM)0"55K)1266K uj u ustt f%ugRYGGGGf\5'CCCGf\5'CCCGfZryAAAGf_b'22GfZ00Gf]Br|DDDGf.w??GfY00GmmooG/VVVVVVVV""$$44V<<'----""5<<#8#899@@IIWKWWW"$6W$6$67(7(]]1F1FR1F1P1P]T\]] 	g 	g 	g 	g 	g 	g 	gah((**I444g...000#w|CTiTTGTT g g g g g g gX\!YY[[((((((;#%% $CII > >I!"Rt{"R"Ry"R"RSS	g g g g g g g g g g g g g	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g ((5"--#'Uw^effg g g g g g g g g g g g g	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	gg g g g g g g g g g g g g g g	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g  / / /-!--......../s   	 ,BM2 A.M2A"L:M&M2 9L:M'M2 :
M	MM	MM2 
M))M2 ,M)-M2 2
N<NNNc                 (  K   	 ddl }n# t          $ r ddicY S w xY w	 |                    d          pt          j        dd                              d          }| pt          j        d	d          } |r| sdd
iS dt          t          j                    dz             dt          j        d          	                                 }ddl
m}  ||d          }| d| d| }	d|  dd}
d|d}	 ddl}|                    |ddg          }t          j        dd|          }d|d<   ||d<   n# t          $ r Y nw xY w|                    |                    d !          "          4 d{V }|                    |	|
|#          4 d{V }|j        d$vrX|                                 d{V }t)          d%|j         d&|           cddd          d{V  cddd          d{V  S |                                 d{V }ddd          d{V  n# 1 d{V swxY w Y   ddd          d{V  n# 1 d{V swxY w Y   d'd(||                    d)          d*S # t,          $ r}t)          d+|           cY d}~S d}~ww xY w),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.
    r   Nr/   r  
homeserverMATRIX_HOMESERVERrt   r  MATRIX_ACCESS_TOKENzGMatrix not configured (MATRIX_HOMESERVER, MATRIX_ACCESS_TOKEN required)hermes_r  r      )quote)safez/_matrix/client/v3/rooms/z/send/m.room.message/r   r   r   zm.text)msgtyper  fenced_codetables)
extensionsz<h[1-6]>(.*?)</h[1-6]>z<strong>\1</strong>zorg.matrix.custom.htmlformatformatted_bodyr  r   r   r      r     zMatrix API error (r  Tr   event_idr  Matrix send failed: )r   rP  re   r   r   r
  r  r  urandomhexurllib.parserX  r  r  r(   r   r   putr  r*   r0   rp   rI   )r   r   r   r-   r   rS  txn_idrX  encoded_roomr   r   r  _mdr  r   r   r  r   rr   s                      r#   rl  rl    s     L L L LJKKKKL2ii--S;NPR1S1S[[\_``
=#8"== 	h 	hfggJ3ty{{T122JJRZ]]5F5F5H5HJJ&&&&&&uW2...aalaaY_aa$5e$5$5GYZZ '88	""""<<]H4M<NND635KTRRD 8GH(,G$%% 	 	 	D	 ((1F1FR1F1P1P(QQ 	) 	) 	) 	) 	) 	) 	)U\{{3g{FF ) ) ) ) ) ) )$;j00!%,,,,,,D!"Mt{"M"Mt"M"MNN) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)
 "YY[[((((((	) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)  X'Y]YaYablYmYmnnn 2 2 20Q00111111112s   	 AI+ :A7I+ 2=D0 /I+ 0
D=:I+ <D==3I+ 0I =HI I+ 1HI 
H'	'I *H'	+I .I+  
I

I+ I
I+ +
J5JJJc                 @  K   	 ddl m} n# t          $ r ddicY S w xY w|pg }	  ||           }|                                 d{V }|s:t	          d          	 |                                 d{V  S # t          $ r Y S w xY w|rd|ind}d}	|                                rg|                    |||           d{V }	|	j	        sBt	          d	|	j
                   	 |                                 d{V  S # t          $ r Y S w xY w|D ]\  }
}t          j                            |
          s?t	          d
|
           c 	 |                                 d{V  S # t          $ r Y S w xY wt          j                            |
          d                                         }|t           v r|                    ||
|           d{V }	n|t$          v r|                    ||
|           d{V }	np|t(          v r!|r|                    ||
|           d{V }	nF|t,          v r|                    ||
|           d{V }	n|                    ||
|           d{V }	|	j	        sDt	          d|	j
                   c 	 |                                 d{V  S # t          $ r Y S w xY w|	/ddi	 |                                 d{V  S # t          $ r Y S w xY wdd||	j        d	 |                                 d{V  S # t          $ r Y S w xY w# t          $ rG}t	          d	|           cY d}~	 |                                 d{V  S # t          $ r Y S w xY wd}~ww xY w# 	 |                                 d{V  w # t          $ r Y w w xY wxY w)zISend via the Matrix adapter so native Matrix media uploads are preserved.r   )MatrixAdapterr/   zIMatrix dependencies not installed. Run: pip install 'mautrix[encryption]'NzMatrix connect failedr   r3  rc  Media file not found: r   zMatrix media send failed: r  Tr   r  )gateway.platforms.matrixrl  rP  connectr0   
disconnectrI   r   rT   r   r/   r   r  r  r  rA   r  send_image_filer  r  r  r  r  r  r^   )r   r   r-   r   r   rl  r   	connectedr3  r}  r   r!  r"  rr   s                 r#   r^  r^    s     f::::::: f f fdeeeef #K0-((!//++++++++	 	3122R	$$&&&&&&&&&& 	 	 	D	S 09BK++d==?? 	J 'Wg Q QQQQQQQK& JH[5FHHIIB	$$&&&&&&&&&& 	 	 	D	C %0 	P 	P J7>>*-- ECzCCDDDD:	$$&&&&&&&&&& 	 	 	D	; '"":..q17799Ck!!$+$;$;GZZb$;$c$ccccccc##$+$6$6w
U]$6$^$^^^^^^^###$+$6$6w
U]$6$^$^^^^^^^##$+$6$6w
U]$6$^$^^^^^^^$+$9$9':X`$9$a$aaaaaaa& PN;;LNNOOOO	$$&&&&&&&&&& 	 	 	D	#P `a	$$&&&&&&&&&& 	 	 	D	  %0	
 
	$$&&&&&&&&&& 	 	 	D	  2 2 20Q001111111	$$&&&&&&&&&& 	 	 	D	2	$$&&&&&&&&&& 	 	 	D	s    5L A55
BBAL C::
DD
:L E  
E-,E-0DL J""
J/.J/2L :K
K"!K"%L 1L
LL
M-&M(7M-8M0 =M
M%$M%(M--M0 0N2NN
NNNNc                   K   	 ddl }n# t          $ r ddicY S w xY w	 |                     d          pt          j        dd          }|sddiS |                    d	
          4 d{V }|                    |dd|id           d{V }|                                 |                                }|                    dd          dk    r8t          d|                    dd                     cddd          d{V  S 	 ddd          d{V  n# 1 d{V swxY w Y   dd|dS # t          $ r}t          d|           cY d}~S d}~ww xY w)aq  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.
    r   Nr/   r  webhook_urlDINGTALK_WEBHOOK_URLrt   zkDingTalk not configured. Set DINGTALK_WEBHOOK_URL env var or webhook_url in dingtalk platform extra config.r  r   r*   r2  )rZ  r*   r  errcodezDingTalk API error: errmsgr  Tdingtalkr  zDingTalk send failed: )r  rP  re   r   r   r  r   r  rp   r0   rI   )	r   r   r-   r  ru  r  r   r   rr   s	            r#   rn  rn  =  s     0 0 0 0.////04ii..W")<RTV2W2W 	L  K  L  L$$T$22 	V 	V 	V 	V 	V 	V 	Vf!')W1EFF %        D !!###99;;Dxx	1%%**TTXXh	5R5RTTUU	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V +	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V  ZGLLL 4 4 42q22333333334sZ   	 /D1 D1 *B
D4D1 D1 
D$$D1 'D$(D1 1
E;EEEc                   K   	 ddl m}m}  |            sddiS n# t          $ r ddicY S w xY w	 ddlm}  ||           } ||          }|                                 d{V }|st          d	|j        pd
           S 	 |	                    ||           d{V }	|	j
        s1t          d|	j                   |                                 d{V  S dd||	j        d|                                 d{V  S # |                                 d{V  w xY w# t          $ r}
t          d|
           cY d}
~
S d}
~
ww xY w)z;Send via WeCom using the adapter's WebSocket send pipeline.r   )WeComAdaptercheck_wecom_requirementsr/   z?WeCom requirements not met. Need aiohttp + WECOM_BOT_ID/SECRET.zWeCom adapter not available.r   r   NzWeCom: failed to connect - zunknown errorzWeCom send failed: Twecomr  )gateway.platforms.wecomr{  r|  rP  r   r   rp  r0   fatal_error_messagerT   r   r/   rq  r^   rI   )r   r   r-   r{  r|  r   r   r   rs  r   rr   s              r#   rp  rp  \  s     9RRRRRRRR'')) 	`^__	` 9 9 97888891111111 .u---,w''!//++++++++	 	jh8S8fWfhhiii	'"<<99999999F> DBFLBBCC $$&&&&&&&&&&  $W\b\mnn$$&&&&&&&&&&'$$&&&&&&&&&& 1 1 1/A//000000001sN    ,,AD 9C= <D C= "D =DD 
E&D=7E=Ec                    K   	 ddl m}m}  |            sddiS n# t          $ r ddicY S w xY w	  || j        | j        |||           d{V S # t          $ r}t          d|           cY d}~S d}~ww xY w)	z6Send via Weixin iLink using the native adapter helper.r   )check_weixin_requirementssend_weixin_directr/   z9Weixin requirements not met. Need aiohttp + cryptography.zWeixin adapter not available.)r   r   r   r-   r   NzWeixin send failed: )gateway.platforms.weixinr  r  rP  r   r   rI   r0   )r   r   r-   r   r  r  rr   s          r#   rM  rM  w  s     :ZZZZZZZZ((** 	ZXYY	Z : : :89999:	2''--#
 
 
 
 
 
 
 
 
 	
  2 2 20Q00111111112s)    ,,A 
A6A1+A61A6c                 v  K   	 ddl m}m}  |            sddiS n# t          $ r ddicY S w xY w	 ddlm}  ||           } ||          }|                                 d{V }|st          d	          S 	 |                    ||           d{V }	|	j	        s1t          d
|	j
                   |                                 d{V  S dd||	j        d|                                 d{V  S # |                                 d{V  w xY w# t          $ r}
t          d
|
           cY d}
~
S d}
~
ww xY w)zBSend via BlueBubbles iMessage server using the adapter's REST API.r   )BlueBubblesAdaptercheck_bluebubbles_requirementsr/   z8BlueBubbles requirements not met (need aiohttp + httpx).z"BlueBubbles adapter not available.r   r}  Nz(BlueBubbles: failed to connect to serverzBlueBubbles send failed: Tbluebubblesr  )gateway.platforms.bluebubblesr  r  rP  r   r   rp  r0   rT   r   r/   rq  r^   rI   )r   r   r-   r  r  r   r   r   rs  r   rr   s              r#   rr  rr    s     ?dddddddd--// 	YWXX	Y ? ? ?=>>>>?7111111 .u---$$W--!//++++++++	 	FDEEE	'"<<99999999F> JH&,HHII $$&&&&&&&&&&  $7bhbstt$$&&&&&&&&&&'$$&&&&&&&&&& 7 7 75!55666666667sN    ,,AD 99C3 2D C3 D 3DD 
D8D3-D83D8c                   K   	 ddl m}m} |sddiS ddl m}m} n# t
          $ r ddicY S w xY w|pg }	  ||           }	t          |	dd          }
|
dk    r|n|}|	                    |          |	_        |rd	|ind
}d
}|	                                r<|	
                    |||           d
{V }|j        st          d|j                   S |D ]P\  }}t          j                            |          st          d|           c S t          j                            |          d                                         }|t&          v r|	                    |||           d
{V }n|t*          v r|	                    |||           d
{V }np|t.          v r!|r|	                    |||           d
{V }nF|t2          v r|	                    |||           d
{V }n|	                    |||           d
{V }|j        st          d|j                   c S R|ddiS dd||j        dS # t8          $ r}t          d|           cY d
}~S d
}~ww xY w)z7Send via Feishu/Lark using the adapter's send pipeline.r   )rG  FEISHU_AVAILABLEr/   zJFeishu dependencies not installed. Run: pip install 'hermes-agent[feishu]')FEISHU_DOMAINLARK_DOMAIN_domain_namer   larkr   Nrm  zFeishu send failed: rn  r   zFeishu media send failed: r  Tr  )rQ  rG  r  r  r  rP  r;   _build_lark_clientr   r   rT   r   r0   r/   r   r  r  r  rA   r  rr  r  r  r  r  r  r  r^   rI   )r   r   r-   r   r   rG  r  r  r  r   domain_namedomainr3  r}  r   r!  r"  rr   s                     r#   rc  rc    s     gLLLLLLLL 	kijjGGGGGGGGG g g geffffg #K*2-((g~x@@"-"7"7[!44V<</8BK++d==?? 	J 'Wg Q QQQQQQQK& JH[5FHHIII$/ 	P 	P J7>>*-- ECzCCDDDDD'"":..q17799Ck!!$+$;$;GZZb$;$c$ccccccc##$+$6$6w
U]$6$^$^^^^^^^###$+$6$6w
U]$6$^$^^^^^^^##$+$6$6w
U]$6$^$^^^^^^^$+$9$9':X`$9$a$aaaaaaa& PN;;LNNOOOOOP `aa  %0	
 
 	
  2 2 20Q00111111112sG     ,,BH4 :H4 	DH4  H4 (H4 4
I>IIIc                      t           j                            d          rdS ddlm}   | dd          }|r|dk    rdS 	 ddlm}  |            S # t          $ r Y d	S w xY w)
u  Gate send_message on gateway running (always available on messaging platforms).

    Also passes for kanban workers — the dispatcher sets ``HERMES_KANBAN_TASK``
    on every spawned worker, but those workers run with the assignee profile's
    ``HERMES_HOME`` which has no ``gateway.pid``, so the gateway-running check
    would fail even though the parent gateway is alive. Honoring the env var
    lets workers call ``send_message`` to deliver rich content directly to the
    originating chat (paired with ``kanban_complete`` for the short notifier
    summary), which is the canonical pattern for any worker that needs to
    reply with more than the ~200-char first-line truncation the kanban
    notifier applies.
    HERMES_KANBAN_TASKTr   r   r   rt   local)is_gateway_runningF)r   environre   r   r   gateway.statusr  rI   )r   r   r  s      r#   _check_send_messager    s     
z~~*++ t7777778"==H H''t555555!!###   uus   A 
AAc           	        K   	 ddl }n# t          $ r t          d          cY S w xY w| j        pi }|                    d          pt          j        dd          }| j        p)|                    d          pt          j        dd          }|r|st          d	          S 	 |                    d
          4 d{V }|	                    dt          |          t          |          d           d{V }|j        dk    r)t          d|j                   cddd          d{V  S |                                }	|	                    d          }
|
s!t          d          cddd          d{V  S d|
 dd}|dd         dd}d| d}|	                    |||           d{V }|j        dv r@|                                }dd||                    d          dcddd          d{V  S d | d}|	                    |||           d{V }|j        dv r@|                                }dd||                    d          dcddd          d{V  S d!| d}|	                    |||           d{V }|j        dv r@|                                }dd||                    d          dcddd          d{V  S t          d"|j         d#|j         d$|j                   cddd          d{V  S # 1 d{V swxY w Y   dS # t          $ r}t          d%|           cY d}~S d}~ww xY w)&a  Send via QQBot using the REST API directly (no WebSocket needed).

    Uses the QQ Bot Open Platform REST endpoints to get an access token
    and post a message. Supports guild channels, C2C (private) chats,
    and group chats by trying the appropriate endpoints.
    r   Nz8QQBot direct send requires httpx. Run: pip install httpxapp_id	QQ_APP_IDrt   client_secretQQ_CLIENT_SECRETz3QQBot: QQ_APP_ID / QQ_CLIENT_SECRET not configured.   r   z)https://bots.qq.com/app/getAppAccessToken)appIdclientSecretr  r  zQQBot token request failed: access_tokenz"QQBot: no access_token in responsezQQBot r   r   i  )r2  msg_typez#https://api.sgroup.qq.com/channels/z	/messages)rp   r   r`  Tqqbotr   r  z#https://api.sgroup.qq.com/v2/users/z$https://api.sgroup.qq.com/v2/groups/zQQBot send failed: channel=z c2c=z group=zQQBot send failed: )r  rP  r0   r   re   r   r   r   r  r   r@   status_coderp   rI   )r   r   r-   r  r   appidsecretr  
token_resp
token_datar  r   r  r   r   r   url_c2cresp_c2c	url_group
resp_grouprr   s                        r#   rt  rt    sK     R R R RPQQQQQR MREIIh=29["#=#=Em 3uyy99 3-r22  M MKLLL21$$R$00 /	F /	F /	F /	F /	F /	F /	FF%{{;"5zz3v;;GG  +          J %,,UZ=SUUVV/	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F $**J%>>.99L ECDD/	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F" "9,!8!8 2 G #*%4%.a@@G KJJJCSwHHHHHHHHD:--yy{{#'W&*hhtnn6 67/	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F> OGNNNG#[[w[PPPPPPPPH#z11}}#'W&*hhtnn6 6G/	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	FN RwQQQI%{{97G{TTTTTTTTJ%33!((#'W&*hhtnn6 6W/	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F^   E8H  E  ExOc  E  Elv  mC  E  E  F  F_/	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F /	F`  1 1 1/A//000000001s   	 %% L <ALL +9L$L 7A/L&L 9ALL &AL L &L9L 
LL LL 
M)M :M Mc                   K   	 ddl m}m} n# t          $ r t	          d          cY S w xY w |            }|t	          d          S 	  ||| ||           d{V S # t
          $ r}t	          d|           cY d}~S d}~ww xY w)u  Send via Yuanbao using the running gateway adapter's WebSocket connection.

    Yuanbao uses a persistent WebSocket — unlike HTTP-based platforms, we
    cannot create a throwaway client.  We obtain the running singleton from
    the adapter module itself (``get_active_adapter``).

    chat_id format:
      - Group: "group:<group_code>"
      - DM:    "direct:<account_id>" or just "<account_id>"
    r   )get_active_adaptersend_yuanbao_directz%Yuanbao adapter module not available.NzVYuanbao adapter is not running. Start the gateway with yuanbao platform enabled first.rB  zYuanbao send failed: )gateway.platforms.yuanbaor  r  rP  r0   rI   )r   r-   r   r  r  r   rr   s          r#   rb  rb  B  s      ?UUUUUUUUU ? ? ?=>>>>>? ! ""GE
 
 	

3(('7P[\\\\\\\\\\ 3 3 31a11222222223s*    ))A 
B'A>8B>B)registryr   	messagingu   📨)ra   toolsetschemahandlercheck_fnr]   )Fr  )NNFFr  )NN)N__doc__rL   rp   loggingr   r  r3  r  email.utilsr   agent.redactr   	getLoggerr=  rJ   compiler  r	  r  r  r  r  r
  	frozensetr  r  r  r   r  r  r  r  r  
IGNORECASEr'   r)   r@   r,   r   r0   rI   r  r=   rB   rQ   SEND_MESSAGE_SCHEMArk   rf   rg   rh   r   r   r'  r   r@  r   r   r  r[  rd  rf  r`  rh  rj  rl  r^  rn  rp  rM  rr  rc  r  rt  rb  tools.registryr  r   registerrF   r%   r#   <module>r     s       				 				 



  " " " " " " . . . . . .		8	$	$&BJ'DEE BJfgg  2:=>> $"*%MNN BJuvv RZ CDD -  9DDDEE "*455 2:WXX 
  '(<= 888666@@@w $V, !rzWM   'BJQM  #    4C 4D 4 4 4 4
y 3 54<    2 EF ' ' 'c ' ' ' '& 	5  !<<<  }  !  \ 
 !  ] 
 !  J 
 !   %
 
. 3 % % P   L L LY1 Y1 Y1 Y1xn7 n7 n7bBS Bc B B B BJ: : :&  3  QTW[Q[    J \ \ \ \ \~u u u up4 4t 4 4 4 4]4 ]4 ]4 ]4@1 1 1 124 4 48r2 r2 r2 r2j1 1 1B5/ 5/ 5/p)2 )2 )2X9 9 9 9x4 4 4>1 1 162 2 2 2*7 7 7662 62 62 62r  4E1 E1 E1P3 3 3 3< 0 / / / / / / /  	 
     r%   