+
    kHàjÃÁ  ã            	      ó  € R t ^ RIHt ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIHtHtHt ^ RIHtHtHtHtHt  ^ RIt ^ RIt]RJt]RJt^ RIHtHt ^ RIHtHtHt ^ RI H!t! ^ R	I"H#t#H$t$H%t% ^ R
I&H't'H(t( ^ RI)H*t* ^ RI+H,t-H.t. ^ RI/H0t0H1t1 ^ RI2H3t3 ^ RI4H5t5H6t6 ^ RI7H8t8H9t9H:t:H;t;H<t<H=t=H>t>H?t?H@t@ ]P‚                  ! ]B4      tCRtDRtERtFRtGRtHRtI]F]G0tJ]J]H0,          tKRtLRtMRtNRtO. RBOtPRtQR R ltRR R ltSR  R! ltTR" R# ltUR$ R% ltVR& R' ltW ! R( R)]8]5]3]!]$4      tXR*tYR+tZR,t[^R-ut\t]R.]]/R/ R0 llt^R1 R2 lt_R3RR4RR5R6/R7 lt`RCtaRDtbR8 R9 ltcR: R; ltdR< R= lteR> tfR?tgR@ RA lthR#   ] d    Rt EL3i ; i  ] d    Rt EL>i ; i)Ea»  WeCom (Enterprise WeChat) AI Bot adapter over the ``openws`` WebSocket gateway.
Streaming lives in ``streaming.py``, media in ``media.py``, per-chat send queue in ``send_queue.py``.
Config (``platforms.wecom.extra``): ``bot_id``/``secret`` (or WECOM_BOT_ID / WECOM_SECRET), ``websocket_url``,
``dm_policy``/``group_policy`` (open|allowlist|disabled|pairing), ``allow_from``, ``group_allow_from``,
``groups: {<group_id>: {allow_from: [...]}}``.)Úannotations)Úinstall_hintN)ÚdatetimeÚtimezoneÚUTC)ÚAnyÚDictÚListÚOptionalÚTuple)ÚPlatformÚPlatformConfig)ÚMessageDeduplicatorÚbounded_putÚsend_chunks)ÚOwnAccessPolicyMixin)Úgateway_trust_envÚBasePlatformAdapterÚ
SendResult)ÚMessageEventÚMessageType)Ú	env_float)Úget_scoped_secretÚ
send_error)ÚStandaloneSendPolicyÚparse_nonempty)ÚChatSendQueueMixin)ÚWeComMediaMixinÚAPP_CMD_SEND)	ÚWeComStreamMixinÚ
ReplyQueueÚ
StreamTurnÚAPP_CMD_RESPONSEÚSTREAM_NOT_SUBSCRIBED_ERRCODEÚMAX_STREAM_CONTENT_LENGTHÚSTREAM_SAFE_DURATION_SECONDSÚ!STREAM_KEEPALIVE_INTERVAL_SECONDSÚ STREAM_KEEPALIVE_ENABLED_DEFAULTzwss://openws.work.weixin.qq.comÚaibot_subscribeÚaibot_msg_callbackÚaibot_callbackÚaibot_event_callbackÚpingé   g      4@g      .@g      >@iè  c               ó   € V ^8„  d   QhRR/# ©é   ÚreturnÚbool© )Úformats   "ÚD/home/ubuntu/.hermes/hermes-agent/plugins/platforms/wecom/adapter.pyÚ__annotate__r6   F   s   € ÷ 1ñ 1 $ñ 1ó    c                 ó*   € \         ;'       d    \        # ©N)ÚAIOHTTP_AVAILABLEÚHTTPX_AVAILABLEr3   r7   r5   Úcheck_wecom_requirementsr<   F   s   € Ü×0Ð0¤Ð0r7   c               ó    € V ^8„  d   QhRRRR/# )r0   Úvaluer   r1   ú	list[str]r3   )r4   s   "r5   r6   r6   J   s   € ÷ Lñ L˜ð L 	ñ Lr7   c                óô   € \        V \        4      '       d   V P                  R4      p M*\        V \        \        \
        34      '       g
   V f   . MV .p R V  4        Uu. uF  q'       g   K  VNK  	  up# u upi )z_Coerce config values (None | "a, b" | iterable | scalar) into a trimmed, non-empty string list.Ú,c              3  óT   "  € T F  p\        V4      P                  4       x € K   	  R # 5ir9   )ÚstrÚstrip)Ú.0Úitems   & r5   Ú	<genexpr>Ú_coerce_list.<locals>.<genexpr>P   s   é € ÐB¹E°Dœc $›iŸo™o×/Ð/»Eùs   ‚&()Ú
isinstancerC   ÚsplitÚlistÚtupleÚset)r>   rF   s   & r5   Ú_coerce_listrN   J   sa   € ä�%œ×ÒØ—‘˜CÓ ‰Ü˜¤¤e¬SÐ1×2Ò2Ø’m‘¨%¨ˆÙB¹EÔBÓKÑB�TÃd�DˆDÑBÑKÐKùÒKs   Á	A5Á,A5c               ó    € V ^8„  d   QhRRRR/# )r0   ÚrawrC   r1   r3   )r4   s   "r5   r6   r6   S   s   € ÷ Mñ M˜#ð M #ñ Mr7   c                óì   € \         P                  ! RR\        V 4      P                  4       \         P                  R7      p\         P                  ! RRV\         P                  R7      P                  4       # )z7Normalize allowlist entries such as ``wecom:user:foo``.z^wecom:Ú )Úflagsz^(user|group):)ÚreÚsubrC   rD   Ú
IGNORECASE)rP   r>   s   & r5   Ú_normalize_entryrW   S   sH   € ä�FŠF�:˜r¤3 s£8§>¡>Ó#3¼2¿=¹=ÔI€EÜ�6Š6Ð# R¨´b·m±mÔD×JÑJÓLÐLr7   c               ó$   € V ^8„  d   QhRRRRRR/# ©r0   Úentriesr?   ÚtargetrC   r1   r2   r3   )r4   s   "r5   r6   r6   Y   s&   € ÷ Yñ Y˜Ið Y¨sð Y°tñ Yr7   c                óÆ   a€ \        V4      P                  4       P                  4       o\        ;QJ d    V3R lV  4       F  '       g   K   R# 	  R# ! V3R lV  4       4      # )z4Case-insensitive allowlist match with ``*`` support.c              3  ó`   <"  € T F#  p\        V4      P                  4       R S39   x € K%  	  R# 5i)Ú*N)rW   Úlower)rE   ÚeÚnormalized_targets   & €r5   rG   Ú!_entry_matches.<locals>.<genexpr>\   s-   øé € ÐXÑPWÈ1Ô Ó"×(Ñ(Ó*¨sÐ4EÐ.FÖFÓPWùs   ƒ+.TF)rC   rD   r_   Úany)rZ   r[   ra   s   &&@r5   Ú_entry_matchesrd   Y   sJ   ø€ ä˜F›×)Ñ)Ó+×1Ñ1Ó3Ðß‹3ÔXÑPWÓX�3Œ3ÐXŠ3ÐXˆ3ÔXÑPWÓXÓXÐXr7   c               ó$   € V ^8„  d   QhRRRRRR/# ©r0   Ú	containerúdict[str, Any]ÚkeyrC   r1   r3   )r4   s   "r5   r6   r6   _   s&   € ÷ Nñ N˜nð N°3ð N¸>ñ Nr7   c                ór   € \        V P                  V4      \        4      '       d   V P                  V4      # / # r9   )rI   ÚgetÚdict©rg   ri   s   &&r5   Ú_dict_or_emptyrn   _   s+   € Ü!+¨I¯M©M¸#Ó,>Ä×!EÒ!Eˆ9�=‰=˜ÓÐMÈ2ÐMr7   c               ó$   € V ^8„  d   QhRRRRRR/# rf   r3   )r4   s   "r5   r6   r6   c   s&   € ÷ Lñ L˜>ð L°ð L¸ñ Lr7   c                óx   € \        \        W4      P                  R 4      ;'       g    R4      P                  4       # )ÚcontentrR   )rC   rn   rk   rD   rm   s   &&r5   Ú_content_ofrr   c   s.   € ÜŒ~˜iÓ-×1Ñ1°)Ó<×BÐBÀÓC×IÑIÓKÐKr7   c                  óö  a € ] tR t^gtRtRt]tRtRt]	t	Rt
RtRtR V 3R lltR R	 ltR
R/R R lltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R  ltR! R" ltR# R$ ltR% R& ltR' R( ltR) R* lt]3R+ R, llt ]!]3R- R. llt"]#R/ R0 l4       t$]#R1 R2 l4       t%]#R3 R4 l4       t&]#R5 R6 l4       t'R7 R8 lt(R9 R: lt)R; V 3R< llt*R= V 3R> llt+]#R? R@ l4       t,]#RA RB l4       t-RC RD lt.RE V 3RF llt/RG RH lt0RI RJ lt1RK RL lt2RM RN lt3RO RP lt4]#RQ RR l4       t5]6RS RT l4       t7RU RV lt8RW RX lt9RY RZ lt:ReR[ R\ llt;RfR]R/R^ R_ lllt<R` Ra lt=Rb Rc lt>Rdt?V ;t@# )gÚWeComAdapterzAWeCom AI Bot adapter backed by a persistent WebSocket connection.ÚWECOMFTi<  c               ó   € V ^8„  d   QhRR/# )r0   Úconfigr   r3   )r4   s   "r5   r6   ÚWeComAdapter.__annotate__s   s   € ÷ )Hñ )H˜~ñ )Hr7   c                	ó˜  <a€ \         SV `  V\        P                  4       VP                  ;'       g    / oR  V3R llpRRRR/R V3R lllpV! RRR	7      V n        V! R
RR	7      V n        V! RRR\        R7      ;'       g    \        V n        V! RRRR7      P                  4       V n
        \        SP                  R4      ;'       g&    SP                  R4      ;'       g    \        RR4      4      V n        V! RRRR7      P                  4       V n        \        SP                  R4      ;'       g    SP                  R4      4      V n        \#        SP                  R4      \$        4      '       d   SP                  R4      M/ V n        R;V n        ;V n        ;V n        ;V n        V n        / V n        / V n        \7        \8        R7      / uV n        V n        \?        RR4      V n         \?        RR 4      V n!        V! R!R"4      V n"        V! R#\F        4      V n$        \K        SP                  R$\L        4      4      V n'        V! R%\P        4      V n)        \T        PV                  ! 4       PX                  V n-        / V n.        / V n/        \a        4       \a        4       uV n1        V n2        / / / / / 3w  V n3        V n4        V n5        V n6        V n7        R# )&c               ó$   € V ^8„  d   QhRRRRRR/# )r0   ri   rC   ÚdefaultÚfloatr1   r3   )r4   s   "r5   r6   Ú+WeComAdapter.__init__.<locals>.__annotate__w   s!   € ÷ 	ñ 	˜cð 	¨Eð 	°eñ 	r7   c                ól   <€  \        SP                  W4      4      #   \        \        3 d    Tu # i ; ir9   )r|   rk   Ú	TypeErrorÚ
ValueError)ri   r{   Úextras   &&€r5   Ú_extra_floatÚ+WeComAdapter.__init__.<locals>._extra_floatw   s5   ø€ ðÜ˜UŸY™Y sÓ4Ó5Ð5øÜœzÐ*ô Ø’ðús   ƒ �3²3ÚenvrR   r{   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r0   ÚkeysrC   r„   r{   r1   r3   )r4   s   "r5   r6   r}   }   s.   € ÷ 	Jñ 	J˜Cð 	J cð 	J¸ð 	JÀcñ 	Jr7   c                ó¼   <€ \        \        V3R  lV 4       R4      ;'       g(    V '       d   \        W4      4      P                  4       # R4      P                  4       # )c              3  óh   <"  € T F'  pSP                  V4      '       g   K  SV,          x € K)  	  R # 5ir9   ©rk   )rE   Úkr�   s   & €r5   rG   Ú:WeComAdapter.__init__.<locals>._setting.<locals>.<genexpr>~   s#   øé € ÐD©t¨!°u·y±yÀ·|œX˜U 1ŸXšX«tùs   ƒ2¡2NrR   )rC   ÚnextÚ_get_scoped_secretrD   )r„   r{   r†   r�   s   $$*€r5   Ú_settingÚ'WeComAdapter.__init__.<locals>._setting}   sl   ø€ Ü”tÔD©tÓDÀdÓK÷  Að  A×twÔPbÐcfÓPpó  B÷  Hñ  Hó  Jð  JÐ}ó  B÷  Hñ  Hó  Jð  Jr7   Úbot_idÚWECOM_BOT_ID)r„   ÚsecretÚWECOM_SECRETÚwebsocket_urlÚwebsocketUrlÚWECOM_WEBSOCKET_URL)r„   r{   Ú	dm_policyÚWECOM_DM_POLICYÚpairingÚ
allow_fromÚ	allowFromÚWECOM_ALLOWED_USERSÚgroup_policyÚWECOM_GROUP_POLICYÚgroup_allow_fromÚgroupAllowFromÚgroupsN)Úmax_sizeÚ%HERMES_WECOM_TEXT_BATCH_DELAY_SECONDSg333333ã?Ú+HERMES_WECOM_TEXT_BATCH_SPLIT_DELAY_SECONDSg       @Ú#attachment_text_merge_delay_secondsgš™™™™™é?Ústream_safe_duration_secondsÚstream_keepalive_enabledÚ!stream_keepalive_interval_seconds)8ÚsuperÚ__init__r   ru   r�   Ú_bot_idÚ_secretÚDEFAULT_WS_URLÚ_ws_urlr_   Ú
_dm_policyrN   rk   r�   Ú_allow_fromÚ_group_policyÚ_group_allow_fromrI   rl   Ú_groupsÚ_sessionÚ_wsÚ_http_clientÚ_listen_taskÚ_heartbeat_taskÚ_pending_responsesÚ_reply_queuesr   ÚDEDUP_MAX_SIZEÚ_dedupÚ_reply_req_idsr   Ú_text_batch_delay_secondsÚ_text_batch_split_delay_secondsÚ$_attachment_text_merge_delay_secondsr%   Ú_stream_safe_duration_secondsr2   r'   Ú_stream_keepalive_enabledr&   Ú"_stream_keepalive_interval_secondsÚuuidÚuuid4ÚhexÚ
_device_idÚ_last_chat_req_idsÚ_stream_turnsrM   Ú_stream_expired_chatsÚ_group_chat_idsÚ_chat_queuesÚ_chat_workersÚ_control_queuesÚ_control_workersÚ_chat_token_usage)Úselfrw   r‚   rŽ   r�   Ú	__class__s   &&  @€r5   rª   ÚWeComAdapter.__init__s   s¦  ù€ Ü‰Ñ˜¤§¡Ô0Ø—‘×"Ð" ˆ÷	ð 	ð	J¨Bð 	J¸r÷ 	Jò 	Jñ   ¨nÔ=ˆŒÙ ¨nÔ=ˆŒÙ °ÐEZÔdrÔs÷  Fð  Fô  xFˆŒÙ" ;Ð4EÈyÔY×_Ñ_ÓaˆŒä'¨¯	©	°,Ó(?÷  )Kð  )KÀ5Ç9Á9È[ÓCY÷  )Kð  )KÔ]oð  qFð  HJó  ^Kó  LˆÔÙ% nÐ:NÐXaÔb×hÑhÓjˆÔÜ!-¨e¯i©iÐ8JÓ.K×.jÐ.jÈuÏyÉyÐYiÓOjÓ!kˆÔÜ.8¸¿¹À8Ó9LÌd×.SÒ.S�u—y‘y Ô*ÐY[ˆŒØbfÐfˆŒÐf˜œÐf 4Ô#4Ðf°tÔ7HÈ4ÔK_Ø=?ˆÔØ46ˆÔÜ+>ÌÔ+WÐY[Ð(ˆŒ�TÔ(ô *3Ð3ZÐ\_Ó)`ˆÔ&Ü/8Ð9fÐhkÓ/lˆÔ,Ù4@ÐAfÐhkÓ4lˆÔ1á-9Ð:XÔZvÓ-wˆÔ*Ü)-¨e¯i©iÐ8RÔTtÓ.uÓ)vˆÔ&Ù2>Ð?bô  eFó  3GˆÔ/ÜŸ*š*›,×*Ñ*ˆŒØ24ˆÔà46ˆÔÜ;>»5Ä#Ã%Ð8ˆÔ" DÔ$8àuwÐy{Ð}ð  BDð  FHð  vHÑrˆÔ˜4Ô-¨tÔ/CÀTÔEZÐ\`Ö\rr7   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r0   ÚcoderC   ÚmessageÚlog_msgÚargsr   r1   r2   r3   )r4   s   "r5   r6   rx   ž   s0   € ÷ ñ  Sð °3ð Àð ÈSð ÐUYñ r7   c                	ór   € V P                  WR R7       \        P                  ! W0P                  V.VO5!   R# )T©Ú	retryableF)Ú_set_fatal_errorÚloggerÚwarningÚname)rÑ   rÕ   rÖ   r×   rØ   s   &&&&*r5   Ú_startup_failureÚWeComAdapter._startup_failurež   s/   € Ø×Ñ˜d°tÐÔ<Ü�Š�w§	¡	¨7Ð:°TÔ:Ùr7   Úis_reconnectc               ó    € V ^8„  d   QhRRRR/# )r0   râ   r2   r1   r3   )r4   s   "r5   r6   rx   £   s   € ÷ ñ ¨Tð ¸dñ r7   c             ƒ  	ób  "  € \         R 3\        R33 F'  w  r#V'       d   K  V P                  RRV R2RV4      u # 	  V P                  '       d   V P                  '       g   V P                  RRR4      #  ^ R	IHp V! 4       V n        V P                  4       G R
j  x€L
  V P                  4        \        P                  ! V P                  4       4      \        P                  ! V P                  4       4      uV n        V n        \         P#                  RV P$                  V P&                  4       V P)                  R
4       R#  L¥  \*         d_   pT P-                  RRT 2RR7       \         P/                  RT P$                  TRR7       T P1                  4       G R
j  x€L 
   R
p?R# R
p?ii ; i5i)ÚaiohttpÚhttpxÚwecom_missing_dependencyzWeCom startup failed: z not installedz[%s] %s. Run: pip install %sÚwecom_missing_credentialsz@WeCom startup failed: WECOM_BOT_ID and WECOM_SECRET are requiredz[%s] %s)Úplatform_http_clientNz[%s] Connected to %sTÚwecom_connect_errorrÚ   z[%s] Failed to connect: %s)Úexc_infoF)r:   r;   rà   r«   r¬   Úgateway.platforms.helpersré   r¶   Ú_open_connectionÚ_mark_connectedÚasyncioÚcreate_taskÚ_listen_loopÚ_heartbeat_loopr·   r¸   rÝ   Úinforß   r®   Ú_wire_plugin_handlersÚ	ExceptionrÜ   ÚerrorÚ	_teardown)rÑ   râ   Ú	availableÚdepré   Úexcs   &$    r5   ÚconnectÚWeComAdapter.connect£   s£  é € Ü 1°9Ð=ÄÐQXÐ?YÓZ‰NˆIß‘9Ø×,Ñ,Ð-GÐKaÐbeÐafÐftÐIuð  xVð  X[ó  \ò  \ñ [ð �|�|ˆ| 4§<§< <Ø×(Ñ(Ð)Dð  GIð  KTó  Uð  Uð	õ GÙ 4Ó 6ˆDÔØ×'Ñ'Ó)×)Ð)Ø× Ñ Ô"Ü6=×6IÒ6IÈ$×J[ÑJ[ÓJ]Ó6^Ô`g×`sÒ`sÐtx÷  uIñ  uIó  uKó  aLÐ3ˆDÔ˜tÔ3Ü�K‰KÐ.°·	±	¸4¿<¹<ÔHØ×&Ñ& tÔ,Ùñ *øô ô 	Ø×!Ñ!Ð"7Ð;QÐRUÐQVÐ9WÐcgÐ!ÔhÜ�L‰LÐ5°t·y±yÀ#ÐPTˆLÔUØ—.‘.Ó"×"Ñ"Ýûð		üs`   ‚F/¢-F/ÁF/Á"F/Á6%E ÂEÂB#E Ä?F/ÅE ÅF,ÅAF'ÆFÆF'Æ!F/Æ'F,Æ,F/c               ó   € V ^8„  d   QhRR/# ©r0   r1   ÚNoner3   )r4   s   "r5   r6   rx   º   s   € ÷ 4ñ 4 $ñ 4r7   c              ƒ  	ó&  "  € R V n         V P                  4        \        V P                  P	                  4       4      \        V P
                  P	                  4       4      ,            F  pVP                  4        K  	  V P                  V P
                  V P                  V P                  3 F  pVP                  4        K  	  R F=  p\        W4      pV'       d   VP                  4         VG Rj  x€L
  \        WR4       K?  	  V P                  \        R4      4       V P!                  4       G Rj  x€L
  V P"                  P                  4        \$        P'                  RV P(                  4       R#  L‚  \        P                   d     L—i ; i L]5i)FNzWeCom adapter disconnectedz[%s] Disconnected)r·   r¸   )Ú_runningÚ_mark_disconnectedrK   rÍ   ÚvaluesrÏ   ÚcancelrÌ   rÎ   ÚclearÚgetattrrï   ÚCancelledErrorÚsetattrÚ	_fail_allÚRuntimeErrorr÷   r¼   rÝ   ró   rß   )rÑ   ÚtaskÚregistryÚattrs   &   r5   Ú
disconnectÚWeComAdapter.disconnectº   s4  é € ØˆŒØ×ÑÔ!Ü˜×+Ñ+×2Ñ2Ó4Ó5¼¸T×=RÑ=R×=YÑ=YÓ=[Ó8\×\Ð\ˆDØ�K‰KŽMñ ]à×+Ñ+¨T×-BÑ-BÀD×DUÑDUÐW[×WkÑWkÓlˆHØ�N‰NÖñ mã7ˆDÜ˜4Ó&ˆDßØ—‘”ðØ—J�Jô �D Ö%ñ 8ð 	�‰”|Ð$@ÓAÔBØ�n‰nÓ×ÐØ�‰×ÑÔÜ�‰Ð'¨¯©Ö3ñ øÜ×-Ñ-ô Ùðúñ 	ùsI   ‚C'FÃ*E4Ã/E2Ã0E4Ã4=FÄ1FÄ2A FÅ2E4Å4FÆ	FÆFÆFc               ó    € V ^8„  d   QhRRRR/# ©r0   rú   rõ   r1   rÿ   r3   )r4   s   "r5   r6   rx   Ï   s   € ÷ %ñ %˜Yð %¨4ñ %r7   c                	óJ   € V P                  V4       V P                  V4       R # r9   )Ú_fail_pending_responsesÚ_fail_reply_queues©rÑ   rú   s   &&r5   r	  ÚWeComAdapter._fail_allÏ   s   € Ø×$Ñ$ SÔ)Ø×Ñ Ö$r7   c               ó   € V ^8„  d   QhRR/# rþ   r3   )r4   s   "r5   r6   rx   Ó   s   € ÷ &ñ & 4ñ &r7   c              ƒ  ó¶   "  € R FL  p\        W4      pV'       d+   VP                  '       g   VP                  4       G Rj  x€L
  \        WR4       KN  	  R#  L5i)z3Close the live websocket, then its session, if any.N)rµ   r´   )r  ÚclosedÚcloser  )rÑ   r  Úlives   &  r5   Ú_cleanup_wsÚWeComAdapter._cleanup_wsÓ   sB   é € ã'ˆDÜ˜4Ó&ˆDß˜DŸKŸK˜KØ—j‘j“l×"Ð"Ü�D Ö%ó	 (ñ #ùs   ‚*A­AÁ AÁAc               ó   € V ^8„  d   QhRR/# rþ   r3   )r4   s   "r5   r6   rx   Û   s   € ÷ %ñ % ñ %r7   c              ƒ  óÀ   "  € V P                  4       G Rj  x€L
  V P                  '       d,   V P                  P                  4       G Rj  x€L
  RV n        R# R#  LC L5i)z)_cleanup_ws, then close the httpx client.N)r  r¶   Úaclose©rÑ   s   &r5   r÷   ÚWeComAdapter._teardownÛ   sP   é € à×ÑÓ × Ð Ø××ÐØ×#Ñ#×*Ñ*Ó,×,Ð,Ø $ˆDÖñ ñ 	!á,ùs&   ‚A–A—A­AÁ
AÁAÁAc               ó   € V ^8„  d   QhRR/# rþ   r3   )r4   s   "r5   r6   rx   â   s   € ÷ mñ m¨ñ mr7   c              ƒ  	óì  "  € V P                  4       G R j  x€L
  ^ R Ip^ RIHp V! 4       pVP	                  VR7      p\
        P                  ! \        4       \
        P                  ! VR7      R7      V n	        V P                  P                  V P                  \        ^,          \        R7      G R j  x€L
 V n        V P                  R4      pV P!                  R\"        RR	V/R
RV P$                  RV P&                  RV P(                  //4      G R j  x€L
  V P+                  V4      G R j  x€L
 pVP-                  R^ 4      pVR9  d"   \/        VP-                  RR4       RV R24      hR #  ELU L» L^ LG5i)N)Úcertifi_bundle_path)Úcafile)Ússl)Ú	trust_envÚ	connector)Ú	heartbeatÚtimeoutÚ	subscribeÚcmdÚheadersÚreq_idÚbodyr�   r’   Ú	device_idÚerrcodeÚerrmsgzauthentication failedz
 (errcode=Ú)¾   Né    )r  r'  Úagent.ssl_verifyr%  Úcreate_default_contextrå   ÚClientSessionr   ÚTCPConnectorr´   Ú
ws_connectr®   ÚHEARTBEAT_INTERVAL_SECONDSÚCONNECT_TIMEOUT_SECONDSrµ   Ú_new_req_idÚ
_send_jsonÚAPP_CMD_SUBSCRIBEr«   r¬   rÇ   Ú_wait_for_handshakerk   r
  )rÑ   Ú_sslr%  r&  Ú_ssl_ctxr/  Úauth_payloadr2  s   &       r5   rí   ÚWeComAdapter._open_connectionâ   s‘  é € Ø×ÑÓ × Ð ó 	å8Ù$Ó&ˆØ×.Ñ.°fÐ.Ó=ˆÜ×-Ò-Ô8IÓ8KÔW^×WkÒWkÐpxÔWyÔzˆŒØŸ™×1Ñ1°$·,±,ÔJdÐghÕJhô  sJÐ1ó  K÷  KˆŒØ×!Ñ! +Ó.ˆØ�o‰o˜uÔ&7¸ÀXÈvÐDVÐX^ÐaiÐko×kwÑkwð  zBð  DH÷  DPñ  DPð  R]ð  _c÷  _nñ  _nð  aoð  pó  q÷  	qð  	qØ!×5Ñ5°fÓ=×=ˆØ×"Ñ" 9¨aÓ0ˆØ˜)Ô#Ü ,×"2Ñ"2°8Ð=TÓ"UÐ!VÐV`ÐahÐ`iÐijÐkÓlÐlñ $ò 	!ñ Kñ 	qÙ=ùsH   ‚E4–E+—BE4Â2E.Â3AE4ÄE0ÄE4Ä*E2Ä+AE4Å.E4Å0E4Å2E4c               ó    € V ^8„  d   QhRRRR/# )r0   r/  rC   r1   rh   r3   )r4   s   "r5   r6   rx   ô   s   € ÷ Tñ T°ð T¸ñ Tr7   c              ƒ  	ó¦  "  € V P                   '       g   \        R 4      h\        P                  ! 4       pVP	                  4       \
        ,           pW2P	                  4       ,
          ;p^ 8”  EdV   \        P                  ! V P                   P                  4       VR7      G Rj  x€L
 pVP                  \        P                  P                  8X  d‹   V P                  VP                  4      pV'       d   VP                  R4      \        8X  d   K¾  V P!                  V4      V8X  d   V# \"        P%                  RV P&                  VP                  R4      4       EK	  VP                  \        P                  P(                  \        P                  P*                  \        P                  P,                  09   g   EKh  \        R4      h\/        R4      h EL-5i)zWebSocket not initialized©r+  Nr-  z"[%s] Ignoring pre-auth payload: %sz,WeCom websocket closed during authenticationz5Timed out waiting for WeCom subscribe acknowledgement)rµ   r
  rï   Úget_running_loopÚtimer=  Úwait_forÚreceiveÚtyperå   Ú	WSMsgTypeÚTEXTÚ_parse_jsonÚdatark   ÚAPP_CMD_PINGÚ_payload_req_idrÝ   Údebugrß   ÚCLOSEDÚCLOSEÚERRORÚTimeoutError)rÑ   r/  ÚloopÚdeadlineÚ	remainingÚmsgÚpayloads   &&     r5   rA  Ú WeComAdapter._wait_for_handshakeô   s@  é € Ø�x�xˆxÜÐ:Ó;Ð;Ü×'Ò'Ó)ˆØ—9‘9“;Ô!8Õ8ˆØ$§y¡y£{Õ2Ð2ˆy°aÕ7Ü×(Ò(¨¯©×)9Ñ)9Ó);ÀYÔO×OˆCØ�x‰xœ7×,Ñ,×1Ñ1Ô1Ø×*Ñ*¨3¯8©8Ó4�ß '§+¡+¨eÓ"4¼Ô"DÙØ×'Ñ'¨Ó0°FÔ:Ø"�NÜ—‘ÐAÀ4Ç9Á9ÈgÏkÉkÐZ_ÓN`×aØ—‘œg×/Ñ/×6Ñ6¼×8IÑ8I×8OÑ8OÔQX×QbÑQb×QhÑQhÐi×iÜ"Ð#QÓRÐRÜÐRÓSÐSò Pùs    ‚BGÂ!GÂ"AGÃ2C GÆ8Gc               ó   € V ^8„  d   QhRR/# rþ   r3   )r4   s   "r5   r6   rx     s   € ÷ Zñ Z Dñ Zr7   c           
   ƒ  	ó6  "  € ^ pV P                   '       d    V P                  4       G Rj  x€L
  ^ pK/  R#  L
  \        P                   d     R# \         Ed<   pT P                   '       g    Rp?R# \
        P                  RT P                  T4       T P                  \        R4      4       \        P                  ! \        \        T\        \        4      ^,
          4      ,          4      G Rj  x€L 
  T^,          p T P                  4       G Rj  x€L 
  ^ pT P                  4        \
        P!                  RT P                  4        Rp?EKM    \         d2   p\
        P                  RT P                  T4        Rp? Rp?EK„  Rp?ii ; iRp?ii ; i5i)r6  Nz[%s] WebSocket error: %szWeCom connection interruptedz[%s] Reconnectedz[%s] Reconnect failed: %s)r  Ú_read_eventsrï   r  rõ   rÝ   rÞ   rß   r	  r
  ÚsleepÚRECONNECT_BACKOFFÚminÚlenrí   rî   ró   )rÑ   Úbackoff_idxrú   Úreconnect_excs   &   r5   rñ   ÚWeComAdapter._listen_loop  s*  é € ØˆØ�m�mˆmðZØ×'Ñ'Ó)×)Ð)Ø’ñ á)øä×)Ñ)ô ÚÜõ ZØ—}—}�}ÝÜ—‘Ð9¸4¿9¹9ÀcÔJØ—‘œ|Ð,JÓKÔLÜ—m’mÔ$5´c¸+ÄsÔK\ÓG]Ð`aÕGaÓ6bÕ$cÓd×dÑdØ˜qÕ �ðZØ×/Ñ/Ó1×1Ñ1Ø"#�KØ×(Ñ(Ô*Ü—K‘KÐ 2°D·I±I×>Ó>øÜ ô ZÜ—N‘NÐ#>ÀÇ	Á	È=×Y×YûðZþðZüs˜   ‚F˜8 «6¬8 ²F¶8 ¸FÁFÁ	FÁFÁFÁ-FÁ3A=FÃ0C3Ã1FÄ EÄDÄ7EÅFÅFÅ!F	Å>FÆFÆ	FÆFÆFÆFc               ó   € V ^8„  d   QhRR/# rþ   r3   )r4   s   "r5   r6   rx     s   € ÷ 
]ñ 
] Dñ 
]r7   c              ƒ  	óœ  "  € V P                   '       g   \        R 4      hV P                  '       Ed“   V P                   '       Ed~   V P                   P                  '       Eg_   V P                   P	                  4       G Rj  x€L
 pVP
                  \        P                  P                  \        P                  P                  39   dL   V P                  VP                  VP
                  \        P                  P                  8H  4      G Rj  x€L
  Kó  VP
                  \        P                  P                  \        P                  P                  \        P                  P                  \        P                  P                  09   d   \        R4      h\         P#                  RV P$                  VP
                  4       EK¡  R# R# R#  ELG L½5i)zWebSocket not connectedNzWeCom websocket closedz([%s] Inbound frame ignored: WSMsgType=%s)rµ   r
  r  r  rL  rM  rå   rN  rO  ÚBINARYÚ_handle_framerQ  rV  rU  rW  ÚCLOSINGrÝ   ró   rß   )rÑ   r\  s   & r5   ra  ÚWeComAdapter._read_events  s1  é € Ø�x�xˆxÜÐ8Ó9Ð9Ø�m�m‰m §§¡°·±··±ØŸ™×(Ñ(Ó*×*ˆCØ�x‰xœG×-Ñ-×2Ñ2´G×4EÑ4E×4LÑ4LÐMÔMØ×(Ñ(¨¯©°3·8±8¼w×?PÑ?P×?WÑ?WÑ3WÓX×XÒXØ—‘œg×/Ñ/×5Ñ5´w×7HÑ7H×7OÑ7OÔQX×QbÑQb×QhÑQhÔjq×j{Ñj{÷  kDñ  kDð  Eô  EÜ"Ð#;Ó<Ð<ä—‘ÐFÈÏ	É	ÐSV×S[ÑS[×\ñ 2A¡‰mÚ*áXùs6   ‚0G³GÁGÁ#GÂ GÂBGÄG
ÄB;GÇ
Gc               ó$   € V ^8„  d   QhRRRRRR/# )r0   rQ  r   Ú	is_binaryr2   r1   rÿ   r3   )r4   s   "r5   r6   rx   )  s&   € ÷ nñ n¨ð n¸ð nÀñ nr7   c              ƒ  ó.  "  € \        V\        \        \        34      '       d   \	        V4      MR
pV'       dZ   \        V\        \        34      '       d   VP                  RRR7      MRp\        P                  RV P                  W4R,          4       V P                  V4      pV'       d   V P                  V4      G Rj  x€L
  R# V'       d#   \        P                  RV P                  4       R# \        P                  R	V P                  V4       R#  LS5i)zJParse one TEXT/BINARY frame and dispatch it; every drop is logged at INFO.úutf-8Úreplace©Úerrorsz<undecodable>uM   [%s] Inbound BINARY frame received (len=%d) head=%r â€” attempting JSON parse:NéÈ   NNu3   [%s] BINARY frame not parseable as JSON â€” droppedz=[%s] Inbound TEXT frame dropped (unparseable/non-dict) len=%déÿÿÿÿ)rI   rC   ÚbytesÚ	bytearrayre  ÚdecoderÝ   ró   rß   rP  Ú_dispatch_payload)rÑ   rQ  rp  Údata_lenÚdecodedr]  s   &&&   r5   rl  ÚWeComAdapter._handle_frame)  sÓ   é € ä *¨4´#´u¼iÐ1H× IÒ I”3�t”9ÈrˆßÜ@JÈ4ÔRWÔYbÐQc×@dÒ@d�d—k‘k '°)�kÔ<ÐjyˆGÜ�K‰KÐgÐim×irÑirÐt|ð  GKõ  Lô  MØ×"Ñ" 4Ó(ˆßØ×(Ñ(¨Ó1×1Ò1ßÜ�K‰KÐMÈtÏyÉyÖYä�K‰KÐWÐY]×YbÑYbÐdlÖmñ	 2ùs$   ‚6D¹A1DÂ+DÂ?DÃ DÃADc               ó   € V ^8„  d   QhRR/# rþ   r3   )r4   s   "r5   r6   rx   7  s   € ÷ 
ñ 
 tñ 
r7   c           	   ƒ  	óþ  "  €  V P                   '       dŒ   \        P                  ! \        4      G R j  x€L
   V P                  '       dU   V P                  P
                  '       g7   V P                  R\        RRV P                  R4      /R/ /4      G R j  x€L
  K™  K›  K�  R #  Lo L  \         d-   p\        P                  RT P                  T4        R p?KÕ  R p?ii ; i  \        P                   d     R # i ; i5i)Nr-  r.  r/  r,   r0  z[%s] Heartbeat send failed: %s)r  rï   rb  r<  rµ   r  r?  rR  r>  rõ   rÝ   rT  rß   r  r  s   & r5   rò   ÚWeComAdapter._heartbeat_loop7  sÖ   é € ð		Ø—-—-�-Ü—m’mÔ$>Ó?×?Ð?ðSØ—x—x�x¨¯©¯¯¨Ø"Ÿo™o¨u´lÀIÐPXÐZ^×ZjÑZjÐkqÓZrÐOsÐu{Ð}ð  /Aó  B÷  Bò  Bñ )8‘xñ  Ù?ñ BøÜ ô SÜ—L‘LÐ!AÀ4Ç9Á9Èc×RÒRûðSûä×%Ñ%ô 	Úð	üs„   ‚C=„C! –C! ³B#´C! ¹B' ÁB' Á'/B' ÂB%ÂB' ÂC! Â!C=Â#C! Â%B' Â'CÂ2!CÃC! ÃCÃC! Ã!C:Ã6C=Ã9C:Ã:C=c               ó    € V ^8„  d   QhRRRR/# ©r0   r]  rh   r1   rÿ   r3   )r4   s   "r5   r6   rx   C  s   € ÷ Nñ N¨~ð NÀ$ñ Nr7   c              ƒ  	ó  "  € V P                  V4      p\        VP                  R 4      ;'       g    R4      p\        VP                  R4      \        4      '       d   VP                  R4      MRpV P
                  '       dd   V\        8w  dY   \        P                  RV P                  T;'       g    RT;'       g    R\        V P
                  P                  4       4      4       V'       d˜   V P
                  P                  V4      '       dw   \        P                  RV P                  Y#V P
                  V,          P                  RJVe   VP                  RR	4      MR	V\        9   \        VP                  4       4      4       V'       dy   V\        9  dn   V P                  W!4      '       d   R# W P                  9   dE   V P                  V,          pV'       d(   VP!                  4       '       g   VP#                  V4       R# V\$        9   d   V P'                  V4      G Rj  x€L
  R# V\(        8X  dn   \        VP                  R4      ;'       g    / P                  R
4      ;'       g    R4      R8X  d*   \        P+                  RV P                  4       RV n        R# R# V\        8w  dW   \        P/                  RV P                  T;'       g    RT;'       g    RVe   \        VP                  4       4      MR4       R# R#  Lá5i)r-  rR   r0  Nz>[%s] _dispatch_payload[ALL]: req_id=%s cmd=%r active_queues=%sz(none)z(empty)zi[%s] _dispatch_payload: req_id=%s cmd=%r has_pending_ack=%s errcode=%s in_NON_RESPONSE=%s payload_keys=%sr2  zN/AÚ
event_typeÚdisconnected_eventz�[%s] Kicked by server (another WS connection established). Suppressing reconnect to avoid mutual kicking. Check for duplicate gateway instances.FzF[%s] Unrouted websocket payload dropped: cmd=%r req_id=%s body_keys=%s)rS  rC   rk   rI   rl   rº   rR  rÝ   rT  rß   rK   r†   Úpending_ackÚNON_RESPONSE_COMMANDSÚ_resolve_reply_ackr¹   ÚdoneÚ
set_resultÚCALLBACK_COMMANDSÚ_on_messageÚAPP_CMD_EVENT_CALLBACKrÞ   r  ró   )rÑ   r]  r/  r-  Ú	body_dictÚfutures   &&    r5   r{  ÚWeComAdapter._dispatch_payloadC  s  é € Ø×%Ñ% gÓ.ˆÜ�'—+‘+˜eÓ$×*Ð*¨Ó+ˆÜ+5°g·k±kÀ&Ó6IÌ4×+PÒ+P�G—K‘K Ô'ÐVZˆ	Ø××Ð #¬Ô"5Ü�L‰LÐYÐ[_×[dÑ[dÐfl×fxÐfxÐpxÐz}÷  {Kð  {Kð  BKô  MQð  RV÷  Rdñ  Rd÷  Riñ  Rió  Rkó  Mlô  mß�d×(Ñ(×,Ñ,¨V×4Ò4Ü�L‰LØ{ð  ~B÷  ~Gñ  ~Gð  IOØ×"Ñ" 6Õ*×6Ñ6¸dÐBÐgpÒg|ÀIÇMÁMÐR[Ð]bÔDcð  CHð  JMô  Qfñ  Jfô  hlð  mt÷  myñ  myó  m{ó  h|ô÷
 �cÔ!6Ô6Ø×&Ñ& v×7Ò7ÙØ×0Ñ0Ô0Ø×0Ñ0°Õ8�ß &§+¡+§-¢-Ø×%Ñ% gÔ.ÙØÔ#Ô#Ø×"Ñ" 7Ó+×+Ò+ØÔ*Ô*ä�G—K‘K Ó'×-Ð-¨2×2Ñ2°<Ó@×FÐFÀBÓGÐK_Ô_Ü—‘ð   rð  tx÷  t}ñ  t}ô  ~Ø %�–ñ `ð ”LÔ Ü�K‰KÐ`Ðbf×bkÑbkÐmp×m}Ðm}Ðt}ð  @F÷  @Rð  @Rð  JRð  nwò  nCô  TXð  Yb÷  Ygñ  Ygó  Yiô  Tjð  IMö  Nñ !ñ ,ùs]   ‚A?LÂ.LÂ1
LÂ<0LÃ- LÄA=LÆALÇLÇ12LÈ#LÈ$-LÉLÉ+A%LË
LË*Lc               ó    € V ^8„  d   QhRRRR/# r  r3   )r4   s   "r5   r6   rx   a  s   € ÷ 6ñ 6¨9ð 6¸ñ 6r7   c                	óä   € \        V P                  P                  4       4       FH  w  r#VP                  4       '       g   VP	                  V4       V P                  P                  VR 4       KJ  	  R # r9   )rK   r¹   ÚitemsrŠ  Úset_exceptionÚpop)rÑ   rú   r/  r�  s   &&  r5   r  Ú$WeComAdapter._fail_pending_responsesa  sR   € Ü" 4×#:Ñ#:×#@Ñ#@Ó#BÖC‰NˆFØ—;‘;—=’=Ø×$Ñ$ SÔ)Ø×#Ñ#×'Ñ'¨°Ö5ó Dr7   c               ó   € V ^8„  d   QhRR/# rþ   r3   )r4   s   "r5   r6   rx   g  s   € ÷ Cñ C˜Tñ Cr7   c                	óx   € V P                   '       d   V P                   P                  '       d   \        R 4      hR# )z WeCom websocket is not connectedN)rµ   r  r
  r!  s   &r5   Ú_require_wsÚWeComAdapter._require_wsg  s(   € Ø�x�xˆx˜4Ÿ8™8Ÿ?Ÿ?˜?ÜÐAÓBÐBñ +r7   c               ó    € V ^8„  d   QhRRRR/# rƒ  r3   )r4   s   "r5   r6   rx   k  s   € ÷ *ñ *¨ð *¸4ñ *r7   c              ƒ  	óx   "  € V P                  4        V P                  P                  V4      G R j  x€L
  R #  L5ir9   )rš  rµ   Ú	send_json)rÑ   r]  s   &&r5   r?  ÚWeComAdapter._send_jsonk  s)   é € Ø×ÑÔØ�h‰h× Ñ  Ó)×)Ô)ùs   ‚/:±8²:c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r0   r-  rC   r/  r0  rh   r+  r|   r1   r3   )r4   s   "r5   r6   rx   o  s1   € ÷ 6ñ 6 #ð 6¨sð 6¸.ð 6ÐSXð 6Ð]kñ 6r7   c              ƒ  	óp  "  € \         P                  ! 4       P                  4       ;qPP                  V&    V P	                  R VRRV/RV/4      G Rj  x€L
  \         P
                  ! WTR7      G Rj  x€L
 V P                  P                  VR4       #  L? L"  T P                  P                  TR4       i ; i5i)r-  r.  r/  r0  NrH  )rï   rI  Úcreate_futurer¹   r?  rK  r–  )rÑ   r-  r/  r0  r+  r�  s   &&&&& r5   Ú_requestÚWeComAdapter._requesto  s›   é € Ü3:×3KÒ3KÓ3M×3[Ñ3[Ó3]Ð]ˆ×(Ñ(¨Ñ0ð	6Ø—/‘/ 5¨#¨y¸8ÀVÐ:LÈfÐVZÐ"[Ó\×\Ð\Ü ×)Ò)¨&ÔB×Bà×#Ñ#×'Ñ'¨°Õ5ñ ]ÙBøà×#Ñ#×'Ñ'¨°Õ5üs@   ‚2B6µB ÁBÁB Á0BÁ1B Á4B6ÂB ÂB ÂB3Â3B6c               ó(   € V ^8„  d   QhRRRRRRRR/# )r0   r-  rC   r0  rh   r+  r|   r1   r3   )r4   s   "r5   r6   rx   w  s/   € ÷ Nñ N sð N°.ð NÈ5ð NÐo}ñ Nr7   c              ƒ  	ó€   "  € V P                  4        V P                  WP                  V4      W#4      G R j  x€L
 #  L5ir9   )rš  r£  r>  )rÑ   r-  r0  r+  s   &&&&r5   Ú_send_requestÚWeComAdapter._send_requestw  s3   é € Ø×ÑÔØ—]‘] 3×(8Ñ(8¸Ó(=¸tÓM×MÐMÑMùó   ‚5>·<¸>c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r0   Úreply_req_idrC   r0  rh   r-  r+  r|   r1   r3   )r4   s   "r5   r6   rx   {  s=   € ÷ añ a°cð aÀð aÐVYð aÐw|ð að  \jñ ar7   c              ƒ  ó€   "  € V P                  4        V P                  W0P                  V4      W$4      G Rj  x€L
 #  L5i)z<Send a reply frame correlated to an inbound callback req_id.N)rš  r£  Ú_require_reply_req_id)rÑ   r«  r0  r-  r+  s   &&&&&r5   Ú_send_reply_requestÚ WeComAdapter._send_reply_request{  s4   é € à×ÑÔØ—]‘] 3×(BÑ(BÀ<Ó(PÐRVÓ`×`Ð`Ñ`ùr©  c               ó    € V ^8„  d   QhRRRR/# )r0   r«  rC   r1   r3   )r4   s   "r5   r6   rx   �  s   € ÷ ñ ¨Cð °Cñ r7   c                	ór   € \        T ;'       g    R 4      P                  4       pV'       g   \        R4      hV# )rR   zreply_req_id is required)rC   rD   r€   )r«  Ú
normalizeds   & r5   r­  Ú"WeComAdapter._require_reply_req_id€  s2   € ä˜×+Ð+¨Ó,×2Ñ2Ó4ˆ
ßÜÐ7Ó8Ð8ØÐr7   c               ó    € V ^8„  d   QhRRRR/# )r0   ÚprefixrC   r1   r3   )r4   s   "r5   r6   rx   ˆ  s   € ÷ .ñ .˜Cð . Cñ .r7   c                	óJ   € V  R \         P                  ! 4       P                   2# )Ú-)rÄ   rÅ   rÆ   )rµ  s   &r5   r>  ÚWeComAdapter._new_req_id‡  s    € à�˜œ4Ÿ:š:›<×+Ñ+Ð,Ð-Ð-r7   c               ó    € V ^8„  d   QhRRRR/# )r0   r]  rh   r1   rC   r3   )r4   s   "r5   r6   rx   Œ  s   € ÷ Uñ U ð U°Cñ Ur7   c                	óœ   € V P                  R 4      p\        V\        4      '       d%   \        VP                  R4      ;'       g    R4      # R# )r.  r/  rR   )rk   rI   rl   rC   )r]  r.  s   & r5   rS  ÚWeComAdapter._payload_req_id‹  s>   € à—+‘+˜iÓ(ˆÜ3=¸gÄt×3LÒ3LŒs�7—;‘;˜xÓ(×.Ð.¨BÓ/ÐTÐRTÐTr7   c               ó    € V ^8„  d   QhRRRR/# )r0   rP   r   r1   úOptional[dict[str, Any]]r3   )r4   s   "r5   r6   rx   ‘  s   € ÷ >ñ >˜ð >Ð!9ñ >r7   c                	óØ  € \        V \        \        34      '       d   \        V 4      MR
p \        P
                  ! V 4      p\        T\        4      '       d   T# R#   \        P                   dÐ     \        T \        4      '       d   T MT P                  RRR7      p\        P                  ! RR7      P                  T4      p\        P                  RT4        L™  \         dW   p\        T \        \        34      '       d   \        T 4      ^d8”  d   T RR MT p\        P                  RYAT4        Rp? R# Rp?ii ; i\         d"   p\        P                  R	Ya4        Rp?R# Rp?ii ; i)é   rr  rs  rt  F)Ústrictz5WeCom payload required strict=False fallback (len=%d)NzQFailed to parse WeCom payload (strict=False also failed): error=%s len=%d tail=%rz.Failed to parse WeCom payload: error=%s len=%drw  iœÿÿÿ)rI   rC   rx  re  ÚjsonÚloadsÚJSONDecodeErrorrz  ÚJSONDecoderrÝ   ró   rõ   rÞ   rl   )rP   Úraw_lenr]  ÚtextÚexc2Útailrú   s   &      r5   rP  ÚWeComAdapter._parse_json�  s#  € ä(¨¬s´E¨l×;Ò;”#�c”(Àˆð	Ü—j’j “oˆGô % W¬d×3Ò3ˆwÐ=¸Ð=øô ×#Ñ#ô 		ðÜ(¨¬c×2Ò2‘s¸¿
¹
À7ÐS\¸
Ó8]�Ü×*Ò*°%Ô8×?Ñ?ÀÓE�Ü—‘ÐSÐU\Ö]øÜô Ü%/°´c¼5°\×%BÒ%BÄsÈ3ÃxÐRUÄ~�s˜4˜5‘zÐ[^�Ü—‘ÐrÐtxð  DHô  IÞûðúô ô 	Ü�N‰NÐKÈSÔZÝûð	úsC   «A ÁE)Á1A'CÃD;Ã%A
D6Ä/E)Ä6D;Ä;E)ÅE)ÅE$Å$E)c               ó    € V ^8„  d   QhRRRR/# rƒ  r3   )r4   s   "r5   r6   rx   ¤  s   € ÷ 0-ñ 0-¨ð 0-¸Dñ 0-r7   c              ƒ  	ó~	  "  € VP                  R 4      p\        V\        4      '       g   R# V P                  V4      p\	        VP                  R4      ;'       g*    T;'       g     \
        P                  ! 4       P                  4      p\        VR4      p\	        VP                  R4      ;'       g    R4      P                  4       pV P                  P                  V4      '       dN   \        P                  RV P                  YCV'       d   VP                  R4      MRVP                  R4      4       R# V'       d   \        V P                   WC\"        4       \	        VP                  R4      ;'       g    T4      P                  4       p\        P                  R	V P                  VP                  R4      VP                  R4      WbP                  R
4      \%        VP                  R4      4      4       V'       g;   \        P                  RV P                  \'        VP)                  4       4      4       R# \	        VP                  R4      ;'       g    R4      P+                  4       R8H  pV P-                  W‡V4      '       g   R# V P/                  Ws4       V P1                  V4      w  ršV'       d/   V	'       d'   \2        P4                  ! RRV	4      P                  4       p	V P7                  V4      G Rj  x€L
 w  r¼V P9                  W)V4      p\%        T
;'       d    T	;'       g    T4      pV
'       d   V'       g   T
p	V	'       g<   V'       g4   \        P                  RV P                  W‡VP                  R
4      4       R# T P;                  Yx'       d   RMRT;'       g    RT;'       g    RVR7      p\=        Y�YñYKTV'       d   RV 2MRV'       d   T
MR\>        P@                  ! \B        R7      R7
      pV PE                  V4      V PF                  9   p\%        V4      ;'       d     T	;'       g    RP                  4       '       * pV\H        PJ                  8X  d   V PL                  ^ 8”  g"   V'       g   V'       d%   V PN                  ^ 8”  d   V PQ                  V4       R# V PS                  V4      G Rj  x€L
  R#  ELÇ L	5i)r0  NÚmsgidÚfromÚuseridrR   zN[%s] Duplicate message %s ignored (dedup drop) req_id=%s sender=%r chattype=%rÚchattypeÚchatidzO[%s] Inbound callback: chattype=%r chatid=%r sender=%r msgtype=%r has_chatid=%sÚmsgtypez4[%s] Missing chat id, skipping message; body_keys=%sÚgroupz^@\S+\s*z@[%s] Empty WeCom message skipped: is_group=%s chat=%s msgtype=%rÚdm)Úchat_idÚ	chat_typeÚuser_idÚ	user_nameÚ
message_idúquote:)Útz)
rÆ  Úmessage_typeÚsourceÚraw_messagerØ  Ú
media_urlsÚmedia_typesÚreply_to_message_idÚreply_to_textÚ	timestamp)*rk   rI   rl   rS  rC   rÄ   rÅ   rÆ   rn   rD   r¼   Úis_duplicaterÝ   ró   rß   r   r½   r»   r2   rK   r†   r_   Ú_admit_inboundÚ_remember_chat_req_idÚ_extract_textrT   rU   Ú_extract_mediaÚ_derive_message_typeÚbuild_sourcer   r   Únowr   Ú_text_batch_keyÚ_pending_text_batchesr   rO  r¾   rÀ   Ú_enqueue_text_eventÚhandle_message)rÑ   r]  r0  r/  Úmsg_idÚsenderÚ	sender_idrÔ  Úis_grouprÆ  Ú
reply_textrÞ  rß  rÛ  Úhas_reply_contextrÜ  ÚeventÚhas_pending_batchÚis_attachment_onlys   &&                 r5   r�  ÚWeComAdapter._on_message¤  s’  é € Ø�{‰{˜6Ó"ˆÜ˜$¤×%Ò%ÙØ×%Ñ% gÓ.ˆÜ�T—X‘X˜gÓ&×DÐD¨&×DÐD´D·J²J³L×4DÑ4DÓEˆÜ  fÓ-ˆÜ˜Ÿ
™
 8Ó,×2Ð2°Ó3×9Ñ9Ó;ˆ	Ø�;‰;×#Ñ# F×+Ò+ä�K‰KÐhÐjn×jsÑjsÐu{÷  ^dð  FL÷  FPñ  FPð  QYô  FZð  jnð  pt÷  pxñ  pxð  yCó  pDô  EÙßÜ˜×+Ñ+¨V¼^ÔLÜ�d—h‘h˜xÓ(×5Ð5¨IÓ6×<Ñ<Ó>ˆÜ�‰ÐeÐgk×gpÑgpÐrv×rzÑrzð  |Fó  sGð  IM÷  IQñ  IQð  RZó  I[ð  ]f÷  hpñ  hpð  qzó  h{ô  }Að  BF÷  BJñ  BJð  KSó  BTó  }Uô  	VßÜ�K‰KÐNÐPT×PYÑPYÔ[_Ð`d×`iÑ`iÓ`kÓ[lÔmÙÜ�t—x‘x 
Ó+×1Ð1¨rÓ2×8Ñ8Ó:¸gÑEˆØ×"Ñ" 8°i×@Ò@Ùà×"Ñ" 7Ô3Ø×-Ñ-¨dÓ3ÑˆßŸÜ—6’6˜+ r¨4Ó0×6Ñ6Ó8ˆDØ(,×(;Ñ(;¸DÓ(A×"AÑˆ
Ø×0Ñ0°¸[ÓIˆÜ  ×!DÐ!D°×1CÐ1C¸ÓEÐß×/ØˆDßŸJÜ�K‰KÐZÐ\`×\eÑ\eÐgoÐz~÷  {Cñ  {Cð  DMó  {Nô  OÙØ×"Ñ"¨7Î¹gÐW[Ðen×evÐevÐrvð  CL÷  CTð  CTð  PTØ.4ð #ó 6ˆäØ¸Ðagð  MXß5F &¨¨Ñ 1ÈD×nÑ`jð  FJô  V^÷  Vbò  Vbô  fiô  Vjô
ˆð !×0Ñ0°Ó7¸4×;UÑ;UÑUÐÜ! *Ó-×JÐJ°t·z°z¸r×6HÑ6HÓ6JÔ2JÐØœK×,Ñ,Ô,°$×2PÑ2PÐSTÔ2T×Xi÷  qCð  HL÷  Hqñ  Hqð  tuô  HuØ×$Ñ$ UÖ+à×%Ñ% eÓ,×,Ò,ò+ #Bñ* -ùs£   ‚AR=Á	R=Á$AR=Â15R=Ã'AR=Ä<7R=Å4CR=ÉA%R=Ê7:R=Ë1R8Ë2/R=Ì"R=Ì1R=Ì9	R=ÍR=ÍAR=Î
R=Î('R=ÏAR=Ð#	R=Ð-AR=Ñ1R=Ñ98R=Ò1R;Ò2R=Ò;R=c               ó(   € V ^8„  d   QhRRRRRRRR/# )r0   rò  r2   rÔ  rC   rñ  r1   r3   )r4   s   "r5   r6   rx   Ö  s(   € ÷ ñ  tð °cð Àcð Èdñ r7   c                óN  € V'       g=   V P                  V4      pV'       g"   \        P                  RV P                  V4       V# V P                  P                  V4       V P                  W#4      pV'       g-   \        P                  RV P                  W#V P                  4       V# )zNApply group_policy / dm_policy at intake; logs and returns False when dropped.z#[%s] DM sender %s blocked by policyzŠ[%s] Group message DROPPED by policy: chat=%s sender=%s group_policy=%r (set group_policy to 'open' or add to group_allow_from to receive))Ú_is_dm_intake_allowedrÝ   ró   rß   rË   ÚaddÚ_is_group_allowedr±   )rÑ   rò  rÔ  rñ  Úalloweds   &&&& r5   rä  ÚWeComAdapter._admit_inboundÖ  sƒ   € çØ×0Ñ0°Ó;ˆGßÜ—‘ÐAÀ4Ç9Á9ÈiÔXØˆNØ×Ñ× Ñ  Ô)Ø×(Ñ(¨Ó<ˆßÜ�K‰Kð ]Ø—	‘	˜7¨t×/AÑ/Aôð ˆr7   c               ó    € V ^8„  d   QhRRRR/# )r0   rõ  r   r1   rÿ   r3   )r4   s   "r5   r6   rx   æ  s   € ÷ Iñ I¨ð I¸$ñ Ir7   c                ó°  <€ V P                   P                  V P                  V4      4      p\        SV `  V4       Ve˜   VP
                  '       d„   VP
                  P                  4       '       db   \        P                  Vn	        VP                  '       d9   VP                  '       g%   VP                  Vn
        VP                  Vn        R# R# R# R# R# R# )z{Buffer + reset the flush timer; real text joining a buffered attachment promotes it to TEXT and inherits the quote context.N)rì  rk   rë  r©   rí  rÆ  rD   r   rO  rÛ  rá  rà  )rÑ   rõ  ÚexistingrÒ   s   && €r5   rí  Ú WeComAdapter._enqueue_text_eventæ  s¦   ø€ à×-Ñ-×1Ñ1°$×2FÑ2FÀuÓ2MÓNˆÜ‰Ñ# EÔ*ØÒ E§J§J J°5·:±:×3CÑ3C×3EÒ3EÜ$/×$4Ñ$4ˆHÔ!Ø×"×"Ð"¨8×+A×+AÐ+AØ).×)<Ñ)<�Ô&Ø/4×/HÑ/H�Ö,ñ ,BÑ"ñ 4F¡JÑr7   c               ó    € V ^8„  d   QhRRRR/# )r0   ÚpendingzOptional[MessageEvent]r1   r|   r3   )r4   s   "r5   r6   rx   ð  s   € ÷ 6ñ 6Ð-Cð 6Èñ 6r7   c                	óº   <€ VeI   VP                   '       d7   VP                  ;'       g    RP                  4       '       g   V P                  # \        SV `  V4      # )NrR   )rÞ  rÆ  rD   rÀ   r©   Ú_text_batch_delay_for)rÑ   r  rÒ   s   &&€r5   r  Ú"WeComAdapter._text_batch_delay_forð  sJ   ø€ ØÒ 7×#5×#5Ð#5¸w¿|¹|×?QÐ?QÈr×>XÑ>X×>ZÒ>ZØ×<Ñ<Ð<Ü‰wÑ,¨WÓ5Ð5r7   c               ó    € V ^8„  d   QhRRRR/# )r0   r0  rh   r1   ztuple[str, Optional[str]]r3   )r4   s   "r5   r6   rx   ö  s   € ÷ Rñ R˜Nð RÐ/Hñ Rr7   c                	ó�  € \        V P                  R 4      ;'       g    R4      P                  4       pVR8X  d¡   \        V R4      P                  R4      p\	        V\
        4      '       d   TM.  Uu. uF`  p\	        V\        4      '       g   K  \        VP                  R 4      ;'       g    R4      P                  4       R8X  g   KT  \        VR4      NKb  	  ppMe\        V R4      VR8X  d   \        V R4      MRVR8X  d=   \        \        V R4      P                  R4      ;'       g    R4      P                  4       MR.p\        V R4      p\        VP                  R 4      ;'       g    R4      P                  4       pVR9   d   \        WV4      ;'       g    R	MR	pR
P                  R V 4       4      P                  4       V3# u upi )rÑ  rR   ÚmixedÚmsg_itemrÆ  ÚvoiceÚappmsgÚtitleÚquoteNÚ
c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir9   r3   )rE   Úparts   & r5   rG   Ú-WeComAdapter._extract_text.<locals>.<genexpr>  s   é € Ð=©* $»Ÿš«*ùs   ‚	�
)rÆ  r  )
rC   rk   r_   rn   rI   rK   rl   rr   rD   Újoin)r0  rÑ  r”  rF   Ú
text_partsr  Ú
quote_typeró  s   &       r5   ræ  ÚWeComAdapter._extract_textõ  s×  € ä�d—h‘h˜yÓ)×/Ð/¨RÓ0×6Ñ6Ó8ˆØ�gÔÜ" 4¨Ó1×5Ñ5°jÓAˆEÜJTÐUZÔ\`×JaÒJaÁÐgiÐAió  {ÑAi¸ÔnxÐy}ô  @D÷  oEÔ3ô  JMð  NR÷  NVñ  NVð  W`ó  Na÷  Ngð  Ngð  egó  Jh÷  Jnñ  Jnó  Jpð  tzñ  JzÔ3œ+ d¨FÖ3ÑAiˆJð  {ˆJô ˜D &Ó)ÈÐT[ÔI[¬;°t¸WÔ+EÐacØRYÐ]eÔRe””N 4¨Ó2×6Ñ6°wÓ?×EÐEÀ2ÓF×LÑLÔNÐkmðˆJô ˜t WÓ-ˆÜ˜Ÿ™ 9Ó-×3Ð3°Ó4×:Ñ:Ó<ˆ
Ø?IÐM^Ô?^”[ Ó3×;Ð;°tøÐdhˆ
Ø�y‰yÑ=©*Ó=Ó=×CÑCÓEÀzÐQÐQùò {s   Á1GÂGÂ+GÃGc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r0   r0  rh   rÆ  rC   rß  r?   r1   r   r3   )r4   s   "r5   r6   rx     s)   € ÷  ñ   >ð  ¸ð  È9ð  ÐYdñ  r7   c                	ó  € \         ;QJ d    R  V 4       F  '       g   K   RM	  RM! R  V 4       4      '       d   \        P                  # \         ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d)   V'       d   \        P                  # \        P                  # \        V P                  R4      ;'       g    R4      P                  4       R8X  d   \        P                  # \        P                  # )c              3  óB   "  € T F  qP                  R4      x € K  	  R# 5i)úapplication/N)r  ztext/©Ú
startswith©rE   Úmtypes   & r5   rG   Ú4WeComAdapter._derive_message_type.<locals>.<genexpr>  s   é € ÐTÉ¸u×ÑÐ 9×:Ð:Ëùó   ‚TFc              3  óB   "  € T F  qP                  R 4      x € K  	  R# 5i)zimage/Nr  r  s   & r5   rG   r!  	  s   é € ÐC±{¨e×Ñ ×)Ð)³{ùr"  rÑ  rR   r  )	rc   r   ÚDOCUMENTrO  ÚPHOTOrC   rk   r_   ÚVOICE)r0  rÆ  rß  s   &&&r5   rè  Ú!WeComAdapter._derive_message_type  s¨   € ç‹3ÑTÉÓT�3�3Š3ÑTÉÓT×TÒTÜ×'Ñ'Ð'ß‹3ÑC±{ÓC�3�3Š3ÑC±{ÓC×CÒCß'+”;×#Ñ#ÐB´×1BÑ1BÐBÜˆt�x‰x˜	Ó"×(Ð( bÓ)×/Ñ/Ó1°WÔ<Ü×$Ñ$Ð$Ü×ÑÐr7   c               ó$   € V ^8„  d   QhRRRRRR/# rY   r3   )r4   s   "r5   r6   rx     s!   € ÷ /ñ / ið /¸ð /Àñ /r7   c                	ó   € \        W4      # r9   )rd   )rÑ   rZ   r[   s   &&&r5   rd   ÚWeComAdapter._entry_matches  s   € Ü˜gÓ.Ð.r7   c               ó$   € V ^8„  d   QhRRRRRR/# )r0   rÔ  rC   rñ  r1   r2   r3   )r4   s   "r5   r6   rx     s&   € ÷ Qñ Q¨ð Q¸ð QÀñ Qr7   c                óä   <€ \         SV `  V4      '       g   R# V P                  V4      p\        VP	                  R4      ;'       g    VP	                  R4      4      pV'       d   \        WB4      # R# )zWPer-group ``groups.<id>.allow_from`` restricts senders on top of the chat-level policy.Frš   r›   T)r©   rý  Ú_resolve_group_cfgrN   rk   rd   )rÑ   rÔ  rñ  Ú	group_cfgÚsender_allowrÒ   s   &&&  €r5   rý  ÚWeComAdapter._is_group_allowed  s]   ø€ ä‰wÑ(¨×1Ò1ÙØ×+Ñ+¨GÓ4ˆ	Ü# I§M¡M°,Ó$?×$]Ð$]À9Ç=Á=ÐQ\ÓC]Ó^ˆß:FŒ~˜lÓ6ÐPÈDÐPr7   c               ó    € V ^8„  d   QhRRRR/# ©r0   rÔ  rC   r1   rh   r3   )r4   s   "r5   r6   rx     s   € ÷ Hñ H¨#ð H°.ñ Hr7   c                óT  a€ \        V P                  \        4      '       g   / # VP                  4       oV P                  P	                  V4      \        V3R lV P                  P                  4        4       R4      V P                  P	                  R4      3p\        R V 4       / 4      # )zKExact key, then case-insensitive key, then ``"*"``; only dict values count.c              3  óº   <"  € T FP  w  r\        V\        4      '       g   K  VP                  4       S8X  g   K4  \        V\        4      '       g   KL  Vx € KR  	  R # 5ir9   )rI   rC   r_   rl   )rE   rŠ   ÚvÚlowereds   &  €r5   rG   Ú2WeComAdapter._resolve_group_cfg.<locals>.<genexpr>  s`   øé € ð  7bÑEY¹T¸QÔ]gÐhiÔkn×]o´qÐtu×t{Ñt{Ót}ð  BIñ  uI´qô  NXð  YZô  \`÷  Na·q²qÓEYùs   ƒA¢A¹AÁ
ANr^   c              3  óV   "  € T F  p\        V\        4      '       g   K  Vx € K!  	  R # 5ir9   )rI   rl   )rE   Úcs   & r5   rG   r7     s   é € ÐB¡
˜1¬j¸¼D×.A—Q’Q£
ùs   ‚)Ÿ
))rI   r³   rl   r_   rk   rŒ   r”  )rÑ   rÔ  Ú
candidatesr6  s   && @r5   r-  ÚWeComAdapter._resolve_group_cfg  s¬   ø€ ä˜$Ÿ,™,¬×-Ò-ØˆIØ—-‘-“/ˆØ—l‘l×&Ñ& wÓ/´ô  7bÀTÇ\Á\×EWÑEWÔEYó  7bð  dhó  2ið  ko÷  kwñ  kw÷  k{ñ  k{ð  |ó  k@ð  Aˆ
ÜÑB¡
ÓBÀBÓGÐGr7   c               ó$   € V ^8„  d   QhRRRRRR/# )r0   rÔ  rC   r/  r1   rÿ   r3   )r4   s   "r5   r6   rx   "  s!   € ÷ 8ñ 8¨Sð 8¸#ð 8À$ñ 8r7   c                ó$  € \        T;'       g    R4      P                  4       \        T;'       g    R4      P                  4       r!V'       dC   V'       d9   \        V P                  W\        4       V P
                  P                  V4       R# R# R# )zWCache the chat's latest inbound req_id; a fresh one also resurrects its stream channel.rR   N)rC   rD   r   rÈ   r»   rÊ   Údiscard)rÑ   rÔ  r/  s   &&&r5   rå  Ú"WeComAdapter._remember_chat_req_id"  sc   € ä˜gŸm˜m¨Ó,×2Ñ2Ó4´c¸&¿,¸,ÀBÓ6G×6MÑ6MÓ6O�ß—vÜ˜×/Ñ/°Ä.ÔQØ×&Ñ&×.Ñ.¨wÖ7ñ ‰7r7   c               ó    € V ^8„  d   QhRRRR/# )r0   Úreply_toúOptional[str]r1   r3   )r4   s   "r5   r6   rx   )  s   € ÷ rñ r°-ð rÀMñ rr7   c                	óÀ   € \        T;'       g    R 4      P                  4       pV'       d   VP                  R4      '       d   R# V P                  P	                  V4      # )rR   rÙ  N)rC   rD   r  r½   rk   )rÑ   rA  r²  s   && r5   Ú_reply_req_id_for_messageÚ&WeComAdapter._reply_req_id_for_message)  sJ   € Ü˜Ÿ˜ RÓ(×.Ñ.Ó0ˆ
ß%¨×)>Ñ)>¸x×)HÒ)HˆtÐqÈd×NaÑNa×NeÑNeÐfpÓNqÐqr7   c               ó$   € V ^8„  d   QhRRRRRR/# )r0   rÔ  rC   rA  rB  r1   r3   )r4   s   "r5   r6   rx   -  s&   € ÷ `ñ `¨Cð `¸=ð `È]ñ `r7   c                ój   € V P                  V4      ;'       g    V P                  P                  V4      # )z?Explicit reply_to mapping, else the chat's last inbound req_id.)rD  rÈ   rk   )rÑ   rÔ  rA  s   &&&r5   Ú_cached_reply_req_idÚ!WeComAdapter._cached_reply_req_id-  s-   € à×-Ñ-¨hÓ7×_Ð_¸4×;RÑ;R×;VÑ;VÐW^Ó;_Ð_r7   c               ó    € V ^8„  d   QhRRRR/# )r0   r2  Úintr1   rÿ   r3   )r4   s   "r5   r6   rx   1  s   € ÷ $ñ $ÀCð $ÈDñ $r7   c              ƒ  óÒ   "  € V\         8w  d   R# \        P                  RV P                  V4       V P                  P                  4        V P                  P                  4        R# 5i)zªOn 846609 (subscription lost) drop req_ids bound to the dead session. Do NOT close the
WS: a second connection gets kicked and invalidates the first (infinite kick loop).Nu@   [%s] Got errcode %d (subscription lost) â€” clearing stale state)r#   rÝ   rÞ   rß   rÈ   r  r½   )rÑ   r2  s   &&r5   Ú&_force_reconnect_on_stale_subscriptionÚ3WeComAdapter._force_reconnect_on_stale_subscription1  sP   é € ð Ô3Ô3ÙÜ�‰ÐYÐ[_×[dÑ[dÐfmÔnØ×Ñ×%Ñ%Ô'Ø×Ñ×!Ñ!Ö#ùs   ‚A%A'c               ó    € V ^8„  d   QhRRRR/# )r0   Úresponserh   r1   rB  r3   )r4   s   "r5   r6   rx   ;  s   € ÷ yñ y .ð y°]ñ yr7   c                	óz   € V P                  R ^ 4      pVR9   d   R# RT RV P                  R4      ;'       g    R 2# )r2  NzWeCom errcode z: r3  úunknown errorr5  r‰   )rP  r2  s   & r5   Ú_response_errorÚWeComAdapter._response_error:  sE   € à—,‘,˜y¨!Ó,ˆØ )Ô+ˆtÐx°>À'ÀÈ"ÈXÏ\É\ÐZbÓMc×MvÐMvÐgvÐLwÐ1xÐxr7   c               ó$   € V ^8„  d   QhRRRRRR/# )r0   rP  rh   Ú	operationrC   r1   rÿ   r3   )r4   s   "r5   r6   rx   @  s"   € ÷ ?ñ ?¨nð ?Èð ?ÐQUñ ?r7   c                	óX   € V P                  V4      pV'       d   \        V R V 24      hR# ©z	 failed: N)rS  r
  )ÚclsrP  rV  rö   s   &&& r5   Ú_raise_for_wecom_errorÚ#WeComAdapter._raise_for_wecom_error?  s0   € à×#Ñ# HÓ-ˆßÜ ) ¨I°e°WÐ=Ó>Ð>ñ r7   c               ó    € V ^8„  d   QhRRRR/# )r0   rq   rC   r1   rh   r3   )r4   s   "r5   r6   rx   E  s   € ÷ cñ c cð c¨nñ cr7   c                	ó,   € R RRRVRV P                    //# )rÑ  Úmarkdownrq   N)ÚMAX_MESSAGE_LENGTH)rÑ   rq   s   &&r5   Ú_markdown_bodyÚWeComAdapter._markdown_bodyE  s$   € Ø˜: z°I¸wÐG_È×H_ÑH_Ð?`Ð3aÐbÐbr7   c               ó$   € V ^8„  d   QhRRRRRR/# )r0   r«  rC   rq   r1   rh   r3   )r4   s   "r5   r6   rx   H  s!   € ÷ ñ °sð ÀSð È^ñ r7   c              ƒ  	ó†   "  € V P                  WP                  V4      4      G R j  x€L
 pV P                  VR4       V#  L5i)Nzsend reply markdown)r®  r`  rZ  )rÑ   r«  rq   rP  s   &&& r5   Ú_send_reply_markdownÚ!WeComAdapter._send_reply_markdownH  s@   é € Ø×1Ñ1°,×@SÑ@SÐT[Ó@\Ó]×]ˆØ×#Ñ# HÐ.CÔDØˆñ ^ùs   ‚$A¦?§Ac               ó$   € V ^8„  d   QhRRRRRR/# )r0   rÔ  rC   rq   r1   rh   r3   )r4   s   "r5   r6   rx   M  s&   € ÷ kñ k°cð kÀCð kÈNñ kr7   c              ƒ  	óp   "  € V P                  \        R V/V P                  V4      C4      G Rj  x€L
 #  L5i)rÐ  N)r§  r   r`  )rÑ   rÔ  rq   s   &&&r5   Ú_send_proactive_markdownÚ%WeComAdapter._send_proactive_markdownM  s4   é € Ø×'Ñ'¬°xÀÐ6iÈD×L_ÑL_Ð`gÓLhÐ6iÓj×jÐjÑjùs   ‚-6¯4°6c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r0   rÔ  rC   rq   rA  rB  Úmetadatar½  r1   r   r3   )r4   s   "r5   r6   rx   P  s<   € ÷ Bñ B #ð B°ð B¸}ð BÐ_wð Bð  DNñ Br7   c              ƒ  ó   a aaaa"  € S'       g   \        RRR7      # T;'       g    / pVP                  RR4      o\        VP                  RR4      4      o\        S P	                  VS P
                  4      VVVVV 3R l4      G Rj  x€L
 #  L5i)zªSend standalone markdown (never touches active streams); serialized per chat for the 30 msgs/min
limit (846607). ``metadata["is_approval_prompt"]`` uses the control lane.Fzchat_id is required©Úsuccessrö   Úis_approval_promptÚforce_proactive_sendc                ó>   <a € SP                  SVV VVV3R  lSR7      # )c                 ó.   <€ SP                  S SSSR 7      # ))Úforce_proactive)Ú_send_inner)rÔ  Úchunkrs  rA  rÑ   s   €€€€€r5   Ú<lambda>Ú5WeComAdapter.send.<locals>.<lambda>.<locals>.<lambda>[  s   ø€ ˜T×-Ñ-¨g°u¸hÐXgÐ-Ôhr7   )Ú
is_control)Ú_enqueue_chat_send)ru  rÔ  rs  rx  rA  rÑ   s   f€€€€€r5   rv  Ú#WeComAdapter.send.<locals>.<lambda>Z  s&   ù€ Ðhl×hÑhØ×hÐhÐuð i@ô iAr7   N)r   r–  r2   r   Útruncate_messager_  )rÑ   rÔ  rq   rA  rk  rs  rx  s   ff&f&@@r5   ÚsendÚWeComAdapter.sendP  s‰   üé € ÷ Ü eÐ3HÔIÐIØ—>�>˜rˆØ—\‘\Ð"6¸Ó>ˆ
ä˜xŸ|™|Ð,BÀEÓJÓKˆä  ×!6Ñ!6°wÀ×@WÑ@WÓ!X÷ [Að [Aó B÷ Bð 	Bñ Bùs   ‡B¦A!BÂBÂBrs  c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r0   rÔ  rC   rq   rA  rB  rs  r2   r1   r   r3   )r4   s   "r5   r6   rx   ]  s<   € ÷ Cñ C¨ð C°sð CÀmð CÐptð Cð  BLñ Cr7   c             ƒ  ó6  "  €  V'       d   WP                   9  d   RMV P                  W4      pV'       d    V P                  WR4      G Rj  x€L
 pMXWP                   9   d/   \
        P                  RV P                  V4       \        RRR7      # V P                  W4      G Rj  x€L
 p V P                  V4      ;p	'       d)   V P                  W–P!                  R	^ 4      \        8H  4      # \        R
V P#                  V4      ;'       g'    \$        P&                  ! 4       P(                  R,          VR7      #  Lé  \        \        3 dF   p\
        P                  RT P                  T4       T P                  Y4      G Rj  x€L 
 p Rp?LßRp?ii ; i Lì  \         d    \        RRR7      u # \         d`   p\
        P                  RT P                  T4       T P                  \        T4      \        \        4      \        T4      9   4      u Rp?# Rp?ii ; i5i)zTSend under the per-chat queue; force_proactive skips passive reply except in groups.Nz>[%s] Passive reply failed (%s), falling back to proactive sendua   [%s] No cached req_id for group chat %s â€” cannot send (groups require passive reply via req_id)Fz;No req_id available for group chat (passive reply required)rm  z Timeout sending message to WeComz[%s] Send failed: %sr2  T:Né   N)rn  rØ  Úraw_response)rË   rH  rd  rX  r
  rÝ   rÞ   rß   rh  r   rõ   rö   Ú_send_failurerC   r#   rS  rk   rS  rÄ   rÅ   rÆ   )
rÑ   rÔ  rq   rA  rs  r«  rP  Úpassive_errrú   rö   s
   &&&&$     r5   rt  ÚWeComAdapter._send_inner]  sã  é € ð	`ß#2°w×FZÑFZÔ7Z™4Ð`d×`yÑ`yð  {Bó  aMˆLßðUØ%)×%>Ñ%>¸|Ó%U×U‘Hð
 ×0Ñ0Ô0Ü—‘ð   Cð  EI÷  ENñ  ENð  PWô  XÜ!¨%Ð7tÔuÐuà!%×!>Ñ!>¸wÓ!P×P‘ð ×(Ñ(¨Ó2Ð2ˆ5Ö2Ø×%Ñ% e¯\©\¸)ÀQÓ-GÔKhÑ-hÓiÐiÜ $°4×3GÑ3GÈÓ3Q×3jÐ3jÔUY×U_ÒU_ÓUa×UeÑUeÐfiÕUjð  zBô  Cð  	Cñ#  VøÜ$¤lÐ3ô Uä—N‘NÐ#cÐei×enÑenÐp{Ô|Ø%)×%BÑ%BÀ7Ó%T×TÐT•HûðUúñ QøÜô 	WÜ eÐ3UÔVÒVÜô 	`Ü�L‰LÐ/°·±¸CÔ@Ø×%Ñ%¤c¨#£h´Ô4QÓ0RÔVYÐZ]ÓV^Ñ0^Ó_Õ_ûð	`üs¿   ‚H„2F ¸D8 ÁD6ÁD8 ÁHÁ=F ÂHÂF Â$FÂ%F Â)HÃAHÄ	-HÄ6D8 Ä8FÅ	5F	Å>FÅ?F	ÆF ÆHÆ	FÆF ÆHÆ+HÆ-HÆ6HÆ7AHÈHÈHÈHÈHc               ó$   € V ^8„  d   QhRRRRRR/# )r0   rö   rC   Úsubscription_lostr2   r1   r   r3   )r4   s   "r5   r6   rx   v  s!   € ÷ 6ñ 6 3ð 6¸4ð 6ÀJñ 6r7   c                ó~   € V'       d*   \         P                  ! V P                  \        4      4       \	        RVR7      # )zTFailed SendResult; on 846609 schedule the stale-req_id purge so later sends recover.Frm  )rï   Úensure_futurerM  r#   r   )rÑ   rö   r†  s   &&&r5   r‚  ÚWeComAdapter._send_failurev  s,   € çÜ×!Ò! $×"MÑ"MÔNkÓ"lÔmÜ %¨uÔ5Ð5r7   c               ó    € V ^8„  d   QhRRRR/# r2  r3   )r4   s   "r5   r6   rx   |  s   € ÷ oñ o¨3ð o°>ñ or7   c              ƒ  	óv   "  € R TRV'       d)   VP                  4       P                  R4      '       d   R/# R/# 5i)rß   rM  rÒ  rÓ  )r_   r  )rÑ   rÔ  s   &&r5   Úget_chat_infoÚWeComAdapter.get_chat_info|  s6   é € Ø˜ ·GÀÇÁÃ×@ZÑ@ZÐ[b×@cÒ@c¨ÐnÐnÐimÐnÐnùs   ‚09³9)"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®   )NNr9   )AÚ__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚALLOW_ALL_ENV_PREFIXr_  ÚSUPPORTS_MESSAGE_EDITINGÚSUPPORTS_NATIVE_STREAMINGr$   Úsplits_long_messagesÚ_SPLIT_THRESHOLDÚserial_receive_looprª   rà   rû   r  r	  r  r÷   rí   rA  rñ   ra  rl  rò   r{  r  rš  r?  r£  ÚREQUEST_TIMEOUT_SECONDSr§  r"   r®  Ústaticmethodr­  r>  rS  rP  r�  rä  rí  r  ræ  rè  rd   rý  r-  rå  rD  rH  rM  rS  ÚclassmethodrZ  r`  rd  rh  r|  rt  r‚  rŒ  Ú__static_attributes__Ú__classcell__)rÒ   s   @r5   rt   rt   g   sø  ø† ÙKà"ÐØ+ÐØ$ÐØ $ÐØ 9ÐØÐØÐØÐ÷)Hð )HõVð
°E÷ õ.4õ*%õ&õ%õmõ$Tõ$Zõ.
]õnõ
õNõ<6õCõ*õ6ð Tk÷ Nð ]mð  @W÷ að
 ôó ðð ô.ó ð.ð ôUó ðUð ô>ó ð>õ&0-õd÷ Ið I÷6ð 6ð
 ôRó ðRð ô ó ð õ/÷Qð QõHõ8õrõ`õ$ð ôyó ðyð ô?ó ð?õ
cõõ
k÷BñCÐw|÷ Cð Cõ26÷oó or7   rt   z)https://work.weixin.qq.com/ai/qc/generatez-https://work.weixin.qq.com/ai/qc/query_resultz9https://work.weixin.qq.com/ai/qc/gen?source=hermes&scode=i,  Útimeout_secondsc               ó    € V ^8„  d   QhRRRR/# )r0   rž  rK  r1   zOptional[dict[str, str]]r3   )r4   s   "r5   r6   r6   †  s   € ÷ <ñ <¨Sð <ÐH`ñ <r7   c                ó¦  aa€ ^ RI o^ RIoR V3R llpR R lp\        RRRR	7        V! \         R
2^4      oT3R lR' 4       w  rET'       d	   T'       g   T! RSR4      # \        R4       \
         SP                  P                  T4       2p ^ RIpTP                  4       pTP                  T4       TP                  RR7       TP                  RR7       \        RT 24       \        RRRR	7       \        P                  ! 4       T ,           p	\          RSP                  P                  T4       2p
\        P                  ! 4       T	8  Eda    T! T
^
4      p\        RRRR	7       TP'                  R4      ;'       g    / p\)        TP'                  R4      ;'       g    R4      P+                  4       R8w  d   \        P,                  ! \.        4       K¡  TP'                  R4      ;'       g    / p\)        TP'                  R 4      ;'       g    TP'                  R!4      ;'       g    R4      P1                  4       \)        TP'                  R"4      ;'       g    R4      P1                  4       rþT'       d   T'       d   \        4        R!TR"T/# \"        P3                  R#T4       \        R$4       R# \        R%T ^<,           R&24       R#   \         d   pT! RY34      u Rp?# Rp?ii ; i  \         d,    \        RT R24       \        R\        R4       R24        EL7i ; i  \         d$   p\"        P%                  RT4       / p Rp?ELãRp?ii ; i)(z¸Fetch a WeCom QR code, render it, poll until scanned or timeout; ``{"bot_id", "secret"}`` or None.
The ``ai/qc/*`` endpoints back the admin console, not the public API, and may change.Nc               ó$   € V ^8„  d   QhRRRRRR/# )r0   ÚurlrC   r+  rK  r1   rh   r3   )r4   s   "r5   r6   Ú*qr_scan_for_bot_info.<locals>.__annotate__Œ  s!   € ÷ ;ñ ;�sð ; Sð ;¨^ñ ;r7   c                ó.  <€ SP                   P                  V R R/R7      pSP                   P                  W!R7      ;_uu_ 4       p\        P                  ! VP                  4       P                  R4      4      uuRRR4       #   + '       g   i     R# ; i)z
User-AgentzHermesAgent/1.0)r.  rH  rr  N)ÚrequestÚRequestÚurlopenrÁ  rÂ  Úreadrz  )r¢  r+  ÚreqÚrespÚurllibs   &&  €r5   Ú	_get_jsonÚ'qr_scan_for_bot_info.<locals>._get_jsonŒ  sh   ø€ Ø�n‰n×$Ñ$ S°<ÐARÐ2SÐ$ÓTˆØ�^‰^×#Ñ# CÐ#×9Ô9¸TÜ—:’:˜dŸi™i›k×0Ñ0°Ó9Ó:÷ :×9×9Ó9ús   Á3BÂB	c               ó(   € V ^8„  d   QhRRRRRRRR/# )r0   r×   rC   Údetailr   Úshownr1   rÿ   r3   )r4   s   "r5   r6   r£  ‘  s(   € ÷ #ñ #�sð # Cð #°ð #¸ñ #r7   c                óL   € \         P                  W4       \        R V 24       R# rX  )rÝ   rö   Úprint)r×   r¯  r°  s   &&&r5   Ú_failÚ#qr_scan_for_bot_info.<locals>._fail‘  s   € Ü�‰�WÔ%Ü�	˜%˜Ð!Ö"r7   z  Connecting to WeCom...rR   T)ÚendÚflushz?source=hermesz%WeCom QR: failed to fetch QR code: %sc              3  óº   <"  € T FP  p\        SP                  R 4      ;'       g    / P                  V4      ;'       g    R4      P                  4       x € KR  	  R# 5i)rQ  rR   N)rC   rk   rD   )rE   rŠ   rP   s   & €r5   rG   Ú'qr_scan_for_bot_info.<locals>.<genexpr>š  sG   øé € ÐhÑRgÈQ”s˜CŸG™G F›O×1Ð1¨r×6Ñ6°qÓ9×?Ð?¸RÓ@×FÑF×HÐHÓRgùs   ƒ!A¥A¾Az(WeCom QR: unexpected response format: %szunexpected response formatz done.
)Úfit)Úinvertz8
  Scan the QR code above, or open this URL directly:
  z+  Open this URL in WeCom on your phone:

  r  z)  Tip: from the Hermes environment, run: Ú	messagingz. to display a scannable QR code here next timez$
  Fetching configuration results...z?scode=Ú.zWeCom QR poll error: %srQ  Ústatusrn  Úbot_infoÚbotidr�   r’   zFWeCom QR: scan reported success but bot_info missing or incomplete: %szµ
  QR scan reported success but no bot credentials were returned.
  This usually means the bot was not actually created on the WeCom side.
  Falling back to manual credential entry.z
  QR scan timed out (z minutes). Please try again.)ÚscodeÚauth_url)Úurllib.requestÚurllib.parser²  Ú_QR_GENERATE_URLrõ   Ú_QR_CODE_PAGEÚparser  ÚqrcodeÚQRCodeÚadd_dataÚmakeÚprint_asciir   rJ  Ú	monotonicÚ_QR_QUERY_URLrÝ   rT  rk   rC   r_   rb  Ú_QR_POLL_INTERVALrD   rÞ   )rž  r¬  r³  rú   rÀ  rÁ  Úpage_urlÚ_qrcodeÚqrrZ  Ú	query_urlÚresultÚresult_datar¾  r�   r’   rP   r«  s   $               @@r5   Úqr_scan_for_bot_inforÕ  †  s÷  ù€ ó Û÷;ð ;õ
#ô 
Ð
$¨"°DÕ9ðHÙÔ+Ð,¨NÐ;¸RÓ@ˆô iÑRgÓh�O€EßŸÙÐ?ÀÐFbÓcÐcÜ	ˆ*ÔÜ� §¡×!3Ñ!3°EÓ!:Ð ;Ð<€Hð?Û Ø�^‰^ÓˆØ
�‰�HÔØ
�‰�DˆÔØ
�‰˜dˆÔ#ÜÐJÈ8È*ÐUÔVô 
Ð
1°rÀÕFÜ�~Š~Ó /Õ1€HÜ �/ ¨¯©×);Ñ);¸EÓ)BÐ(CÐD€IÜ
�.Š.Ó
˜XÕ
%ð	Ù˜y¨"Ó-ˆFÜ�#˜2 TÕ*ð —j‘j Ó(×.Ð.¨BˆÜˆ{�‰˜xÓ(×.Ð.¨BÓ/×5Ñ5Ó7¸9ÔDÜ�JŠJÔ(Ô)ÙØ—?‘? :Ó.×4Ð4°"ˆÜ˜XŸ\™\¨'Ó2×RÐR°h·l±lÀ8Ó6L×RÐRÐPRÓS×YÑYÓ[Ô]`Ðai×amÑamÐnvÓaw×a}Ða}Ð{}Ó]~÷  ^Eñ  ^Eó  ^G�ß—fÜŒGØ˜f h°Ð7Ð7Ü�‰Ð_ÐalÔmÜð  Iô  	JÙÜ	Ð# O°rÕ$9Ð#:Ð:VÐ
WÔXÙøôU ô HÙÐ<¸cÓGÕGûðHûô ô ?ÜÐ=¸h¸ZÀrÐJÔKÜÐ9Ü˜kÓ*Ð+ð ,>ð>÷ 	?ð?ûô ô 	Ü�L‰LÐ2°CÔ8ØŽFûð	úsH   ©K ÂAK) ÅL" ËK&ËK!ËK&Ë!K&Ë)2LÌLÌ"MÌ-MÍMc               ó   € V ^8„  d   QhRR/# )r0   r  r2   r3   )r4   s   "r5   r6   r6   Å  s   € ÷ <ñ <¸ñ <r7   c             ƒ  ó$  "  €  V P                  W4      G R j  x€L
 pTP                  '       d   RRRRRTRTP                  /# \        RTP
                   24      #  LB  \         d&   p\        T'       d   RT 2MRT 24      u R p?# R p?ii ; i5i)	Nz WeCom live adapter send failed: úWeCom send failed: rn  TÚplatformÚwecomrÔ  rØ  )r|  rõ   r   rn  rØ  rö   )ÚadapterrÔ  rÖ   r  rÓ  r`   s   &&&$  r5   Ú	_send_viarÜ  Å  s“   é € ðiØ—|‘| GÓ5×5ˆð ‡~‡~€~Ø˜4 ¨W°iÀÈ,ÐX^×XiÑXiÐjÐjÜÐ+¨F¯L©L¨>Ð:Ó;Ð;ñ 6øÜô iÜÇDÐ<¸Q¸CÑ@ÐPcÐdeÐcfÐNgÓhÕhûðiüsH   ‚B„A ˜A™A �B¯,BÁA ÁBÁ(BÂBÂBÂBÂBÚ	thread_idÚmedia_filesÚforce_documentFc             ƒ  óh  "  €  ^ RI Hp V! \        P                  4      w  rxVe   \        W�VRR7      G Rj  x€L
 # \        4       '       g   \        R4      #  \        V 4      pVP                  4       G Rj  x€L
 '       g$   \        R\        VRR4      ;'       g    R 24      #  \        W�VR	R7      G Rj  x€L
 VP                  4       G Rj  x€L
  #   \         d    Rp LÀi ; i L® Lq L3 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)u_  Reuse the live gateway adapter in-process, else connect ephemerally (WeCom allows ONE
WebSocket per bot â€” a second connection kicks the first). The live adapter is the ACTIVE
PROFILE's (``_live_adapter``): a bare ``runner.adapters`` hit is the default profile's bot under
multiplex, so a secondary profile's send would leave with the wrong identity.)Ú_live_adapterNT)r  z?WeCom requirements not met. Need aiohttp + WECOM_BOT_ID/SECRET.zWeCom: failed to connect - Úfatal_error_messagerR  FrØ  )Útools.send_message_sendersrá  r   ru   rõ   rÜ  r<   r   rt   rû   r  r  )
ÚpconfigrÔ  rÖ   rÝ  rÞ  rß  rá  Ú_rÛ  r`   s
   &&&$$$    r5   Ú_standalone_sendræ  Ï  s  é € ð
Ý<Ù"¤8§>¡>Ó2‰
ˆð ÒÜ˜w°¸tÔD×DÐDÜ#×%Ò%ÜÐ[Ó\Ð\ð	5Ü˜wÓ'ˆØ—_‘_Ó&×&Ö&ÜÐ ;¼GÀGÐMbÐdhÓ<i×<|Ð<|Ðm|Ð;}Ð~ÓÐð	'Ü" 7°WÀ5ÔI×Ià×$Ñ$Ó&×&Ñ&øô ô ØŠðúñ Eñ
 'ñ Já&ø�'×$Ñ$Ó&×&Ò&ûÜô 5ÜÐ/°¨sÐ3Ó4Õ4ûð5üsÍ   ‚D2„C ¢D2·C&¸D2ÁD Á6C(Á7	D ÂD ÂD Â#D2Â%C. Â6C*Â7C. Â:D ÃC,ÃD ÃD2ÃC#Ã D2Ã"C#Ã#D2Ã(D Ã*C. Ã,D Ã.D	ÄDÄD	Ä	D ÄD/ÄD*Ä$D/Ä%D2Ä*D/Ä/D2c               ó   € V ^8„  d   QhRR/# rþ   r3   )r4   s   "r5   r6   r6   ú  s   € ÷ 7,ñ 7,˜4ñ 7,r7   c            
     ó  € ^ RI Hp Hp ^ RIHp ^ RIHpHpHpH	pH
p ^ RIHp V! R4       V! RRR4      '       d   R	# V! R
RR.^ 4      p	R	;r«V	^ 8X  dd    \        4       ;'       g    / pT'       d,   TP!                  RR4      TP!                  RR4      rºT! R4       T
'       d	   T'       g   T! R4       R	;r«V
'       d	   V'       g_   \"         F  pV! V4       K  	  . pR( F=  w  ppVP%                  V! VVR7      4       VR),          '       d   K0  V! RV R24        R	# 	  Vw  r«V! RV
4       V! RV4       V! R4       V! R4       V! RRR7      pV'       d#   V! RVP'                  RR4      4       V! R4       MtT! R\(         UUu. uF	  w  p pVNK  	  upp^4      p\(        VR*9   d   TM^,          w  pppV F  w  ppV! VV4       K  	  V F  w  ppR VR!VR"V/V,          ! V4       K  	  V! R#RR7      P+                  4       ;p'       d   V! R$V4       V! R%V 24       MV ! R$4      '       d	   V! R&4       V! R'4       R	#   \         d    T! R4        R	# \         d   pT! RT 24       / p R	p?ELR	p?ii ; iu uppi )+r6  )Úremove_env_valueÚsave_env_value)Úprompt_choice)ÚpromptÚprint_headerÚ
print_infoÚprint_successÚprint_warning)Údeclines_reconfigureúWeCom (Enterprise WeChat)ÚWeComzReconfigure WeCom?r‘   Nz#How would you like to set up WeCom?zDScan QR code to obtain Bot ID and Secret automatically (recommended)z)Enter existing Bot ID and Secret manuallyzWeCom setup cancelled.zQR scan failed: r�   rR   r’   u3   âœ” QR scan successful! Bot ID and Secret obtained.z7QR scan did not complete. Continuing with manual input.F)Úpasswordu'   Skipped â€” WeCom won't work without a r¼  r“   z5The gateway DENIES all users by default for security.z6Enter user IDs to create an allowlist, or leave empty.z,Allowed user IDs (comma-separated, or empty)rœ   Ú u5   Saved â€” only these users can interact with the bot.z)How should unauthorized users be handled?rÞ   rn  ró   z/Home chat ID (optional, for cron/notifications)ÚWECOM_HOME_CHANNELzHome channel set to zHome channel cleared.u   ðŸ’¬ WeCom configured!))zBot IDF)ÚSecretTrw  )r6  r¿  r0   )Úhermes_cli.configré  rê  Úhermes_cli.setuprë  Úhermes_cli.cli_outputrì  rí  rî  rï  rð  Úhermes_cli.setup_platformsrñ  rÕ  ÚKeyboardInterruptrõ   rk   Ú_MANUAL_SETUP_STEPSÚappendrs  Ú_ACCESS_CHOICESrD   )ré  rê  rë  rì  rí  rî  rï  rð  rñ  Ú
method_idxr�   r’   Úcredentialsrú   ÚlineÚcredsÚlabelrô  rþ  rå  Ú
access_idxÚsavesÚmessagesri   r>   ÚlevelrÖ   Úhomes                               r5   Úinteractive_setupr
  ú  s™  € ßBÝ.ßdÕdÝ?ÙÐ,Ô-Ù˜GÐ%9¸>×JÒJÙÙÐDð  HNð  P{ð  G|ð  ~ó  @€JØÐ€FØ�Q„ð	Ü.Ó0×6Ð6°BˆK÷ Ø(Ÿ_™_¨X°rÓ:¸K¿O¹OÈHÐVXÓ<Y�FÙÐOÔPßŸVÙÐPÔQØ"Ð"ˆFßŸß'ˆDÙ�tÖñ (àˆÛD‰OˆE�8Ø�L‰L™ °Ô9Ô:Ø˜—9–9ÙÐ GÈÀwÈaÐPÔQÚñ	  Eð
 ‰ˆÙ�> 6Ô*Ù�> 6Ô*ÙÐFÔGÙÐGÔHÙÐCÈeÔT€GßÙÐ,¨g¯o©o¸cÀ2Ó.FÔGÙÐMÕNá"Ð#NÕjyÔPzÑjyÑ[fÐ[`ÐbcÐefÓQVÑjyÒPzÐ|}Ó~ˆ
Ü,¸:ÈÔ;R©ZÐXYÕZÑˆˆ5�(Û‰JˆC�Ù˜3 Ö&ñ  ã&‰NˆE�7Ø˜ y°-ÀÈÐTÐUZÖ[Ð\cÖdñ 'áÐGÐRWÔX×^Ñ^Ó`Ð`€tÖ`ÙÐ+¨TÔ2ÙÐ,¨T¨FÐ3Õ4Ù	Ð.×	/Ò	/ÙÐ*Ô+ÙÐ*Ö+øôU !ô 	ÙÐ2Ô3ÚÜô 	ÙÐ,¨S¨EÐ2Ô3ØŽKûð	üó8 Q{s0   ÁI Á%I ÆI>ÉI;ÉI;É"I;É#I6É6I;c               ó   € V ^8„  d   QhRR/# r/   r3   )r4   s   "r5   r6   r6   4  s   € ÷ Dñ D˜Tñ Dr7   c                ó`   € \        \        V R / 4      ;'       g    / P                  R4      4      # )r�   r�   )r2   r  rk   )rw   s   &r5   Ú_is_connectedr  4  s)   € Ü”˜ ¨"Ó-×3Ð3°×8Ñ8¸ÓBÓCÐCr7   c               ó   € V ^8„  d   QhRR/# r/   r3   )r4   s   "r5   r6   r6   8  s   € ÷ ;ñ ; dñ ;r7   c                ó–   € \        V R/ 4      ;'       g    / p\        VP                  R4      ;'       g    VP                  R4      4      # )z3Callback mode: corp_id or a multi-app `apps` block.r�   Úcorp_idÚapps)r  r2   rk   )rw   r�   s   & r5   Ú_callback_is_connectedr  8  s=   € ä�F˜G RÓ(×.Ð.¨B€EÜ�—	‘	˜)Ó$×9Ð9¨¯	©	°&Ó(9Ó:Ð:r7   c                ó   € ^ RI Hp V! V 4      # )r6  )ÚWecomCallbackAdapter)Ú(plugins.platforms.wecom.callback_adapterr  )rw   r  s   & r5   Ú_build_callback_adapterr  ?  s   € ÝMÙ Ó'Ð'r7   u­  You are on WeCom (ä¼�ä¸šå¾®ä¿¡). Markdown is supported. You can send files natively: write MEDIA:/absolute/path/to/file in your response. Images (.jpg, .png, .webp) send as photos (â‰¤10 MB), other files as documents (â‰¤20 MB), videos (.mp4) play inline. Voice messages must be AMR â€” other audio formats send as file attachments. Image URLs via ![alt](url) are downloaded and sent as photos. Never claim you lack file-sending.c               ó   € V ^8„  d   QhRR/# rþ   r3   )r4   s   "r5   r6   r6   N  s   € ÷ )ñ )�Tñ )r7   c                óF  € \        R RRR7      p^RIHp V P                  ! R2/ R\        bR\        RR7      bRR	bR
RbR\        bR\        bRRbRRbRRbRR3bRR4bR\        bR\        bRRR.bR\        bRRbR\        bRR bVBR!\        R"R#R$R%R/R&VP                  R'VP                  /BVP                  B  ^ R(IHpHp V P                  ! R2RR)R
R*R\$        RR+RR,RR-RR5RR6RVR0VR\&        R\&        RR.R/./VBR"R#R&VP(                  R'VP*                  /BVP,                  B  R1# )7z,Run `hermes setup` to install WeCom support.u   ðŸ’¼T)r   ÚemojiÚallow_update_command)Úgateway_envÚtarget_ref_syntax_fnÚstandalone_send)Útext_directrß   rÚ  r  rò  Úadapter_factoryÚcheck_fnÚdashboard_labelzWeCom (group bot)Údashboard_descriptionz&Send-only WeCom group bot via webhook.Údocs_urlz8https://developer.work.weixin.qq.com/document/path/91770Údashboard_env_varsr‘   r“   Údashboard_required_envÚis_connectedÚvalidate_configÚrequired_envÚsetup_fnÚcron_deliver_env_varrö  Ústandalone_sender_fnÚmax_message_lengthr-   Úplatform_hintÚdisplay_tierÚlowÚdisplay_overridesÚ	streamingÚenv_overridesÚenv_enable_credentials)Ú!check_wecom_callback_requirementsÚ"ensure_wecom_callback_requirementsÚwecom_callbackz WeCom Callback (self-built apps)zWeCom (app)z+Two-way WeCom integration via callback app.z8https://developer.work.weixin.qq.com/document/path/90930ÚWECOM_CALLBACK_CORP_IDÚWECOM_CALLBACK_CORP_SECRETÚensure_deps_fnNr3   )r‘   r“   )r‘   )r7  r8  ÚWECOM_CALLBACK_AGENT_IDÚWECOM_CALLBACK_TOKENÚWECOM_CALLBACK_ENCODING_AES_KEY)r7  r8  r:  )rl   rR   r  Úregister_platformr   r   rt   r<   r  r
  ræ  Ú_WECOM_PLATFORM_HINTÚENV_OVERRIDESÚENV_ENABLE_CREDENTIALSÚAUTHZr  r4  r5  r  r  ÚCALLBACK_ENV_OVERRIDESÚCALLBACK_ENV_ENABLE_CREDENTIALSÚCALLBACK_AUTHZ)ÚctxÚcommonr  r4  r5  s   &    r5   ÚregisterrG  N  s%  € ÜÐMÐU[ÐrvÔw€FÝØ×Òò Ý+ðä,¸Õ>ðñ ðñ 8ðõ JVðõ ayðñ ,ð	ñ
 Gðñ Lðñ <ðñ  1ðõ #ðõ 5Bðð R`ÐaoÑPpðõ #ðñ 2ðõ IYðñ nrÐu{ñô +ðð ðð '¨Ð-ðð  "×/Ñ/ð!ð"  +×AÑAñ#ð" FQ×EVÑEVò#÷& Ø×Òñ ØðØ%GðÜYpðà%ðð Lðð Lð	ð

ðð 
ðð 3ðð Dfðô ,ðô >Tðð /Ð0LÐMðð RXñð ðð  "×8Ñ8ð!ð"  +×JÑJñ#ð" OZ×NhÑNhô#r7   )r0   é   é
   é   é<   )uO   1. Go to WeCom Application â†’ Workspace â†’ Smart Robot -> Create smart robotsz2. Select API Modez=3. Copy the Bot ID and Secret from the bot's credentials infou?   4. The bot connects via WebSocket â€” no public endpoint needed))z/Enable open access (anyone can message the bot)))r˜   Úopen)ÚGATEWAY_ALLOW_ALL_USERSÚtrue))rÞ   u0   Open access enabled â€” anyone can use your bot!)zXUse DM pairing (unknown users request access, you approve with 'hermes pairing approve')))r˜   r™   ))rn  u@   DM pairing mode â€” users will receive a code to request access.)ró   z6Approve with: hermes pairing approve <platform> <code>)zDisable direct messages))r˜   Údisabled))rÞ   zDirect messages disabled.)z7Skip for now (bot will deny all users until configured)r3   ))ró   u7   Skipped â€” configure later with 'hermes gateway setup')ir’  Ú
__future__r   Úpmr   rï   rÁ  ÚloggingrT   rJ  rÄ   r   r   r   Útypingr   r   r	   r
   r   rå   ÚImportErrorræ   r:   r;   Úgateway.configr   r   rì   r   r   r   Ú%gateway.platforms.access_policy_mixinr   Úgateway.platforms.baser   r   r   Úgateway.platforms.eventr   r   Úutilsr   Úgateway.platforms._sharedr   r�   r   Úgateway.platforms.send_targetsr   r   Ú"plugins.platforms.wecom.send_queuer   Úplugins.platforms.wecom.mediar   r   Ú!plugins.platforms.wecom.streamingr   r    r!   r"   r#   r$   r%   r&   r'   Ú	getLoggerrŽ  rÝ   r­   r@  ÚAPP_CMD_CALLBACKÚAPP_CMD_LEGACY_CALLBACKrŽ  rR  rŒ  rˆ  r_  r=  r™  r<  rc  r»   r<   rN   rW   rd   rn   rr   rt   rÄ  rÍ  rÅ  rÎ  Ú_QR_POLL_TIMEOUTrÕ  rÜ  ræ  rý  rÿ  r
  r  r  r  r>  rG  r3   r7   r5   Ú<module>rc     sì  ðñ2õ #å Û Û Û Û 	Û Û ß ,Ñ ,ß 3Õ 3ðÛðÛð  4Ð'Ð Ø˜tÐ#€ç 3ß SÑ SÝ Fß UÑ Uß =Ý ç Yß OÝ Aß G÷÷ õ ð 
×	Ò	˜8Ó	$€à2€à%Ð Ø'Ð Ø*Ð Ø/Ð Ø€à%Ð'>Ð?Ð Ø)Ð-CÐ,DÕDÐ àÐ ØÐ ØÐ Ø!Ð Ú&Ð à€õ1õLõMõYõNõLôVoÐ# _Ð6HÐJ^Ð`sô Voðr ?Ð Ø?€ØK€Ø&'¨Ð #Ð Ð#ð<Ð3C÷ <õ~<ð5À4ð 5ÐUYð 5Ðjoô 5ð4Ð ð€õ7,õtDõ;ò(ðað ÷)øðs ô ØƒGðûð ô ØƒEðús$   Á E+ ÁE; Å+	E8Å7E8Å;	FÆF