+
    kHàj-s ã                  óØ  a€ 0 t $ 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t^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHtHt ^ RIHt ^ RIHt ^ RIHt ^ R	IH t H!t!H"t"H#t#H$t$H%t% ^ R
I&H't'H(t( ^ RI)H*t* ^ RI+H,t,H-t-  ^ RI.t.^ RI.H/t/  ^ RI1t1ERt2R;t3t4]5! 4       Pm                  ]2 U UUu/ uF  w  rV F  q"RbK  	  K  	  uppp 4       Rt7]Pp                  ! 4       t9]1RJt:].RJt;^ RI<H=t=H>t> ^ RI?H@t@ ^ RIAHBtBHCtCHDtDHEtEHFtFHGtGHHtHHItI ^ RIJHKtKHLtLHMtM ^ RINHOtO ^ RIPHQtQ ^ RIRHStS ^ RITHUtUHVtVHWtW ^ RIXHYtZH[t\H]t^H_t_ ]PÀ                  ! ]a4      tb]PÆ                  ! R]PÈ                  4      te]PÆ                  ! R4      tf]PÆ                  ! R4      tg]PÆ                  ! R4      th]PÆ                  ! R4      ti]PÆ                  ! R]PÔ                  4      tk0 ERmtl0 ERmtm0 ERmtn]EPÞ                  ! 4        UUu/ uF  w  r4WCbK	  	  upptpR tqR!trRR0ts0 ERmttR"R#R$R%R&R%R'R(R)R(R*R+R,R+/tuERtv^tw^txR.tyR/tz^t{R0t|R1t}R2t~R3tR4t€R5t�ERt‚ERtƒERt„^<t…^xt†R6t‡^tˆ^t‰ERtŠER t‹R7R8R9R:R;R<R=R=/tŒR>]�R?&   R8R@R:RAR<RBR=RC/tŽR>]�RD&   RE RF lt�]�! RGRH04      t‘RIt’RJt“R-t”RKt•RLRMRNRO/t–RLRPRNRQ/t—RRt˜^
t™RStšRTt›RUtœRVt�RWtžRXtŸER!t ]PÆ                  ! RY4      t¡]PÆ                  ! RZ4      t¢]�! R[4      t£]�! R\4      t¤]PÆ                  ! R]4      t¥ER"t¦0 ER#mt§0 ER$mt¨]! R^R_7       ! R` Ra4      4       t©]! R^R_7       ! Rb Rc4      4       tª]! R^R_7       ! Rd Re4      4       t«]! R^R_7       ! Rf Rg4      4       t¬]! R^R_7       ! Rh Ri4      4       t­]! R^R_7       ! Rj Rk4      4       t®] ! Rl Rm4      4       t¯] ! Rn Ro4      4       t°]#ER%,          t±Rp Rq lt²Rr Rs lt³Rt Ru lt´Rv Rw ltµRx Ry lt¶Rz R{ lt·R| R} lt¸ER&t¹R~ R ltºR€ R� lt»R‚ Rƒ lt¼ER'R„ R… llt½ER(R† R‡ llt¾Rˆ R‰ 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–R—R˜R™R˜/tÅER)Rš R› lltÆRœ R� ltÇER)Rž RŸ lltÈR RR¡]«! 4       /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ÀER*/RÁ RÂ lltØE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Þ]Pp                  ! 4       tßRsà]EPÂ                  ! 4       tâ ! RÏ RÐ4      tãRÑ RÒ ltäRÓ RÔ ltåRÕ RÖ ltæR× RØ 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/Rå Ræ lltíRç Rè ltî ! Ré Rê]B4      tïRë Rì ltðRí Rî ltñRï Rð ltòER+Rñ Rò lltóER+Ró Rô lltôRõRL/Rö R÷ lltõ ^ RIöt÷Rø Rù ltùRú Rû ltúRü Rý ltûRþ Rÿ ltüER  ER ltýER ER ltþERRLERER/ER ER lltÿER	 ER
 lEt 0 ER,mEt0 ER-mEt0 ER.mEtERRERRERR/ER lEtER ER lEtER ER lEtER ER lEtER ER lEtR#   ]0 d	    Rt.Rt/ ELši ; i  ]0 d    Rt1 EL¥i ; iu uppp i u uppi   ]0]ø3 d    Rt÷ LÆi ; i(/  u  
Feishu/Lark platform adapter.

Supports WebSocket + Webhook transports, DM/@mention-gated group text, inbound
media caching, FEISHU_ALLOWED_USERS allowlisting, persistent dedup, per-chat
serial processing, processing-status reactions (Typing while working, CrossMark
on failure), reaction/card-button events as synthetic events, webhook anomaly
tracking and verification-token validation (all mirroring openclaw).

Feishu identity model (https://open.feishu.cn/document/home/user-identity-introduction/introduction):
  open_id  (ou_xxx) â€” app-scoped; differs per Feishu app; always in event payloads.
  user_id  (u_xxx)  â€” tenant-scoped; needs ``contact:user.employee_id:readonly``; may be absent.
  union_id (on_xxx) â€” developer-scoped; stable across one developer's apps.
Bot: ``app_id`` is the credential; the bot's own open_id (from ``/bot/v3/info``) is
what Feishu puts in ``mentions[].id.open_id`` â€” used for mention gating only.
Session keys prefer union_id (user_id_alt) over open_id (user_id) for stability.
)Úannotations)Úinstall_hintN)ÚOrderedDict)Ú	dataclassÚfield)Údatetime)ÚPath)ÚSimpleNamespace)ÚAnyÚDictÚListÚLiteralÚOptionalÚSequence)Ú	HTTPErrorÚURLError)Ú	urlencode)ÚRequestÚurlopen)ÚwebF)ÚPlatformÚPlatformConfig©Út)ÚBasePlatformAdapterÚExecApprovalPromptÚ
SendResultÚSUPPORTED_DOCUMENT_TYPESÚcache_document_from_bytes_asyncÚcache_image_from_urlÚcache_audio_from_bytes_asyncÚcache_image_from_bytes_async)ÚMessageEventÚMessageTypeÚProcessingOutcome)Úacquire_scoped_lock)Úrelease_scoped_lock)Úget_hermes_home)Úatomic_json_writeÚ	env_floatÚenv_int)Úapply_yaml_bridgeÚextra_or_secretÚget_scoped_secretÚ
send_errorz¾(^\|.*\|\s*\n\|[-:|\s]+\|)|(^#{1,6}\s)|(^\s*[-*]\s)|(^\s*\d+\.\s)|(^\s*---+\s*$)|(```)|(`[^`\n]+`)|(\*\*[^*\n].+?\*\*)|(~~[^~\n].+?~~)|(<u>.+?</u>)|(\*[^*\n]+\*)|(\[[^\]]+\]\([^)]+\))|(^>\s)z\[([^\]]+)\]\(([^)]+)\)z^```([^\n`]*)\s*$z^```\s*$z	[ \t]{2,}z,content format of the post type is incorrectú.oggú.opusÚmessageÚstreamz.pdfÚpdfz.docÚdocz.docxz.xlsÚxlsz.xlsxz.pptÚpptz.pptxi   zfeishu-app-idg333333ã?é   gš™™™™™é?i   z	127.0.0.1i="  z/feishu/webhooki   Úapprove_onceÚonceÚapprove_sessionÚsessionÚapprove_alwaysÚalwaysÚdenyúdict[str, str]Ú_APPROVAL_CHOICE_MAPz&platform.feishu.approval.resolved_oncez)platform.feishu.approval.resolved_sessionz(platform.feishu.approval.resolved_alwaysz&platform.feishu.approval.resolved_denyÚ_APPROVAL_LABEL_KEYSc               ó$   € V ^8„  d   QhRRRRRR/# )é   Úrequestr
   Ú	max_bytesÚintÚreturnÚbytes© )Úformats   "ÚE/home/ubuntu/.hermes/hermes-agent/plugins/platforms/feishu/adapter.pyÚ__annotate__rL   ³   s!   € ÷ ñ °Sð ÀSð ÈUñ ó    c              ƒ  óú   "  €  V P                   P                  V^,           4      G Rj  x€L
 p\        V4      V8”  d   \        R4      hV#  L!  \        P                   d   pTP                  p Rp?LERp?ii ; i5i)z8Read at most ``max_bytes`` from an aiohttp request body.Nzpayload too large)ÚcontentÚreadexactlyÚasyncioÚIncompleteReadErrorÚpartialÚlenÚ
ValueError)rD   rE   ÚbodyÚexcs   &&  rK   Ú!_read_limited_feishu_webhook_bodyrX   ³   sh   é € ðØ—_‘_×0Ñ0°¸QµÓ?×?ˆô ˆ4ƒy�9ÔÜÐ,Ó-Ð-Ø€Kñ @øÜ×&Ñ&ô Ø�{‰{�ûðüs=   ‚A;„%A ©AªA ®A;ÁA ÁA8Á"A3Á.A;Á3A8Á8A;i{‚ i[† ÚTypingÚ	CrossMarki   Úfeishuzhttps://accounts.feishu.cnÚlarkzhttps://accounts.larksuite.comzhttps://open.feishu.cnzhttps://open.larksuite.comz/oauth/v1/app/registrationz[Rich text message]z[Merged forward message]z[Shared chat]z[Interactive message]ú[Image]ú[Attachment]z([\\`*_{}\[\]()#+\-!|>~])z
@_user_\d+u*    	
.,;:!?ã€�ï¼Œã€‚ï¼›ï¼šï¼�ï¼Ÿ()[]{}<>"'`u    	
.!?ã€‚ï¼�ï¼Ÿz\s+T)Úfrozenc                  ó>   € ] tR t^ðt$ R]R&   RtR]R&   RtR]R&   RtR# )	ÚFeishuPostMediaRefÚstrÚfile_keyÚ Ú	file_nameÚfileÚresource_typerI   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotations__re   rg   Ú__static_attributes__rI   rM   rK   ra   ra   ð   s   ‡ àƒMØ€IˆsÓØ€M�3×rM   ra   c                  óP   € ] tR t^÷t$ RtR]R&   RtR]R&   RtR]R&   RtR]R&   R	t	R
# )ÚFeishuMentionRefrd   rb   ÚnameÚopen_idFÚboolÚis_allÚis_selfrI   N)
rh   ri   rj   rk   rp   rl   rq   rs   rt   rm   rI   rM   rK   ro   ro   ÷   s)   ‡ à€Dˆ#ƒNØ€GˆSÓØ€FˆDÓØ€GˆT×rM   ro   c                  óN   € ] tR t^ÿt$ RtR]R&   RtR]R&   RtR]R&   R R ltRt	R	# )
Ú_FeishuBotIdentityrd   rb   rq   Úuser_idrp   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   rq   rb   rw   rp   rG   rr   rI   )rJ   s   "rK   rL   Ú_FeishuBotIdentity.__annotate__  s(   € ÷ 5ñ 5 #ð 5°ð 5¸3ð 5À4ñ 5rM   c               	óø   € V'       d!   V P                   '       d   WP                   8H  # V'       d!   V P                  '       d   W P                  8H  # \        V P                  4      ;'       d    W0P                  8H  # ©N)rq   rw   rr   rp   )Úselfrq   rw   rp   s   &$$$rK   ÚmatchesÚ_FeishuBotIdentity.matches  sQ   € ÷ �t—|—|�|ØŸl™lÑ*Ð*ß�t—|—|�|ØŸl™lÑ*Ð*Ü�D—I‘I‹×4Ð4 4¯9©9Ñ#4Ð4rM   rI   N)
rh   ri   rj   rk   rq   rl   rw   rp   r}   rm   rI   rM   rK   rv   rv   ÿ   s)   ‡ à€GˆSÓØ€GˆSÓØ€Dˆ#ƒN÷5ñ 5rM   rv   c                  óZ   € ] tR tRt$ R]R&   ]! ]R7      tR]R&   ]! ]R7      tR]R&   R	t	R
# )ÚFeishuPostParseResulti  rb   Útext_content©Údefault_factoryú	list[str]Ú
image_keysúlist[FeishuPostMediaRef]Ú
media_refsrI   N)
rh   ri   rj   rk   rl   r   Úlistr…   r‡   rm   rI   rM   rK   r€   r€     s'   ‡ àÓÙ!°$Ô7€J�	Ó7Ù+0ÀÔ+F€JÐ(×FrM   r€   c                  ó¸   € ] tR tRt$ R]R&   R]R&   RtR]R&   ]! ]R7      tR]R	&   ]! ]R7      t	R
]R&   ]! ]R7      t
R]R&   RtR]R&   ]! ]R7      tR]R&   RtR# )ÚFeishuNormalizedMessagei  rb   Úraw_typer�   ÚtextÚpreferred_message_typer‚   r„   r…   r†   r‡   úlist[FeishuMentionRef]ÚmentionsÚplainÚrelation_kindúdict[str, Any]ÚmetadatarI   N)rh   ri   rj   rk   rl   r�   r   rˆ   r…   r‡   r�   r‘   Údictr“   rm   rI   rM   rK   rŠ   rŠ     s`   ‡ àƒMØÓØ"(Ð˜CÓ(Ù!°$Ô7€J�	Ó7Ù+0ÀÔ+F€JÐ(ÓFÙ',¸TÔ'B€HÐ$ÓBØ €M�3Ó Ù$°TÔ:€Hˆn×:rM   rŠ   c                  óˆ  € ] tR tRt$ RtR]R&   R]R&   R]R&   R]R&   R]R&   R]R	&   R]R
&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R&   ^tR]R&   ^xtR]R&   RtR]R&   Rt	R]R &   ]
! 4       tR]R!&   R"tR]R#&   ]! ]R$7      tR%]R&&   R'tR]R(&   R)tR*]R+&   R,tR*]R-&   R.tR# )/ÚFeishuAdapterSettingsi#  zUEvery field is mirrored onto the adapter as ``self._<field>`` by ``_apply_settings``.rb   Úapp_idÚ
app_secretÚdomain_nameÚconnection_modeÚencrypt_keyÚverification_tokenÚgroup_policyzfrozenset[str]Úallowed_group_usersÚbot_open_idÚbot_user_idÚbot_namerF   Údedup_cache_sizeÚfloatÚtext_batch_delay_secondsÚtext_batch_split_delay_secondsÚtext_batch_max_messagesÚtext_batch_max_charsÚmedia_batch_delay_secondsÚwebhook_hostÚwebhook_portÚwebhook_pathÚws_reconnect_nonceÚws_reconnect_intervalNúOptional[int]Úws_ping_intervalÚws_ping_timeoutÚadminsrd   Údefault_group_policyr‚   zdict[str, FeishuGroupRule]Úgroup_rulesÚnoneÚ
allow_botsTrr   Úrequire_mentionFÚallow_all_dmrI   )rh   ri   rj   rk   Ú__doc__rl   r¬   r­   r¯   r°   Ú	frozensetr±   r²   r   r”   r³   rµ   r¶   r·   rm   rI   rM   rK   r–   r–   #  sê   ‡ á_àƒKØƒOØÓØÓØÓØÓØÓØ'Ó'ØÓØÓØƒMØÓØ#Ó#Ø$)Ó)Ø Ó ØÓØ$Ó$ØÓØÓØÓØ Ð˜Ó Ø!$Ð˜3Ó$Ø&*Ð�mÓ*Ø%)€O�]Ó)Ù&›[€FˆNÓ(Ø "Ð˜#Ó"Ù.3ÀDÔ.I€KÐ+ÓIØ€J�ÓØ €O�TÓ Ø€L�$×rM   r–   c                  ól   € ] tR tRt$ RtR]R&   ]! ]R7      tR]R&   ]! ]R7      t	R]R&   R	t
R
]R&   RtR	# )ÚFeishuGroupRuleiG  zLPer-group policy rule for controlling which users may interact with the bot.rb   Úpolicyr‚   úset[str]Ú	allowlistÚ	blacklistNzOptional[bool]r¶   rI   )rh   ri   rj   rk   r¸   rl   r   Úsetr¾   r¿   r¶   rm   rI   rM   rK   r»   r»   G  s2   ‡ áVàƒKÙ°Ô4€IˆxÓ4Ù°Ô4€IˆxÓ4Ø&*€O�^×*rM   r»   c                  ól   € ] tR tRt$ ]! ]R7      tR]R&   ]! ]R7      tR]R&   ]! ]R7      t	R]R&   R	t
R
# )ÚFeishuBatchStateiQ  r‚   zdict[str, MessageEvent]Úeventsúdict[str, asyncio.Task]Útaskszdict[str, int]ÚcountsrI   N)rh   ri   rj   rk   r   r”   rÃ   rl   rÅ   rÆ   rm   rI   rM   rK   rÂ   rÂ   Q  s1   ‡ á&+¸DÔ&A€FÐ#ÓAÙ%*¸4Ô%@€EÐ"Ó@Ù"°4Ô8€FˆN×8rM   rÂ   c               ó    € V ^8„  d   QhRRRR/# )rC   Úsenderr
   rG   rr   rI   )rJ   s   "rK   rL   rL   ]  s   € ÷ @ñ @˜3ð @ 4ñ @rM   c                ó"   € \        V R R4      R9   # )Úsender_typerd   >   ÚappÚbot©Úgetattr)rÈ   s   &rK   Ú_is_bot_senderrÏ   ]  s   € ä�6˜=¨"Ó-°Ñ?Ð?rM   c               ó    € V ^8„  d   QhRRRR/# )rC   rÈ   r
   rG   r¹   rI   )rJ   s   "rK   rL   rL   b  s   € ÷ jñ j˜Sð j Yñ jrM   c                ór   a€ \        V R R4      oSf   \        4       # \        R V3R lR 4        4       4      # )Ú	sender_idNc              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir{   rI   ©Ú.0Úvs   & rK   Ú	<genexpr>Ú#_sender_identity.<locals>.<genexpr>g  s   é € ÐiÑ c˜1Ógh—Q’QÓ cùó   ‚	�
c              3  ó>   <"  € T F  p\        SVR 4      x € K  	  R # 5ir{   rÍ   )rÕ   ÚkÚsids   & €rK   r×   rØ   g  s   øé € Ð cÑ@b¸1¤¨¨a°×!6Ð!6Ó@bùó   ƒ©rq   rw   Úunion_id)rÎ   r¹   )rÈ   rÜ   s   &@rK   Ú_sender_identityrà   b  s6   ø€ ä
�&˜+ tÓ
,€CØ
‚{Ü‹{ÐÜÑiÔ cÑ@bÔ cÓiÓiÐirM   c               ó    € V ^8„  d   QhRRRR/# ©rC   rŒ   rb   rG   rI   )rJ   s   "rK   rL   rL   l  s   € ÷ 9ñ 9 ð 9¨ñ 9rM   c                ó.   € \         P                  R V 4      # )z\\\1)Ú_MARKDOWN_SPECIAL_CHARS_REÚsub)rŒ   s   &rK   Ú_escape_markdown_textræ   l  s   € Ü%×)Ñ)¨'°4Ó8Ð8rM   c               ó    € V ^8„  d   QhRRRR/# )rC   Úvaluer
   rG   rr   rI   )rJ   s   "rK   rL   rL   p  s   € ÷ :ñ :�sð :˜tñ :rM   c                ó>   € V R J ;'       g    V ^8H  ;'       g    V R8H  # )TÚtruerI   )rè   s   &rK   Ú_to_booleanrë   p  s$   € Ø�Dˆ=×9Ð9˜E Q™J×9Ð9¨%°6©/Ð9rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   Ústylezdict[str, Any] | NoneÚkeyrb   rG   rr   rI   )rJ   s   "rK   rL   rL   t  s"   € ÷ 'ñ 'Ð2ð '¸ð 'Àñ 'rM   c                óJ   € V '       g   R # \        V P                  V4      4      # ©F)rë   Úget)rí   rî   s   &&rK   Ú_is_style_enabledrò   t  s   € ßÙÜ�u—y‘y “~Ó&Ð&rM   c               ó    € V ^8„  d   QhRRRR/# râ   rI   )rJ   s   "rK   rL   rL   z  s   € ÷ #ñ #˜Cð # Cñ #rM   c           	     ó   € \        ^ .\        P                  ! RV 4       Uu. uF  p\        V4      NK  	  upO4      pRV^,           ,          pV P	                  R4      '       g   V P                  R4      '       d   RV  R2MT pV V V 2# u upi )é    z`+Ú`Ú )ÚmaxÚreÚfindallrT   Ú
startswithÚendswith)rŒ   ÚrunÚmax_runÚfencerV   s   &    rK   Ú_wrap_inline_coder   z  s†   € Ü�1ÐE¬B¯JªJ°u¸dÔ,CÓDÑ,C Sœ˜CžÑ,CÑDÐEÓF€GØ�7˜Q•;Õ€EØŸ/™/¨#×.Ò.°$·-±-À×2DÒ2DˆQˆtˆf�A‰;È$€DØˆW�T�F˜5˜'Ð"Ð"ùò Es   ¡B
c               ó    € V ^8„  d   QhRRRR/# )rC   Úlanguagerb   rG   rI   )rJ   s   "rK   rL   rL   �  s   € ÷ Bñ B sð B¨sñ BrM   c                ób   € V P                  4       P                  R R4      P                  RR4      # )Ú
r÷   Ú)ÚstripÚreplace)r  s   &rK   Ú_sanitize_fence_languager  �  s)   € Ø�>‰>Ó×#Ñ# D¨#Ó.×6Ñ6°t¸SÓAÐArM   c               ó    € V ^8„  d   QhRRRR/# ©rC   Úelementr’   rG   rb   rI   )rJ   s   "rK   rL   rL   ˆ  s   € ÷ ñ  .ð °Sñ rM   c                óN  € \        V P                  R R4      ;'       g    R4      pV P                  R4      p\        V\        4      '       d   TMRp\	        VR4      '       d   \        V4      # TpV'       g   R# \         F!  w  rVp\	        W54      '       g   K  V V V 2pK#  	  V# )rŒ   rd   rí   NÚcode)rb   rñ   Ú
isinstancer”   rò   r   Ú_TEXT_STYLE_WRAPPERS)r  rŒ   rí   Ú
style_dictÚrenderedrî   ÚprefixÚsuffixs   &       rK   Ú_render_text_elementr  ˆ  s˜   € Üˆw�{‰{˜6 2Ó&×,Ð,¨"Ó-€DØ�K‰K˜Ó €EÜ$ U¬D×1Ò1‘°t€JÜ˜ V×,Ò,Ü  Ó&Ð&ð €HßÙß3Ñˆ�VÜ˜Z×-Ô-Ø ˜ ( ¨F¨8Ð4ŠHñ  4ð €OrM   c               ó    € V ^8„  d   QhRRRR/# r
  rI   )rJ   s   "rK   rL   rL   š  s   € ÷ 9ñ 9¨ð 9¸3ñ 9rM   c                óÈ  € \        \        V P                  R R4      ;'       g    R4      ;'       g&    \        V P                  RR4      ;'       g    R4      4      p\        V P                  RR4      ;'       g    R4      ;'       g&    \        V P                  RR4      ;'       g    R4      P                  RR4      pVP	                  R4      '       d   RMRpRV RV V R2# )r  rd   ÚlangrŒ   rO   ú
r  ú```)r  rb   rñ   r  rü   )r  r  r  Útrailing_newlines   &   rK   Ú_render_code_block_elementr  š  sÉ   € Ü'¬¨G¯K©K¸
ÀBÓ,G×,MÐ,MÈ2Ó(N×(tÐ(tÔRUÐV]×VaÑVaÐbhÐjlÓVm×VsÐVsÐqsÓRtÓu€HÜ�—‘˜F BÓ'×-Ð-¨2Ó.×WÐW´#°g·k±kÀ)ÈRÓ6P×6VÐ6VÐTVÓ2W×`Ñ`ÐagÐimÓn€DØ!Ÿ]™]¨4×0Ò0‘r°dÐØ��
˜"˜T˜FÐ#3Ð"4°CÐ8Ð8rM   c               ó    € V ^8„  d   QhRRRR/# râ   rI   )rJ   s   "rK   rL   rL   ¡  s   € ÷ 	!ñ 	!¨ð 	!°ñ 	!rM   c                óp  € ^ RI Hp V P                  RR4      p\        P	                  R V4      p\
        P                  ! RRV\
        P                  R7      p\
        P                  ! RR	V\
        P                  R7      p\
        P                  ! R
RV4      p\
        P                  ! RRV4      pV! V4      # )z^Plain-text fallback: shared strip_markdown plus Feishu extras (blockquote, ~~, <u>, hr, CRLF).)Ústrip_markdownr  r  c                ój   € V P                  ^4       RV P                  ^4      P                  4        R2# )é   z (Ú))Úgroupr  )Úms   &rK   Ú<lambda>Ú/_strip_markdown_to_plain_text.<locals>.<lambda>¥  s,   € ¨q¯w©w°q«z¨l¸"¸Q¿W¹WÀQ»Z×=MÑ=MÓ=OÐ<PÐPQÑ,RrM   z^>\s?rd   )Úflagsz^\s*---+\s*$z---z~~([^~\n]+)~~z\1z<u>([\s\S]*?)</u>)Úgateway.platforms.helpersr  r  Ú_MARKDOWN_LINK_RErå   rù   Ú	MULTILINE)rŒ   r  r�   s   &  rK   Ú_strip_markdown_to_plain_textr*  ¡  sŠ   € å8Ø�L‰L˜ Ó&€EÜ×!Ñ!Ñ"RÐTYÓZ€EÜ�FŠF�8˜R ¬b¯l©lÔ;€EÜ�FŠF�? E¨5¼¿¹ÔE€EÜ�FŠFÐ# U¨EÓ2€EÜ�FŠFÐ'¨°Ó6€EÙ˜%Ó Ð rM   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   rè   r
   Údefaultr®   Ú	min_valuerF   rG   rI   )rJ   s   "rK   rL   rL   ­  s)   € ÷ 6ñ 6�sð 6 ]ð 6Àcð 6ÐR_ñ 6rM   c                ó`   €  \        V 4      pY28¼  d   T# T#   \        \        3 d    Tu # i ; i)zACoerce value to int with optional default and minimum constraint.)rF   Ú	TypeErrorrU   ©rè   r,  r-  Úparseds   &&& rK   Ú_coerce_intr2  ­  s=   € ðÜ�U“ˆð Ô(ˆ6Ð5¨gÐ5øô ”zÐ"ô ØŠðús   ‚ —-¬-c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   rè   r
   r,  rF   r-  rG   rI   )rJ   s   "rK   rL   rL   ¶  s(   € ÷ 1ñ 1 ð 1¨cð 1¸cð 1È#ñ 1rM   c                ó,   € \        WVR 7      pVf   V# T# )©r,  r-  )r2  r0  s   &&& rK   Ú_coerce_required_intr6  ¶  s   € Ü˜¸9ÔE€FØ’nˆ7Ð0¨&Ð0rM   c               ó    € V ^8„  d   QhRRRR/# ©rC   rO   rb   rG   rI   )rJ   s   "rK   rL   rL   ½  s   € ÷ Hñ H¨#ð H°#ñ HrM   c                óP   € \        V 4      p\        P                  ! R RV//RR7      # ©Úzh_cnrO   F©Úensure_ascii)Ú_build_markdown_post_rowsÚjsonÚdumps)rO   Úrowss   & rK   Ú_build_markdown_post_payloadrB  ½  s'   € Ü$ WÓ-€DÜ�:Š:�w ¨DÐ 1Ð2ÀÔGÐGrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rO   rb   rG   zlist[list[dict[str, str]]]rI   )rJ   s   "rK   rL   rL   Â  s   € ÷ !6ñ !6 sð !6Ð/Iñ !6rM   c                óÐ  aa€ V '       g	   RRRR/..# RV 9  d	   RRRV /..# . o. oRpR VV3R llpV P                  4        F‰  pV'       d   \        M\        p\        VP	                  VP                  4       4      4      pV'       d   V'       g   V! 4        SP                  V4       V'       g   Kq  V'       * pV'       d   K‚  V! 4        K‹  	  V! 4        S;'       g	    RRRV /..# )	zãBuild Feishu post rows, giving each fenced code block its own row.

Feishu's `md` renderer can swallow trailing content when a fence sits inside one
large element; splitting at real fence lines keeps surrounding prose visible.
ÚtagÚmdrŒ   rd   r  Fc               ó   € V ^8„  d   QhRR/# ©rC   rG   ÚNonerI   )rJ   s   "rK   rL   Ú/_build_markdown_post_rows.<locals>.__annotate__Ñ  s   € ÷ ñ ˜Dñ rM   c                 ó†   <€ R P                  S4      p V P                  4       '       d   SP                  RRRV /.4       . oR# )r  rE  rF  rŒ   N)Újoinr  Úappend)ÚsegmentÚcurrentrA  s    €€rK   Ú_flush_currentÚ1_build_markdown_post_rows.<locals>._flush_currentÑ  s9   ø€ à—)‘)˜GÓ$ˆØ�=‰=�?Š?Ø�K‰K˜%  v¨wÐ7Ð8Ô9ØŠrM   )Ú
splitlinesÚ_MARKDOWN_FENCE_CLOSE_REÚ_MARKDOWN_FENCE_OPEN_RErr   Úmatchr  rM  )rO   Úin_code_blockrP  Úraw_lineÚfence_reÚis_fencerO  rA  s   &     @@rK   r>  r>  Â  sá   ù€ ÷ Ø˜˜v rÐ*Ð+Ð,Ð,Ø�GÔØ˜˜v wÐ/Ð0Ð1Ð1à')€DØ€GØ€M÷ñ ð ×&Ñ&Ö(ˆß/<Õ+ÔBYˆÜ˜Ÿ™ x§~¡~Ó'7Ó8Ó9ˆßŸMÙÔØ�‰�xÔ ß‰8Ø -Ô-ˆMß ‘=ÙÖ ñ )ñ ÔØ×5Ð5�e˜T 6¨7Ð3Ð4Ð5Ð5rM   Úmentions_mapc               ó$   € V ^8„  d   QhRRRRRR/# )rC   Úpayloadr
   rZ  ú%Optional[dict[str, FeishuMentionRef]]rG   r€   rI   )rJ   s   "rK   rL   rL   æ  s$   € ÷ "ñ "Øð"Ø#Hð"àñ"rM   c               óÌ  aa	a
€ \        V 4      pV'       g   \        \        R 7      # . o	. o
. p\        \	        VP                  RR4      4      P                  4       4      pV'       d   VP                  V4       VP                  R. 4      ;'       g    .  F\  p\        V\        4      '       g   K  \        RP                  V	V
V3R lV 4       4      4      pV'       g   KK  VP                  V4       K^  	  VP                  R. 4      ;'       g    .  F™  p\        V\        4      '       dP   \        VP                  R4      4      '       g0   \	        VP                  RR4      4      P                  4       '       g   Kj  \        / VCRR	/CS	S
S4      pV'       g   Kˆ  VP                  V4       K›  	  \        R
P                  V4      P                  4       ;'       g    \        S	S
R7      # ))r�   Útitlerd   rO   c              3  ó@   <"  € T F  p\        VSSS4      x € K  	  R # 5ir{   )Ú_render_post_element©rÕ   Úitemr…   r‡   rZ  s   & €€€rK   r×   Ú,parse_feishu_post_payload.<locals>.<genexpr>ö  s#   øé € ÐeÑadÐY]Ô(¨¨z¸:À|×TÐTÓadùó   ƒÚfilesÚ	is_folderrc   rE  rf   r  )r�   r…   r‡   )Ú_resolve_post_payloadr€   ÚFALLBACK_POST_TEXTÚ_normalize_feishu_textrb   rñ   r  rM  r  rˆ   rL  r”   rë   ra  )r\  rZ  ÚresolvedÚpartsr_  ÚrowÚrow_textÚentryÚplaceholderr…   r‡   s   &d       @@rK   Úparse_feishu_post_payloadrq  æ  s‰  ú€ ô % WÓ-€HßÜ$Ô2DÔEÐEØ€JØ+-€JØ€EÜ"¤3 x§|¡|°G¸RÓ'@Ó#A×#GÑ#GÓ#IÓJ€EßØ�‰�UÔØ�|‰|˜I rÓ*×0Ð0¨bÒ0ˆÜ˜#œt×$Ò$ÙÜ)Ø�G‰GÖeÑadÓeÓeó
ˆ÷ ‰8Ø�L‰L˜Ö"ñ 1ð —‘˜g rÓ*×0Ð0¨bÒ0ˆä˜5¤$×'Ò'Ü˜5Ÿ9™9 [Ó1×2Ò2Ü�u—y‘y ¨RÓ0Ó1×7Ñ7×9Ò9áÜ*Ø$ˆuÐ$�e˜VÑ$ j°*¸ló
ˆ÷ ‰;Ø�L‰L˜Ö%ñ 1ô !Ø—Y‘Y˜uÓ%×+Ñ+Ó-×CÐCÔ1CÐPZÐgqôð rM   c               ó    € V ^8„  d   QhRRRR/# ©rC   r\  r
   rG   r’   rI   )rJ   s   "rK   rL   rL     s   € ÷ \ñ \ 3ð \¨>ñ \rM   c                ó¶   € \        V 4      pV'       d   V# \        V \        4      '       g   / # \        V P	                  R 4      4      ;'       g    \        V 4      # )Úpost)Ú_to_post_payloadr  r”   Ú_resolve_locale_payloadrñ   )r\  Údirects   & rK   rh  rh    sI   € Ü˜gÓ&€FßØˆÜ�gœt×$Ò$Øˆ	Ü" 7§;¡;¨vÓ#6Ó7×[Ð[Ô;RÐSZÓ;[Ð[rM   c               ó    € V ^8„  d   QhRRRR/# rs  rI   )rJ   s   "rK   rL   rL     s   € ÷ ñ  Sð ¨^ñ rM   c                ó  a € \        S 4      pV'       d   V# \        S \        4      '       g   / # V 3R  l\         4       p\	        \         \
        P                  ! VS P                  4       4      4       F  pV'       g   K  Vu # 	  / # )c              3  óF   <"  € T F  pSP                  V4      x € K  	  R # 5ir{   ©rñ   )rÕ   rî   r\  s   & €rK   r×   Ú*_resolve_locale_payload.<locals>.<genexpr>  s   øé € Ð@Ñ-? c�—‘˜S×!Ð!Ó-?ùó   ƒ!)rv  r  r”   Ú_PREFERRED_LOCALESÚmapÚ	itertoolsÚchainÚvalues)r\  rx  Ú	preferredÚ	candidates   f   rK   rw  rw    si   ø€ Ü˜gÓ&€FßØˆÜ�gœt×$Ò$Øˆ	ä@Õ-?Ó@€IÜÔ)¬9¯?ª?¸9ÀgÇnÁnÓFVÓ+WÖXˆ	ß‰9ØÒñ Yð €IrM   c               ó    € V ^8„  d   QhRRRR/# )rC   r…  r
   rG   r’   rI   )rJ   s   "rK   rL   rL   "  s   € ÷ ñ  ð ¨ñ rM   c           	     ó.  € \        V \        4      '       g   / # V P                  R 4      p\        V\        4      '       g   / # V P                  R4      pR\	        V P                  RR4      ;'       g    R4      R TR\        V\        4      '       d   V/# . /# )rO   rf  r_  rd   )r  r”   rñ   rˆ   rb   )r…  rO   rf  s   &  rK   rv  rv  "  sŽ   € Ü�i¤×&Ò&Øˆ	Ø�m‰m˜IÓ&€GÜ�gœt×$Ò$Øˆ	Ø�M‰M˜'Ó"€Eà”�Y—]‘] 7¨BÓ/×5Ð5°2Ó6Ø�7Øœ* U¬D×1Ò1�ðð ð 8:ðð rM   Úbrr  Úhrz

---

Údividerc          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )rC   r  r
   r…   r„   r‡   r†   rZ  r]  rG   rb   rI   )rJ   s   "rK   rL   rL   3  s=   € ÷ >Lñ >LØð>LØ'ð>LØ5Mð>Là7ð>Lð 	ñ>LrM   c                ó4	  a a€ \        S \        4      '       d   S # \        S \        4      '       g   R # \        S P                  RR 4      4      P	                  4       P                  4       pV\        9   d   \        V,          # VR8X  d   \        S 4      # VR%9   d   \        S 4      # VR8X  d…   \        S P                  RR 4      4      P	                  4       p\        S P                  RV4      ;'       g    R 4      P	                  4       pV'       g   R # \        V4      pV'       d
   RV RV R2# T# VR8X  d×   \        S P                  R	R 4      4      P	                  4       pVR
8X  d   Ve   R
V9  d   \        RR7      VR
&   R# T;'       g    / P                  V4      p	V	e+   V	P                  ;'       g    V	P                  ;'       g    RM2\        S P                  RR 4      4      P	                  4       ;'       g    Rp
R\        V
4       2# VR&9   d³   \        S P                  RR 4      4      P	                  4       pV'       d   W±9  d   VP                  V4       \        S P                  RR 4      4      P	                  4       ;'       g*    \        S P                  RR 4      4      P	                  4       pV'       d   RV R2# R# VR'9   dÌ   \        S P                  RR 4      4      P	                  4       oV 3R lR( 4       p\        R V 4       R 4      pV'       d   RV R2MRpS'       g   V# \        ;QJ d    V3R lV 4       F  '       g   K   RM	  RM! V3R lV 4       4      '       g(   TP                  \!        SYäR)9   d   TMRR7      4       V# R # VR*9   dt   \        S P                  RR 4      4      P	                  4       ;'       g*    \        S P                  RR 4      4      P	                  4       pV'       d   R \        V4       R 2# R!# VR"8X  dh   \        S P                  RR 4      ;'       g    R 4      ;'       g&    \        S P                  R#R 4      ;'       g    R 4      pV'       d   \#        V4      # R # V 3R$ lR+ 4       p\%        VWV4      # ),rd   rE  rŒ   ÚaÚhrefÚ[z](r!  Úatrw   ú@_allT©rs   ú@allÚuserÚ	user_nameÚ@Ú	image_keyÚaltz[Image: Ú]r]   rf   rc   c              3  óv   <"  € T F.  p\        SP                  VR 4      4      P                  4       x € K0  	  R# 5i©rd   N)rb   rñ   r  )rÕ   rÛ   r  s   & €rK   r×   Ú'_render_post_element.<locals>.<genexpr>_  s/   øé € ÐYÑ:X°Q”�W—[‘[  BÓ'Ó(×.Ñ.×0Ð0Ó:Xùs   ƒ69c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir{   rI   )rÕ   Úns   & rK   r×   rœ  `  s   é € Ð0¡U «aŸ!š!£UùrÙ   ú[Attachment: r^   c              3  ó@   <"  € T F  qP                   S8H  x € K  	  R # 5ir{   )rc   )rÕ   Úrefrc   s   & €rK   r×   rœ  d  s   øé € ÐB±z°—<‘< 8Ö+³zùre  F©rc   re   rg   Ú
emoji_typeÚ:z[Emoji]r  rO   c              3  óF   <"  € T F  pSP                  V4      x € K  	  R # 5ir{   r|  )rÕ   rî   r  s   & €rK   r×   rœ  p  s   øé € Ð_Ñ*^ 3ˆg�k‰k˜#×ÐÓ*^ùr~  >   ÚpreÚ
code_block>   ÚimgÚimage>   rf   ÚaudioÚmediaÚvideo)re   r_  rŒ   >   rª  r¬  >   ÚemojiÚemotion)rŒ   r_  rO   ÚchildrenÚelements)r  rb   r”   rñ   r  ÚlowerÚ_STATIC_POST_TAGSr  r  ræ   ro   rp   rq   rM  ÚnextÚanyra   r   Ú_join_nested_posts)r  r…   r‡   rZ  rE  rŽ  ÚlabelÚescaped_labelrp  r¡  Údisplay_namer—  r˜  Únamesre   r  Únestedrc   s   f&&&             @rK   ra  ra  3  sÞ  ù€ ô �'œ3×ÒØˆÜ�gœt×$Ò$Ùä
ˆg�k‰k˜% Ó$Ó
%×
+Ñ
+Ó
-×
3Ñ
3Ó
5€CØ
ÔÔÜ  Õ%Ð%Ø
ˆf„}Ü# GÓ,Ð,Ø
Ð#Ô#Ü)¨'Ó2Ð2Ø
ˆc„zÜ�7—;‘;˜v rÓ*Ó+×1Ñ1Ó3ˆÜ�G—K‘K ¨Ó-×3Ð3°Ó4×:Ñ:Ó<ˆßÙÜ-¨eÓ4ˆß/3��=�/  D 6¨Ð+ÐF¸ÐFØ
ˆd„{ä˜'Ÿ+™+ i°Ó4Ó5×;Ñ;Ó=ˆØ˜'Ô!àÒ'¨G¸<Ô,GÜ(8ÀÔ(E�˜WÑ%ÙØ×!Ð!˜r×&Ñ& {Ó3ˆØ>Aºo˜Ÿ™×9Ð9 C§K¡K×9Ð9°6øÜ�—‘˜K¨Ó,Ó-×3Ñ3Ó5×?Ð?¸ð 	ð Ô(¨Ó6Ð7Ð8Ð8Ø
ÐÔÜ˜Ÿ™ K°Ó4Ó5×;Ñ;Ó=ˆ	ß˜Ô4Ø×Ñ˜iÔ(Ü�'—+‘+˜f bÓ)Ó*×0Ñ0Ó2×YÐY´c¸'¿+¹+ÀeÈRÓ:PÓ6Q×6WÑ6WÓ6Yˆß$'�˜#˜˜aÐ Ð6¨YÐ6Ø
Ð1Ô1Ü�w—{‘{ :¨rÓ2Ó3×9Ñ9Ó;ˆÜYÑ:XÓYˆÜÑ0¡UÓ0°"Ó5ˆ	ß6?˜ i [°Ñ2À^ˆßØÐß‹sÔB±zÓB�s�sŠsÔB±zÓB×BÒBØ×ÑÔ0Ø!¨YÐTfÔMfÁcÐlrôô ð ÐÙØ
Ð"Ô"Ü�G—K‘K ¨Ó+Ó,×2Ñ2Ó4×bÐb¼¸G¿K¹KÈÐVXÓ<YÓ8Z×8`Ñ8`Ó8bˆß6;�Ô(¨Ó/Ð0°Ð2ÐJÀÐJØ
ˆf„}Ü�7—;‘;˜v rÓ*×0Ð0¨bÓ1×ZÐZ´S¸¿¹ÀYÐPRÓ9S×9YÐ9YÐWYÓ5Zˆß*.Ô  Ó&Ð6°BÐ6Ü_Ñ*^Ó_€FÜ˜f j¸lÓKÐKrM   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )rC   rƒ  r
   r…   r‡   rZ  rG   rb   rI   )rJ   s   "rK   rL   rL   t  s1   € ÷ 4ñ 4˜sð 4°ð 4Àð 4ÐTWð 4Ð\_ñ 4rM   c                óT   aaa€ VVV3R  lV  4       pRP                  R V 4       4      # )c              3  ó@   <"  € T F  p\        VSSS4      x € K  	  R # 5ir{   )Ú_render_nested_postrb  s   & €€€rK   r×   Ú%_join_nested_posts.<locals>.<genexpr>u  s#   øé € Ð`ÑY_ÐQUÔ   z°:¸|×LÐLÓY_ùre  r÷   c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir{   rI   )rÕ   Úparts   & rK   r×   r¿  v  s   é € Ð3¡U˜T«d—D’D£UùrÙ   )rL  )rƒ  r…   r‡   rZ  rl  s   &fff rK   rµ  rµ  t  s#   ú€ Þ`ÑY_Ó`€EØ�8‰8Ñ3¡UÓ3Ó3Ð3rM   c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )rC   rè   r
   r…   r„   r‡   r†   rZ  r]  rG   rb   rI   )rJ   s   "rK   rL   rL   y  s6   € ÷ ñ ØðØ%ðØ3Kðà7ðð 	ñrM   c                ó  € \        V \        4      '       d   \        V 4      # \        V \        4      '       d   \	        WW#4      # \        V \
        4      '       d2   \        WW#4      pT;'       g    \	        V P                  4       WV4      # R # ©rd   )r  rb   ræ   rˆ   rµ  r”   ra  rƒ  )rè   r…   r‡   rZ  rx  s   &&&& rK   r¾  r¾  y  sq   € ô �%œ×ÒÜ$ UÓ+Ð+Ü�%œ×ÒÜ! %°ZÓNÐNÜ�%œ×ÒÜ% e¸ÓRˆØ×aÐaÔ+¨E¯L©L«N¸JÐT`ÓaÐaÙrM   r�   rÌ   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
rC   Úmessage_typerb   Úraw_contentr�   úOptional[Sequence[Any]]rÌ   rv   rG   rŠ   rI   )rJ   s   "rK   rL   rL   ‰  s=   € ÷ 9Nñ 9NØð9NØ'*ð9NØ6Mð9Nà	ð9Nð ñ9NrM   c                óT  € \        T ;'       g    R 4      P                  4       P                  4       p\        V4      p\	        W#4      pVR8X  dq   \        VP                  RR 4      ;'       g    R 4      pRV9   d   RV9  d   \        RR7      VR&   \        V\        Wv4      \        VP                  4       4      R7      # VR8X  dd   \        WVR7      p\        WHP                  \        VP                  4      \        VP                  4      \        VP                  4       4      RR7      # \        VP                  4       4      p	VR	8X  dÇ   \        VP                  R
R 4      ;'       g    R 4      P                  4       p
\        \        VP                  RR 4      ;'       g    R 4      ;'       g4    \        VP                  RR 4      ;'       g    R 4      ;'       g    \        V4      p\        TV\        8w  d   TMR RV
'       d   V
.M. R	V	R7      # VR9   dR   \!        WTR7      p\        TR VR8X  d   RMRVP"                  '       d   V.M. VR\%        VP&                  4      /V	R7      # VR8X  d   \)        V4      # VR8X  d   \+        V4      # VR9   d   \-        WE4      # \        VR R7      # )rd   rŒ   r‘  Tr’  )r‹   r�   r�   ru  )rZ  )r‹   r�   r…   r‡   r�   r‘   r©  r—  r˜  Úphoto)r‹   r�   r�   r…   r‘   r�   rª  )rg   ÚdocumentÚplaceholder_text)r‹   r�   r�   r‡   r‘   r“   r�   Úmerge_forwardÚ
share_chat)r‹   r�   >   rf   rª  r«  >   ÚcardÚinteractive)rb   r  r±  Ú_load_feishu_payloadÚ_build_mentions_maprñ   ro   rŠ   rj  rˆ   rƒ  rq  r�   r…   r‡   ÚFALLBACK_IMAGE_TEXTÚ_build_media_ref_from_payloadrc   Ú_attachment_placeholderre   Ú _normalize_merge_forward_messageÚ_normalize_share_chat_messageÚ_normalize_interactive_message)rÆ  rÇ  r�   rÌ   Únormalized_typer\  rZ  rŒ   Úparsed_postÚmention_refsr—  Úalt_textÚ	media_refs   $$$$         rK   Únormalize_feishu_messagerÞ  ‰  sx  € ô ˜,×,Ð,¨"Ó-×3Ñ3Ó5×;Ñ;Ó=€OÜ" ;Ó/€GÜ& xÓ5€Là˜&Ô Ü�7—;‘;˜v rÓ*×0Ð0¨bÓ1ˆð �dŒ?˜w¨lÔ:Ü$4¸DÔ$AˆL˜Ñ!Ü&Ø$Ô3IÈ$Ó3]Ü˜,×-Ñ-Ó/Ó0ô
ð 	
ð ˜&Ô ô 0°ÔSˆÜ&Ø$×3KÑ3KÜ˜K×2Ñ2Ó3ÄÀ[×E[ÑE[Ó@\Ü˜,×-Ñ-Ó/Ó0Àô
ð 	
ô
 ˜×+Ñ+Ó-Ó.€LØ˜'Ô!Ü˜Ÿ™ K°Ó4×:Ð:¸Ó;×AÑAÓCˆ	Ü)Ü�—‘˜F BÓ'×-Ð-¨2Ó.÷ #ð #Ü�7—;‘;˜u bÓ)×/Ð/¨RÓ0÷#ð #ä"Øó	
ˆô 'Ø$Ø%-Ô1DÔ%D™È"Ø#*Çi¸	±{ÐUWØ!¨Lô	
ð 	
ð Ð4Ô4Ü1°'ÔYˆ	Ü&Ø$°2Ø.=ÀÔ.H¡7ÈjØ&/×&8×&8Ð&8˜	‘{¸bÐP_Ø(Ô*AÀ)×BUÑBUÓ*VÐWØ!ô
ð 	
ð ˜/Ô)Ü/°Ó8Ð8Ø˜,Ô&Ü,¨WÓ5Ð5ØÐ1Ô1Ü-¨oÓGÐGÜ"¨OÈ"ÔMÐMrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rÇ  rb   rG   r’   rI   )rJ   s   "rK   rL   rL   Å  s   € ÷ Gñ G cð G¨nñ GrM   c                óº   €  V '       d   \         P                  ! V 4      M/ p\        T\        4      '       d   T# RT/#   \         P                   d    R T /u # i ; i)rŒ   rO   )r?  ÚloadsÚJSONDecodeErrorr  r”   )rÇ  r1  s   & rK   rÑ  rÑ  Å  sY   € ð%ß,7”—’˜KÔ(¸Rˆô   ¬×-Ò-ˆ6ÐF°I¸vÐ3FÐFøô ×Ñô %Ø˜Ð$Ò$ð%ús   ‚> Š> ¾AÁAc               ó    € V ^8„  d   QhRRRR/# ©rC   r\  r’   rG   rŠ   rI   )rJ   s   "rK   rL   rL   Í  s   € ÷ ñ ¨nð ÐAXñ rM   c           	     óü   € \        V R RRR	R7      p\        V 4      pV'       d   V.M. VR,          ,           p\        RRP                  V4      P	                  4       ;'       g    \
        RR\        V4      R V/R7      # )
r_  ÚsummaryÚpreview©Údeep:Né   NrÍ  r  Úentry_count©r‹   r�   r‘   r“   )r_  ræ  rç  Údescription)Ú_first_text_fieldÚ_collect_forward_entriesrŠ   rL  r  ÚFALLBACK_FORWARD_TEXTrT   )r\  r_  ÚentriesÚliness   &   rK   rÖ  rÖ  Í  ss   € Ü˜g w°	¸9ÐKyÔz€EÜ& wÓ/€Gßˆe‰W 2¨°­Õ4€EÜ"Ø ¨t¯y©y¸Ó/?×/EÑ/EÓ/G×/`Ð/`ÔK`Ø%°ÄÀGÃÈgÐW\Ð0]ôð rM   c               ó    € V ^8„  d   QhRRRR/# rä  rI   )rJ   s   "rK   rL   rL   ×  s   € ÷ 	ñ 	¨>ð 	Ð>Uñ 	rM   c           	     óâ   € \        V R RRRR7      p\        V RRR4      pV'       d   RV 2M\        .pV'       d   VP                  RV 24       \        R	R
P	                  V4      R	RVR V/R7      # )Ú	chat_namerp   r_  rè  Úchat_idÚopen_chat_idÚshare_chat_idzShared chat: z	Chat ID: rÎ  r  rì  )rõ  rp   r_  )rî  ÚFALLBACK_SHARE_CHAT_TEXTrM  rŠ   rL  )r\  rõ  Úshare_idrò  s   &   rK   r×  r×  ×  sx   € Ü! '¨;¸ÀÐNlÔm€IÜ  ¨)°^À_ÓU€Hß,5ˆ}˜Y˜KÑ(Ô;SÐT€EßØ�‰�y  
Ð+Ô,Ü"Ø¨D¯I©I°eÓ,<ÈLØ˜X {°IÐ>ôð rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rÆ  rb   r\  r’   rG   rŠ   rI   )rJ   s   "rK   rL   rL   ã  s"   € ÷ ñ °ð ¸~ð ÐRiñ rM   c           	     ó<  € \        VP                  R 4      \        4      '       d   VP                  R 4      MTp\        \	        V4      VP                  R4      \        VR
R7      4      p\        V4      pV'       d   V.M. \        V4       Uu. uF  qUV8w  g   K  VNK  	  up,           pV'       d$   VP                  RRP                  V4       24       \        T RP                  VR,          4      P                  4       ;'       g    \        RRVRV/R	7      # u upi )rÏ  r_  ©Úkeysz	Actions: ú, r  :Né   NrÐ  Úactionsrì  )r_  ræ  Úsubtitle)r  rñ   r”   Ú_first_non_empty_textÚ_find_header_titleÚ_find_first_textÚ_collect_action_labelsÚ_collect_card_linesrM  rL  rŠ   r  ÚFALLBACK_INTERACTIVE_TEXT)rÆ  r\  Úcard_payloadr_  r  Úlinerò  s   &&     rK   rØ  rØ  ã  sñ   € Ü*4°W·[±[ÀÓ5HÌ$×*OÒ*O�7—;‘;˜vÔ&ÐU\€LÜ!Ü˜<Ó(¨'¯+©+°gÓ*>Ü˜Ð,LÔMó€Eô % \Ó2€Gßˆe‰W 2Ô;NÈ|Ô;\Ó)nÑ;\°4ÐhmÑ`m¯$¨$Ñ;\Ñ)nÕn€EßØ�‰�y §¡¨7Ó!3Ð 4Ð5Ô6Ü"ØØ—Y‘Y˜u S�zÓ*×0Ñ0Ó2×OÐOÔ6OØ#¨w¸¸yÈ'Ð.Rôð ùò *os   ÂDÂDc               ó    € V ^8„  d   QhRRRR/# )rC   r\  r’   rG   r„   rI   )rJ   s   "rK   rL   rL   ö  s   € ÷ "ñ " nð "¸ñ "rM   c           
     óV  € . pR F=  pV P                  V4      p\        V\        4      '       g   K,  VP                  V4       K?  	  . pV EFQ  p\        V\        4      '       g=   \        \        T;'       g    R4      4      pV'       d   VP                  RV 24       KV  \        VRRRR4      p\        VP                  RR4      ;'       g    VP                  R	R4      4      P                  4       P                  4       pVR
8X  d0   \        VP                  R4      ;'       g    T4      P                  p	M\        VRRRRRR7      p	\        V	4      p	V'       d#   V	'       d   VP                  RV RV	 24       EK2  V	'       g   EK=  VP                  RV	 24       EKT  	  \        V4      # )ÚmessagesrO   rd   z- Úsender_namer•  rÈ   rp   rÆ  Úmsg_typeru  rŒ   ræ  rç  rè  z: )r  ÚitemsÚmessage_listÚrecordsrO   )rŒ   rO   ræ  rç  r_  )rñ   r  rˆ   Úextendr”   rj  rb   rM  rî  r  r±  rq  r�   Ú_unique_lines)
r\  Ú
candidatesrî   rè   rñ  rc  rŒ   rÈ   Únested_typerV   s
   &         rK   rï  rï  ö  s`  € Ø€JÛJˆØ—‘˜CÓ ˆÜ�eœT×"Ô"Ø×Ñ˜eÖ$ñ Kð €GÜˆÜ˜$¤×%Ò%Ü)¬#¨d¯j¨j°b«/Ó:ˆDßØ—‘  D 6˜{Ô+ÙÜ" 4¨¸ÀXÈvÓVˆÜ˜$Ÿ(™( >°2Ó6×RÐR¸$¿(¹(À:ÈrÓ:RÓS×YÑYÓ[×aÑaÓcˆØ˜&Ô Ü,¨T¯X©X°iÓ-@×-HÐ-HÀDÓI×VÑV‰Dä$Ø�f˜i¨°IÐDvôˆDô & dÓ+ˆß—dØ�N‰N˜R ˜x r¨$¨Ð0×1ßŠTØ�N‰N˜R ˜v˜;×'ñ% ô& ˜Ó!Ð!rM   c               ó    € V ^8„  d   QhRRRR/# ©rC   r\  r
   rG   r„   rI   )rJ   s   "rK   rL   rL     s   € ÷ @ñ @ ð @¨ñ @rM   c                ó¬   € \        V R R7      pV Uu. uF  p\        V4      NK  	  pp\        V Uu. uF  q"'       g   K  VNK  	  up4      # u upi u upi )F©Úin_rich_block)Ú_collect_text_segmentsrj  r  )r\  rò  r
  Ú
normalizeds   &   rK   r  r    sO   € Ü" 7¸%Ô@€EÙ;@ÓA¹5°4Ô(¨Ö.¹5€JÐAÜ©:Ó>©: 4»Ÿ$˜$©:Ñ>Ó?Ð?ùò BùÚ>s   ’A±	A¿Ac               ó    € V ^8„  d   QhRRRR/# r  rI   )rJ   s   "rK   rL   rL     s   € ÷ !ñ ! Cð !¨Iñ !rM   c           	     óz  € . p\        V 4       F   p\        V\        4      '       g   K  \        VP	                  R R4      ;'       g    VP	                  RR4      4      P                  4       P                  4       pVR9  d   Ku  \        VRRRRR7      pV'       g   K�  VP                  V4       K¢  	  \        V4      # )	rE  rd   ÚtyperŒ   rp   rè   rè  >   ÚbuttonÚpickerÚoverflowÚdate_pickerÚselect_static)rŒ   rO   rp   rè   )
Ú_walk_nodesr  r”   rb   rñ   r  r±  rî  rM  r  )r\  Úlabelsrc  rE  r¶  s   &    rK   r  r    s�   € Ø€FÜ˜GÖ$ˆÜ˜$¤×%Ò%ÙÜ�$—(‘(˜5 "Ó%×=Ð=¨¯©°&¸"Ó)=Ó>×DÑDÓF×LÑLÓNˆØÐVÔVÙÜ! $¨°¸ÐFjÔkˆß‰5Ø�M‰M˜%Ö ñ %ô ˜Ó Ð rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rè   r
   r  rr   rG   r„   rI   )rJ   s   "rK   rL   rL   '  s!   € ÷ ñ  #ð ¸ð À)ñ rM   c          	     ó6  € \        V \        4      '       d   V'       d   \        V 4      .# . # \        V \        4      '       d'   V  UUu. uF  p\	        W!R 7       F  q3NK  	  K  	  upp# \        V \
        4      '       g   . # \        V P                  RR4      ;'       g    V P                  RR4      4      P                  4       P                  4       pT;'       g
    V\        9   p. pV'       dd   \         FY  pV P                  V4      p\        V\        4      '       g   K,  \        V4      '       g   K?  VP                  \        V4      4       K[  	  V P                  4        F-  w  rrV\        9  g   K  VP                  \	        W%R 7      4       K/  	  V# u uppi )r  rE  rd   r   )r  rb   rj  rˆ   r  r”   rñ   r  r±  Ú_RICH_BLOCK_TAGSÚ_SUPPORTED_CARD_TEXT_KEYSrM  r  Ú_SKIP_TEXT_KEYSr  )rè   r  rc  ÚsegrE  Únext_in_rich_blockÚsegmentsrî   s   &$      rK   r  r  '  s:  € Ü�%œ×Òß2?Ô& uÓ-Ð.ÐGÀRÐGÜ�%œ×ÒÙ %Ôk¡˜Ô1GÈ×1j¨#’Ñ1j‘¡ÒkÐkÜ�eœT×"Ò"Øˆ	Ü
ˆe�i‰i˜˜rÓ"×;Ð; e§i¡i°¸Ó&;Ó
<×
BÑ
BÓ
D×
JÑ
JÓ
L€CØ&×AÐA¨#Ô1AÑ*AÐØ€Hßß,ˆCØ—9‘9˜S“>ˆDÜ˜$¤×$Ô$Ô)?À×)EÔ)EØ—‘Ô 6°tÓ <Ö=ñ -ð —[‘[–]‰	ˆØ”oÖ%Ø�O‰OÔ2°4ÔZÖ[ñ #ð €Oùó ls   ÁFc               ó$   € V ^8„  d   QhRRRRRR/# )rC   r\  r’   rg   rb   rG   ra   rI   )rJ   s   "rK   rL   rL   <  s'   € ÷ dñ d¨>ð dÈSð dÐUgñ drM   c               ó´   € \        V P                  R R4      ;'       g    R4      P                  4       p\        V RRR4      pVR9   d   TMRp\	        W#VR7      # )rc   rd   re   r_  rŒ   rf   r¢  >   rª  r¬  )rb   rñ   r  rî  ra   )r\  rg   rc   re   Úeffective_types   &$   rK   rÔ  rÔ  <  sU   € Ü�7—;‘;˜z¨2Ó.×4Ð4°"Ó5×;Ñ;Ó=€HÜ! '¨;¸ÀÓH€IØ&3Ð7IÔ&I‘]Èv€NÜ xÐTbÔcÐcrM   c               ó    € V ^8„  d   QhRRRR/# )rC   re   rb   rG   rI   )rJ   s   "rK   rL   rL   C  s   € ÷ _ñ _ sð _¨sñ _rM   c                ó@   € \        V 4      pV'       d   R V R2# \        # )rŸ  r™  )rj  ÚFALLBACK_ATTACHMENT_TEXT)re   Únormalized_names   & rK   rÕ  rÕ  C  s$   € Ü,¨YÓ7€Oß1@ˆ]˜?Ð+¨1Ð-Ð^ÔF^Ð^rM   c               ó    € V ^8„  d   QhRRRR/# )rC   r\  r
   rG   rb   rI   )rJ   s   "rK   rL   rL   H  s   € ÷ 	4ñ 	4 ð 	4¨ñ 	4rM   c                ó‚  € \        V \        4      '       g   R # V P                  R4      p\        V\        4      '       g   R # VP                  R4      p\        V\        4      '       d;   \        VP                  R4      VP                  R4      VP                  R4      4      # \	        \        T;'       g    R 4      4      # )rd   Úheaderr_  rO   rŒ   rp   )r  r”   rñ   r  rj  rb   )r\  r9  r_  s   &  rK   r  r  H  sŒ   € Ü�gœt×$Ò$ÙØ�[‰[˜Ó"€FÜ�fœd×#Ò#ÙØ�J‰J�wÓ€EÜ�%œ×ÒÜ$ U§Y¡Y¨yÓ%9¸5¿9¹9ÀVÓ;LÈeÏiÉiÐX^ÓN_Ó`Ð`Ü!¤# e§k k¨rÓ"2Ó3Ð3rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r\  r
   rþ  útuple[str, ...]rG   rb   rI   )rJ   s   "rK   rL   rL   T  s!   € ÷ 
ñ 
˜cð 
¨Oð 
Àñ 
rM   c               óð   € \        V 4       Ff  p\        V\        4      '       g   K  V FE  pVP                  V4      p\        V\        4      '       g   K,  \        V4      pV'       g   KA  Vu u # 	  Kh  	  R # rÄ  )r&  r  r”   rñ   rb   rj  )r\  rþ  Únoderî   rè   r  s   &$    rK   r  r  T  s_   € Ü˜GÖ$ˆÜ˜$¤×%Ò%ÙÛˆCØ—H‘H˜S“MˆEÜ˜%¤×%Ô%Ü3°EÓ:�
ß‘:Ø%Ô%ó ñ %ñ rM   c               ó   € V ^8„  d   QhRR/# )rC   rè   r
   rI   )rJ   s   "rK   rL   rL   a  s   € ÷ )ñ )�sñ )rM   c              #  ó
  "  € \        V \        4      '       d1   V x € V P                  4        F  p\        V4       R j  x€L
  K  	  R # \        V \        4      '       d   V  F  p\        V4       R j  x€L
  K  	  R # R #  L@ L5ir{   )r  r”   rƒ  r&  rˆ   )rè   rc  s   & rK   r&  r&  a  si   é € Ü�%œ×ÒØŠØ—L‘L–NˆDÜ" 4Ó(×(Ò(ó #ä	�Eœ4×	 Ò	 ÛˆDÜ" 4Ó(×(Ò(ó ñ 
!ñ )ñ )ùs!   ‚<B¾A?¿3BÁ2BÁ3BÂBc               ó    € V ^8„  d   QhRRRR/# )rC   rƒ  r
   rG   rb   rI   )rJ   s   "rK   rL   rL   k  s   € ÷ ñ  3ð ¨3ñ rM   c                 óÌ   € V  F]  pVe   \        V\        \        34      '       d   K%  \        \        V\        4      '       d   TM
\	        V4      4      pV'       g   K[  Vu # 	  R# )zOFirst scalar (non-dict/list, non-None) value that normalizes to non-empty text.rd   )r  r”   rˆ   rj  rb   )rƒ  rè   r  s   *  rK   r  r  k  sS   € ãˆØŠ=œJ u¬t´T¨l×;Ò;ÙÜ+´ZÀÄs×5KÒ5K©EÔQTÐUZÓQ[Ó\ˆ
ß‰:ØÒñ ñ rM   ré  c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   r\  r’   rþ  rb   ré  r;  rG   rI   )rJ   s   "rK   rL   rL   v  s)   € ÷ *ñ *˜~ð *°cð *Àð *ÐZ]ñ *rM   c               ó¢   € V Uu. uF  q0P                  V4      NK  	  ppV'       d   VP                  \        WR7      4       \        V!  # u upi )z_``_first_non_empty_text`` over ``payload[key]`` for each key, then a deep ``_find_first_text``.rý  )rñ   rM  r  r  )r\  ré  rþ  rî   rƒ  s   &$*  rK   rî  rî  v  sB   € á*.Ó/©$ 3�k‰k˜#Ö©$€FÐ/ßØ�‰Ô& wÔ:Ô;Ü  &Ñ)Ð)ùò 0s   …Ac               ó$   € V ^8„  d   QhRRRRRR/# )rC   rŒ   rb   rZ  r]  rG   rI   )rJ   s   "rK   rL   rL   €  s#   € ÷ ñ  ð Ð4Yð Ðehñ rM   c                ó¤  a€ R  V3R llp\         P                  Y ;'       g    R4      pVP                  RR4      pVP                  RR4      P                  RR4      pRP                  R VP	                  R4       4       4      pRP                  R	 VP	                  R4       4       4      p\
        P                  R
V4      pVP                  4       # )c               ó    € V ^8„  d   QhRRRR/# )rC   rU  zre.Match[str]rG   rb   rI   )rJ   s   "rK   rL   Ú,_normalize_feishu_text.<locals>.__annotate__�  s   € ÷ Oñ O�Mð O cñ OrM   c                ó¾   <€ S;'       g    / P                  V P                  ^ 4      4      pVf   R# RVP                  ;'       g    VP                  ;'       g    R 2# )rõ   r÷   r–  r”  )rñ   r"  rp   rq   )rU  r¡  rZ  s   & €rK   Ú_subÚ$_normalize_feishu_text.<locals>._sub�  sR   ø€ Ø×!Ð!˜r×&Ñ& u§{¡{°1£~Ó6ˆØ’kˆsÐN¨¨3¯8©8×+LÐ+L°s·{±{×+LÐ+LÀfÐ*MÐ'NÐNrM   rd   r‘  r“  r  r  r  c              3  ój   "  € T F)  p\         P                  R V4      P                  4       x € K+  	  R# 5i)r÷   N)Ú_WHITESPACE_RErå   r  ©rÕ   r
  s   & rK   r×   Ú)_normalize_feishu_text.<locals>.<genexpr>ˆ  s+   é € Ð^ÑJ]À$œ×*Ñ*¨3°Ó5×;Ñ;×=Ð=ÓJ]ùs   ‚13c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir{   rI   rM  s   & rK   r×   rN  ‰  s   é € ÐEÑ)< ÃŸšÓ)<ùrÙ   r÷   )Ú_MENTION_PLACEHOLDER_RErå   r  rL  ÚsplitÚ_MULTISPACE_REr  )rŒ   rZ  rI  Úcleaneds   &f  rK   rj  rj  €  s­   ø€ ÷Oð Oô &×)Ñ)¨$·
°
¸Ó;€GØ�o‰o˜g vÓ.€GØ�o‰o˜f dÓ+×3Ñ3°D¸$Ó?€GØ�i‰iÑ^È'Ï-É-ÐX\ÔJ]Ó^Ó^€GØ�i‰iÑE¨¯©°tÔ)<ÓEÓE€GÜ× Ñ   gÓ.€GØ�=‰=‹?ÐrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rò  r„   rG   rI   )rJ   s   "rK   rL   rL   Ž  s   € ÷ ñ ˜ð  yñ rM   c                ó”   € \        4       p. pV  F5  pV'       d   W19   d   K  VP                  V4       VP                  V4       K7  	  V# r{   )rÀ   ÚaddrM  )rò  ÚseenÚuniquer
  s   &   rK   r  r  Ž  s@   € Ü“U€DØ€FÛˆß�t”|ÙØ�‰�ŒØ�‰�dÖñ	 ð
 €MrM   c               ó    € V ^8„  d   QhRRRR/# )rC   Úmentionr
   rG   útuple[str, str]rI   )rJ   s   "rK   rL   rL   ›  s   € ÷ hñ h #ð h¨/ñ hrM   c                ó`  € \        V RR4      p\        V\        4      '       dG   \        \        V RR4      ;'       g    R4      P                  4       pVR8X  d   VR3# VR8X  d   RV3# R# Vf   R# \        \        VRR4      ;'       g    R4      \        \        VRR4      ;'       g    R4      3# )z`(open_id, user_id): message.get gives a string id + id_type; events give a nested UserId object.ÚidNÚid_typerd   rq   rw   ©rd   rd   )rÎ   r  rb   r±  )rZ  Ú
mention_idr^  s   &  rK   Ú_extract_mention_idsra  ›  s±   € ä˜ $¨Ó-€JÜ�*œc×"Ò"Ü”g˜g y°"Ó5×;Ð;¸Ó<×BÑBÓDˆØ#*¨iÔ#7�
˜BÐÐsÐQXÐ\eÔQe¸bÀ*Ð=MÐsÐksÐsØÒØˆÜŒw�z 9¨bÓ1×7Ð7°RÓ8¼#¼gÀjÐR[Ð]_Ó>`×>fÐ>fÐdfÓ:gÐgÐgrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r�   rÈ  rÌ   rv   rG   zdict[str, FeishuMentionRef]rI   )rJ   s   "rK   rL   rL   ¦  s$   € ÷ ñ Ð"9ð Ð@Rð ÐWrñ rM   c                ól  € / pT ;'       g    .  F¡  p\        \        VR R4      ;'       g    R4      pV'       g   K-  VR8X  d   \        RR7      W$&   KD  \        V4      w  rV\        \        VRR4      ;'       g    R4      P	                  4       pVP                  WVVR7      p\        WuVR7      W$&   K£  	  V# )rî   rd   r‘  Tr’  rp   ©rq   rw   rp   )rp   rq   rt   )rb   rÎ   ro   ra  r  r}   )	r�   rÌ   ÚresultrZ  rî   rq   rw   rp   rt   s	   &&       rK   rÒ  rÒ  ¦  s¨   € Ø*,€FØ—>�>˜r’>ˆÜ”'˜' 5¨"Ó-×3Ð3°Ó4ˆßÙØ�'Œ>Ü*°$Ô7ˆF‰KÙÜ/°Ó8ÑˆÜ”7˜7 F¨BÓ/×5Ð5°2Ó6×<Ñ<Ó>ˆØ—+‘+ gÀT�+ÓJˆÜ&¨DÈ7ÔSˆ‹ñ "ð €MrM   c               ó    € V ^8„  d   QhRRRR/# )rC   r�   úSequence[FeishuMentionRef]rG   rb   rI   )rJ   s   "rK   rL   rL   ¶  s   € ÷ ?ñ ?Ð"<ð ?Àñ ?rM   c                ó0  € . p\        4       pV  Fæ  pVP                  '       d   K  VP                  VP                  VP                  3pWB9   d   KB  VP                  V4       VP                  '       d   VP                  R 4       Kx  VP                  '       d8   TP                  VP                  ;'       g    R RVP                   R24       KÁ  TP                  VP                  ;'       g    R4       Kè  	  V'       d   RRP                  V4       R2# R# )r“  Úunknownz
 (open_id=r!  z[Mentioned: rÿ  r™  rd   )rÀ   rt   rs   rq   rp   rV  rM  rL  )r�   rl  rW  r¡  Ú	signatures   &    rK   Ú_build_mention_hintrk  ¶  sÓ   € Ø€EÜ“€DÛˆØ�;�;ˆ;ÙØ—Z‘Z §¡¨c¯h©hÐ7ˆ	ØÔÙØ�‰�ÔØ�:�:ˆ:Ø�L‰L˜Ö Ø�[�[ˆ[Ø�L‰L˜CŸH™H×1Ð1¨	Ð2°*¸S¿[¹[¸MÈÐKÖLà�L‰L˜Ÿ™×.Ð. YÖ/ñ ÷ 27ˆ\˜$Ÿ)™) EÓ*Ð+¨1Ð-Ð>¸BÐ>rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rŒ   rb   r�   rg  rG   rI   )rJ   s   "rK   rL   rL   É  s#   € ÷ ñ  Cð Ð3Mð ÐRUñ rM   c                óÀ  € V '       g   V # V Uu. uFC  q"P                   '       g   K  R VP                  ;'       g    VP                  ;'       g    R 2NKE  	  ppV'       g   V # V P                  4       p V FW  pVP	                  V4      '       g   K  V\        V4      R pV'       d   V^ ,          \        9  d   KF  VP                  4       p K\  	    \        T4      pT^ 8”  d$   YG^,
          ,          \        9   d   T^,          pK*  TRT pYGR p	T FA  pTP                  T4      '       g   K  TR\        T4      )  P                  4       T	,           p K„  	  T# u upi )r–  r”  N)
rt   rp   rq   Úlstriprû   rT   Ú_MENTION_BOUNDARY_CHARSÚ_TRAILING_TERMINAL_PUNCTrü   Úrstrip)
rŒ   r�   r¡  Ú
self_namesÚ	remainingÚnmÚafterÚirV   Útails
   &&        rK   Ú_strip_edge_self_mentionsrx  É  s;  € ÷ ØˆÙEMÓ]ÁX¸c×Q\ÕQ\Ô9�A�c—h‘h×7Ð7 #§+¡+×7Ð7°Ð8Ó9ÁX€JÐ]ßØˆØ—‘“€IØ
ÛˆBØ×'Ñ'¨×+Ò+ÙØœc "›g˜hÐ'ˆEß˜˜q�Ô)@Ô@ÙØŸ™›ˆIÚñ ð Ø
Ü�	‹NˆØ�!Œe˜	 a¥%Õ(Ô,DÔDØ��FŠAØ˜˜!ˆ}ˆØ˜ˆ}ˆÛˆBØ�}‰}˜R× Ô Ø  ¤C¨£G 8Ð,×3Ñ3Ó5¸Õ<�	Úñ ð
 Ðùò5 ^s   �E§E»EÁ	Ec                  óJ   € ] tR tRtRtR R ltR R ltR R ltR	 R
 ltRt	R# )Ú_ThreadLocalLoopProxyi  zBForwards attribute access to the current thread's registered loop.c               ó    € V ^8„  d   QhRRRR/# )rC   Úfallbackr
   rG   rI  rI   )rJ   s   "rK   rL   Ú"_ThreadLocalLoopProxy.__annotate__  s   € ÷ "ñ " ð "¨ñ "rM   c                	ó   € Wn         R # r{   ©Ú	_fallback)r|   r|  s   &&rK   Ú__init__Ú_ThreadLocalLoopProxy.__init__  s   € Ø!ŽrM   c               ó   € V ^8„  d   QhRR/# ©rC   rG   r
   rI   )rJ   s   "rK   rL   r}    s   € ÷ Lñ L˜ñ LrM   c                	óL   € \        \        R R4      ;'       g    V P                  # )ÚloopN)rÎ   Ú_ws_isolation_stater€  ©r|   s   &rK   Ú_targetÚ_ThreadLocalLoopProxy._target  s   € ÜÔ*¨F°DÓ9×KÐK¸T¿^¹^ÐKrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rp   rb   rG   r
   rI   )rJ   s   "rK   rL   r}    s   € ÷ -ñ - ð -¨ñ -rM   c                	ó6   € \        V P                  4       V4      # r{   )rÎ   r‰  )r|   rp   s   &&rK   Ú__getattr__Ú!_ThreadLocalLoopProxy.__getattr__  s   € Ü�t—|‘|“~ tÓ,Ð,rM   c               ó   € V ^8„  d   QhRR/# ©rC   rG   rb   rI   )rJ   s   "rK   rL   r}    s   € ÷ Cñ C˜#ñ CrM   c                	ó,   € R V P                  4       : R2# )z<ThreadLocalLoopProxy target=Ú>)r‰  rˆ  s   &rK   Ú__repr__Ú_ThreadLocalLoopProxy.__repr__  s   € Ø.¨t¯|©|«~Ñ.@ÀÐBÐBrM   r  N)
rh   ri   rj   rk   r¸   r�  r‰  r�  r“  rm   rI   rM   rK   rz  rz    s!   † ÙLõ"õLõ-÷Cñ CrM   rz  c               ó    € V ^8„  d   QhRRRR/# )rC   Úws_client_moduler
   rG   rI  rI   )rJ   s   "rK   rL   rL     s   € ÷ 5'ñ 5'°ð 5'¸ñ 5'rM   c                ó´  aa€ \         ;_uu_ 4        \        '       d    RRR4       R# \        V P                  4      V n        V P                  P
                  oR V3R llpSVn        \        SRR4      Vn        WP                  n        V P                  P                  oR V3R llpW P                  n
        RsRRR4       R#   + '       g   i     R# ; i)	zCInstall the thread-dispatching shims once per process (idempotent).Nc               ó$   € V ^8„  d   QhRRRRRR/# )rC   Úargsr
   ÚkwargsrG   rI   )rJ   s   "rK   rL   Ú0_install_lark_ws_isolation.<locals>.__annotate__(  s!   € ÷ 	1ñ 	1 Sð 	1°Cð 	1¸Cñ 	1rM   c                 óž   <€ \        \        R R4      ;'       g    / pVP                  4        F  w  r4VP                  W44       K  	  S! V / VB # )Úconnect_kwargsN)rÎ   r‡  r  Ú
setdefault)r™  rš  Ú	overridesrî   rè   Úreal_connects   *,   €rK   Ú_dispatch_connectÚ5_install_lark_ws_isolation.<locals>._dispatch_connect(  sM   ø€ ÜÔ 3Ð5EÀtÓL×RÐRÐPRˆIØ'Ÿo™oÖ/‘
�Ø×!Ñ! #Ö-ñ 0á Ð0¨Ñ0Ð0rM   rh   Úconnectc               ó    € V ^8„  d   QhRRRR/# )rC   r|   r
   rG   rI  rI   )rJ   s   "rK   rL   r›  5  s   € ÷ 	2ñ 	2¸#ð 	2À$ñ 	2rM   c              “  ó‚  <"  € \        \        R R4      pVe   V! 4         S! V 4      G Rj  x€L
  R#  L  \         d}    \        \        RR4      pTe   \        TRR4      '       d   \        P	                  R4       M\        P                  RRR7       \        P                  ! 4       P                  4         R# i ; i5i)Ú
on_link_upNÚadapterÚ_runningTzZ[Feishu] lark WS receive loop died; stopping the worker loop so the supervisor can rebuildz5[Feishu] lark WS receive loop ended during disconnect©Úexc_info)	rÎ   r‡  Ú	ExceptionÚloggerÚ	exceptionÚdebugrQ   Úget_running_loopÚstop)r|   r¦  r§  Úoriginal_receive_loops   &  €rK   Ú!_receive_message_loop_exit_notifyÚE_install_lark_ws_isolation.<locals>._receive_message_loop_exit_notify5  s£   øé € ô !Ô!4°lÀDÓIˆJØÒ%Ù”ð2Ù+¨DÓ1×1Ô1øÜô 2ô "Ô"5°yÀ$ÓG�Ø’?¤g¨g°zÀ4×&HÒ&HÜ×$Ñ$ð=õô —L‘LÐ!XÐcg�LÔhÜ×(Ò(Ó*×/Ñ/×1ð)2üs2   ƒB?¡5 ¬3­5 ±B?³5 µBB<Â8B?Â;B<Â<B?T)Ú_WS_ISOLATION_LOCKÚ_WS_ISOLATION_INSTALLEDrz  r†  Ú
websocketsr£  Ú__wrapped__rÎ   rh   ÚClientÚ_receive_message_loop)r–  r¡  r²  r±  r   s   &  @@rK   Ú_install_lark_ws_isolationrº    s¸   ù€ ÷ 
Ö	ß"Ó"Ø÷ 
Ñ	ô !6Ð6F×6KÑ6KÓ LÐÔØ'×2Ñ2×:Ñ:ˆ÷	1ð 	1ð )5ÐÔ%Ü%,¨\¸:ÀyÓ%QÐÔ"Ø.?×#Ñ#Ô+à 0× 7Ñ 7× MÑ MÐ÷	2ð 	2ð< 9Z×ÑÔ5Ø"&Ð÷e 
×	×	Ò	ús   ‘C©BCÃC	c               ó$   € V ^8„  d   QhRRRRRR/# )rC   Ú	ws_clientr
   r§  rG   rI  rI   )rJ   s   "rK   rL   rL   W  s&   € ÷ M'ñ M'¨cð M'¸Cð M'ÀDñ M'rM   c           	     ód  a aaaaa€ ^ RI Hu Hp \        P                  ! 4       p\        P
                  ! V4       VSn        \        S RR4      oR VVV 3R lloRSP                  3RSP                  33 UUu/ uF  w  rEVf   K  WEbK  	  pppSP                  oR VVV 3R lloR	 VVV 3R
 llp\        V4       V\        n        V\        n        V\        n        S\        n        R VV3R llpSe   VS n        S! 4         S P%                  4        R\        n        R\        n        R\        n        R\        n        Se   SS n        \        P(                  ! V4       U	u. uF  q™P*                  ! 4       '       d   K  V	NK  	  p
p	V
 F  pVP-                  4        K  	  V
'       d&   VP/                  \        P0                  ! V
RR/ 4       VP2                  VP4                  3 F  p V! 4        K  	  RSn        R# u uppi   \&         d     Lýi ; iu up	i   \&         d     KB  i ; i  R\        n        R\        n        R\        n        R\        n        Se   SS n        \        P(                  ! T4       U	u. uF  q™P*                  ! 4       '       d   K  T	NK  	  Mu up	i p
p	T
 F  pTP-                  4        K  	  T
'       d&   TP/                  \        P0                  ! T
RR/ 4       TP2                  TP4                  3 F  p T! 4        K    \&         d     K  i ; i	  RSn        i ; i)zYRun the official Lark WS client in its own thread-local loop (see isolation notes above).NÚ
_configurec               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   Ú4_run_official_feishu_ws_client.<locals>.__annotate__`  s   € ÷ `ñ `¨ñ `rM   c                 óì   <€  SP                   Sn        SP                  Sn        SP                  e   SP                  Sn        S Sn        R #   \         d    \        P                  RRR7        R # i ; i)Nz4[Feishu] Failed to apply websocket runtime overridesTr©  )
Ú_ws_reconnect_nonceÚ_reconnect_nonceÚ_ws_reconnect_intervalÚ_reconnect_intervalÚ_ws_ping_intervalÚ_ping_intervalÚon_reconnectingr«  r¬  r®  )Ú_on_reconnectingr§  r¼  s   €€€rK   Ú_apply_runtime_ws_overridesÚC_run_official_feishu_ws_client.<locals>._apply_runtime_ws_overrides`  sl   ø€ ð
	`Ø)0×)DÑ)DˆIÔ&Ø,3×,JÑ,JˆIÔ)Ø×(Ñ(Ò4Ø+2×+DÑ+D�	Ô(ð )9ˆIÖ%øÜô 	`Ü�L‰LÐOÐZ^ˆL×_ð	`ús   ƒAA Á"A3Á2A3Úping_intervalÚping_timeoutc               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rÀ  t  s   € ÷ Tñ T˜dñ TrM   c                 ó|   <€ Se7   SP                  4       '       g   SP                  S P                  S4       R # R # R # r{   )Ú	is_closedÚcall_soon_threadsafeÚ_ws_link_retrying©r§  Úadapter_loopr¼  s   €€€rK   rÉ  Ú8_run_official_feishu_ws_client.<locals>._on_reconnectingt  s6   ø€ ØÒ#¨L×,BÑ,B×,DÒ,DØ×-Ñ-¨g×.GÑ.GÈÖSñ -EÑ#rM   c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rÀ  x  s   € ÷ Nñ N˜ñ NrM   c                 ó|   <€ Se7   SP                  4       '       g   SP                  S P                  S4       R # R # R # r{   )rÐ  rÑ  Ú_ws_link_uprÓ  s   €€€rK   Ú_on_link_upÚ3_run_official_feishu_ws_client.<locals>._on_link_upx  s8   ø€ ð Ò#¨L×,BÑ,B×,DÒ,DØ×-Ñ-¨g×.AÑ.AÀ9ÖMñ -EÑ#rM   c               ó    € V ^8„  d   QhRRRR/# )rC   Úconfr
   rG   rI   )rJ   s   "rK   rL   rÀ  …  s   € ÷ ñ ¨ð °ñ rM   c                óD   <€ Sf   \        R4      hS! V 4      pS! 4        V# )NzFFeishu _configure_with_overrides called but original_configure is None)ÚRuntimeError)rÜ  re  rÊ  Úoriginal_configures   & €€rK   Ú_configure_with_overridesÚA_run_official_feishu_ws_client.<locals>._configure_with_overrides…  s*   ø€ ØÒ%ÜÐgÓhÐhÙ# DÓ)ˆÙ#Ô%ØˆrM   Úreturn_exceptionsT)Úlark_oapi.ws.clientÚwsÚclientrQ   Únew_event_loopÚset_event_loopÚ_ws_thread_looprÎ   rÆ  Ú_ws_ping_timeoutÚ_looprº  r‡  r†  r�  r¦  r§  r¾  Ústartr«  Ú	all_tasksÚdoneÚcancelÚrun_until_completeÚgatherr°  Úclose)r¼  r§  r–  r†  rî   rè   Úconnect_overridesrÙ  rà  r   ÚpendingÚtaskÚcloserrÊ  rÉ  rÔ  rß  s   ff           @@@@rK   Ú_run_official_feishu_ws_clientrö  W  sÎ  ý€ ç2Ð2ä×!Ò!Ó#€DÜ×Ò˜4Ô Ø"€GÔÜ  ¨L¸$Ó?Ð÷`ò `ð ,¨W×-FÑ-FÐGÈ.ÐZa×ZrÑZrÐIsÑtôát‰JˆCØô 	ˆŠ
Ùtð ñ ð
 —=‘=€L÷Tò T÷Nò Nô Ð/Ô0Ø#ÔÔØ):ÔÔ&Ø%0ÔÔ"Ø")ÔÔ÷ñ ð Ò%Ø8ˆ	ÔÙÔ!ð'Ø�‰Ôð $(ÔÔ Ø-1ÔÔ*Ø)-ÔÔ&Ø&*ÔÔ#ØÒ)Ø#5ˆIÔ Ü%×/Ò/°Ô5ÓFÑ5˜¿VºV¿X—1�1Ñ5ˆÐFÛˆDØ�K‰KŽMñ çØ×#Ñ#¤G§N¢N°GÐ$TÈtÑ$TÔUØ—y‘y $§*¡*Ó-ˆFðÙ–ñ .ð
 #'ˆÖùóoøôH ô Ùðüò Gøô ô Úðûð $(ÔÔ Ø-1ÔÔ*Ø)-ÔÔ&Ø&*ÔÔ#ØÒ)Ø#5ˆIÔ Ü%×/Ò/°Ô5ÓFÑ5˜¿VºV¿X—1�1Ò5ùÒFˆÐFÛˆDØ�K‰KŽMñ çØ×#Ñ#¤G§N¢N°GÐ$TÈtÑ$TÔUØ—y‘y $§*¡*Ó-ˆFðÙ–øÜô Úðúñ .ð
 #'ˆÕúsŒ   Á9G?ÂG?ÄH Å$HÆHÇ+HÈHÈH- ÈHÈH- ÈH*È)H*È-AL/É=J!ÊJ!Ê (L/Ë	A L/Ì
LÌL/ÌL"	ÌL/Ì!L"	Ì"L/c               ó   € V ^8„  d   QhRR/# ©rC   rG   rr   rI   )rJ   s   "rK   rL   rL   §  s   € ÷ ñ ˜ñ rM   c                 ó.  € \         '       d   R# \        ;_uu_ 4        \         '       d    RRR4       R# ^ RIp  RV P                  R4      /p\         F@  w  r#V P                  V4      pTP                  V Uu/ uF  qU\        WE4      bK  	  up4       KB  	  V P                  R4      P                  VR&   RTR&   \        4       P                  T4        RRR4       R# u upi   \        \        3 d     RRR4       R# i ; i  + '       g   i     R# ; i)	zDImport and bind the Feishu SDK after an explicit connection request.TNr\   Ú	lark_oapizlark_oapi.wsÚFeishuWSClientFÚFEISHU_AVAILABLE)rü  Ú_lark_import_lockÚ	importlibÚimport_moduleÚ_LARK_SDK_IMPORTSÚupdaterÎ   r¸  ÚImportErrorÚAttributeErrorÚglobals)rþ  ÚboundÚmodule_namer¹  Úmodulerp   s         rK   Ú_load_lark_oapir  §  sø   € çÓÙß	Ö	ßÓØ÷ 
Ñ	ó 	ð	Ø%+¨Y×-DÑ-DÀ[Ó-QÐ$RˆEß&7Ñ"�Ø"×0Ñ0°Ó=�Ø—‘ÁeÓLÁe¸d¤G¨FÓ$9Ò9ÁeÑLÖMñ '8ð '0×&=Ñ&=¸nÓ&M×&TÑ&TˆEÐ"Ñ#ð %)ˆÐ Ñ!Ü‹	×Ñ˜ÔØ÷ 
Ñ	ùò Møäœ^Ð,ô 	Ø÷ 
Ñ	ð	ú÷ 
×	Ð	úsE   �DµDº>C#Á8CÂ)C#Â5DÃC#Ã#D Ã4DÃ?D Ä DÄD	c               ó   € V ^8„  d   QhRR/# rø  rI   )rJ   s   "rK   rL   rL   ¼  s   € ÷ ñ ˜Tñ rM   c                 ó`   € \         '       d   R#  ^ RIHp  V ! R4      #   \         d     R# i ; i)u  PASSIVE registry ``check_fn``: is lark-oapi installed? Must never install or import the SDK.

Uses cheap importlib.metadata lookups; the real import is deferred to ``_load_lark_oapi``
and the ACTIVE installer is ``check_feishu_requirements`` (``ensure_deps_fn``).

Registry ``check_fn`` â€” called from status displays and config loading, so it must never install
anything. The ACTIVE lazy-installer (``check_feishu_requirements``) is registered as ``ensure_deps_fn``
and runs from ``create_adapter()`` when this returns False (#79812).
T©Ú	availabler[   F)rü  Ú	pm.extrasr  r«  r  s    rK   Úfeishu_deps_presentr  ¼  s2   € ÷ ÓÙðÝ'Ù˜Ó"Ð"øÜô Úðús   � ž-¬-c               ó   € V ^8„  d   QhRR/# rø  rI   )rJ   s   "rK   rL   rL   Ï  s   € ÷ ñ  4ñ rM   c                 ód   € \         '       d   R# ^ RIHp   V ! R4       R#   \         d     R# i ; i)zCEnsure Feishu dependencies are installed without importing the SDK.T©Úensure_importr[   F)rü  Úpmr  r«  r  s    rK   Úcheck_feishu_requirementsr  Ï  s0   € çÓÙå ðÙ�hÔÙøÜô Úðús   –   /®/Úqueriesc               ó$   € V ^8„  d   QhRRRRRR/# ©rC   Úurirb   r  zOptional[list[tuple[str, str]]]rG   r
   rI   )rJ   s   "rK   rL   rL   Ý  s(   € ÷ Añ A˜Sð AÐ.Mð AÐY\ñ ArM   c               ó  € \         P                  4       P                  \        P                  4      P                  V 4      pVe   VP                  V4      pVP                  \        P                  04      P                  4       # )zbRaw ``BaseRequest`` GET with the tenant access token (bot/v3 endpoints have no typed SDK request).)ÚBaseRequestÚbuilderÚhttp_methodÚ
HttpMethodÚGETr  r  Útoken_typesÚAccessTokenTypeÚTENANTÚbuild)r  r  r  s   &$ rK   Ú_tenant_get_requestr#  Ý  sa   € ä×!Ñ!Ó#×/Ñ/´
·±Ó?×CÑCÀCÓH€GØÒØ—/‘/ 'Ó*ˆØ×Ñ¤× 6Ñ 6Ð7Ó8×>Ñ>Ó@Ð@rM   c               ó    € V ^8„  d   QhRRRR/# )rC   r™   rb   rG   r
   rI   )rJ   s   "rK   rL   rL   å  s   € ÷ Cñ C˜Sð C Sñ CrM   c                ó(   € V R 8X  d   \         # \        # )r\   )ÚLARK_DOMAINÚFEISHU_DOMAIN)r™   s   &rK   Ú_sdk_domainr(  å  s   € Ø%¨Ô/Œ;ÐB´]ÐBrM   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   r—   rb   r˜   Ú
sdk_domainr
   rG   rI   )rJ   s   "rK   rL   rL   é  s.   € ÷ Cñ C˜sð C°ð CÀð CÈñ CrM   c                ó  € \         P                  P                  4       P                  V 4      P	                  V4      P                  V4      P                  \         P                  P                  4      P                  4       # r{   )
r\   r¸  r  r—   r˜   ÚdomainÚ	log_levelÚLogLevelÚWARNINGr"  )r—   r˜   r*  s   &&&rK   Ú_build_lark_clientr0  é  sc   € Ü�;‰;×ÑÓ ×'Ñ'¨Ó/×:Ñ:¸:ÓF×MÑMÈjÓY×cÑcÔdh×dqÑdq×dyÑdyÓz÷  Añ  Aó  Cð  CrM   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   r¶  rb   Úbtn_typerè   r’   rG   rI   )rJ   s   "rK   rL   rL   í  s.   € ÷ pñ p˜ð p sð p°>ð pÀnñ prM   c                ó   € R RRR RRV /RVRV/# )rE  r!  rŒ   Ú
plain_textrO   r   rè   rI   )r¶  r2  rè   s   &&&rK   Ú_card_buttonr5  í  s%   € Ø�8˜V e¨\¸9ÀeÐ%LÈfÐV^Ð`gÐinÐoÐorM   r  c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	rC   r_  rb   ÚtemplateÚmarkdownr  zOptional[list[dict[str, Any]]]rG   r’   rI   )rJ   s   "rK   rL   rL   ñ  s1   € ÷ 	ñ 	�ð 	 ð 	¨sð 	Ð@^ð 	Ðjxñ 	rM   c               óf   € RRRV/.pVe   VP                  RRRV/4       RRR/R	R
RV RR/RV/RV/# )zVWide interactive card: colored header + one markdown block (+ an optional button row).rE  r8  rO   Úactionr  ÚconfigÚwide_screen_modeTr9  r_  r4  r7  r°  ©rM  )r_  r7  r8  r  r°  s   &&&$ rK   Ú_cardr>  ñ  s`   € à',¨j¸)ÀXÐ&NÐ%O€HØÒØ�‰˜ ¨)°WÐ=Ô>àÐ% tÐ,Ø�7˜Y¨¨u°lÐCÀZÐQYÐZØ�Hðð rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   Úrequest_clsr
   ÚfieldsrG   rI   )rJ   s   "rK   rL   rL   ý  s!   € ÷ ñ ˜Cð ¨3ð °3ñ rM   c                ó´   € V f   \        R/ VB # V P                  4       pVP                  4        F  w  r4\        W#4      ! V4      pK  	  VP	                  4       # )z\``request_cls.builder().<field>(value)...build()``; SimpleNamespace when the SDK is unbound.rI   )r	   r  r  rÎ   r"  )r@  rA  r  rp   rè   s   &,   rK   Ú
_sdk_buildrC  ý  sQ   € àÒÜÑ( Ñ(Ð(Ø×!Ñ!Ó#€GØ—|‘|–~‰ˆÜ˜'Ô(¨Ó/Šñ &à�=‰=‹?ÐrM   c                  óÐ  a € ] tR tRt$ RtRtR]R&   RtRtRt	Rt
RtR]R	&   R
tR V 3R llt]R R l4       tR R ltR R ltR R ltR 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ER–R) R* lltR+R/R, R- lltR. R/ ltR0tR1t ]!R2 R3 l4       t"]!R4 R5 l4       t#]!R6 R7 l4       t$R8R9R:R;R<R=R>R>/t%R? R@ lt&RA RB lt']RC RD l4       t(ER—RE RF llt)]RG RH l4       t*]RI RJ l4       t+]RK RL l4       t,ER˜RM RN llt-ER™RO RP llt.ER˜RQ RR llt/ER˜RS RT llt0ERšRU RV llt1ER˜RW V 3RX lllt2ER˜RY V 3RZ lllt3R[ R\ lt4R] R^ lt5R_ R` lt6Ra Rb lt7Rc Rd lt8Re Rf lt9Rg Rh lt:Ri Rj lt;Rk Rl lt<Rm Rn lt=Ro Rp lt>Rq Rr lt?Rs Rt lt@Ru Rv ltARw Rx ltBRy Rz ltCR{ R| ltD]R} R~ l4       tER R€ ltFR� R‚ ltG]ERšRƒ R„ ll4       tHR… R† ltIR‡ Rˆ ltJR‰ RŠ ltKR‹ RŒ ltLR�R0RŽR0/R� R� lltMR�R0RŽR0/R‘ R’ lltNR“ R” ltOR• R– ltPR— R˜ ltQR™ Rš ltRR› Rœ ltSR� Rž ltTRŸ R  ltUR¡ R¢ ltVR£ R¤ ltWR¥ R¦ ltXR§ R¨ ltYR© Rª ltZR« R¬ lt[R­ R® lt\ERšR¯ R° llt]R±R/R² R³ llt^R´ Rµ lt_R¶ R· lt`R¸ R¹ lta]Rº R» l4       tbR¼ R½ ltcR¾ R¿ ltdRÀ RÁ lte]RÂ RÃ l4       tfRÄ RÅ ltgRÆ RÇ lthRÈ RÉ lti]RÊ RË l4       tj]RÌ RÍ l4       tk]RÎ RÏ l4       tlER–RÐ RÑ lltmRÒ RÓ ltnRÔRÕRÖR×RØRÙRÚRÛRÜRÝRÞRßRàRá/toRâ Rã ltpRä Rå ltq]Ræ Rç l4       trRè Ré ltsRê Rë ltt]Rì Rí l4       tuRî Rï ltvRð Rñ ltwRò Ró ltxRô Rõ ltyRö R÷ ltz]Rø Rù l4       t{Rú Rû lt|Rü Rý lt}Rþ Rÿ lt~ER  ER ltER ER lt€]ER ER l4       t�]ER ER l4       t‚]ER ER	 l4       tƒ]ER
 ER l4       t„]ER ER l4       t…]ER ER l4       t†]ER ER l4       t‡]ER ER l4       tˆ]ER ER l4       t‰R±R/ER ER lltŠER ER lt‹R±R/ER ER lltŒERR(/ER ER llt�ER ER  ltŽER! ER" lt�ER#R(/ER$ ER% llt�]ER& ER' l4       t‘]ER( ER) l4       t’ER* ER+ lt“Rt”ER, ER- lt•ER. ER/ lt–ER›R±R/ER0 ER1 lllt—ER2 ER3 lt˜ER4 ER5 lt™ER6 ER7 ltšER8 ER9 lt›ER: ER; ltœER< ER= lt�ER> ER? ltžER@ ERA ltŸERB ERC lt ERDR/ERE ERF llt¡]ERG ERH l4       t¢ERIR(ERJR(ERKERL/ERM ERN llt£ERO ERP lt¤ERQ ERR lt¥ERS ERT lt¦]ERU ERV l4       t§]ERW ERX l4       t¨ERYR(/ERZ ER[ llt©ER\ ER] ltªER^ ER_ lt«ER` ERa lt¬ERb ERc lt­ERd ERe lt®ERf ERg lt¯ERh ERi lt°ERj ERk lt±ERl ERm lt²ERn ERo lt³ERp ERq lt´]ERr ERs l4       tµ]ERt ERu l4       t¶]ERv ERw l4       t·]ERx ERy l4       t¸]ERz ER{ l4       t¹]ER| ER} l4       tº]ER~ ER l4       t»]ER€ ER� l4       t¼]ER‚ ERƒ l4       t½]ER„ ER… l4       t¾]ER† ER‡ l4       t¿]ERˆ ER‰ l4       tÀ]ERŠ ER‹ l4       tÁ]ERŒ^ /ER� ERŽ ll4       tÂ]ER� ER� l4       tÃER‘ ER’ ltÄ]ER“ ER” l4       tÅER•tÆV ;tÇ# (œ  ÚFeishuAdapteri  zFeishu/Lark bot adapter.Trr   Úserves_profile_prefixé@  éè  rF   ÚCHAT_LOCK_MAX_SIZEr7   c               ó   € V ^8„  d   QhRR/# )rC   r;  r   rI   )rJ   s   "rK   rL   ÚFeishuAdapter.__annotate__  s   € ÷ 1&ñ 1&˜~ñ 1&rM   c                	ón  <€ \         SV `  V\        P                  4       T P	                  VP
                  ;'       g    / 4      V n        V P                  V P                  4       R V n        \        P                  ! 4       V n        R V n        RV n        R ;V n        ;V n        ;V n        V n        RV n        R V n        R ;V n        ;V n        V n        / V n        . V n        \3        4       R,          V n        \        P                  ! 4       V n        \8        P                  ! 4       V n        / V n        / V n        / V n         / V n!        . V n"        \        P                  ! 4       V n#        RV n$        RV n%        \L        PN                  ! 4       V n(        / V n)        \O        4       V n*        R V n+        \Y        4       V n-        V PZ                  P\                  V n/        V PZ                  P`                  V n1        V PZ                  Pd                  V n3        \Y        4       V n4        V Ph                  P\                  V n5        V Ph                  P`                  V n6        / V n7        \p        Pr                  ! ^4      V n:        / V n;        \p        Pr                  ! ^4      V n<        \O        4       V n=        V P}                  4        R # )NFç      @zfeishu_seen_message_ids.jsonrH  )?Úsuperr�  r   ÚFEISHUÚ_load_settingsÚextraÚ	_settingsÚ_apply_settingsÚ_clientÚ	threadingÚLockÚ_sdk_executor_lockÚ_sdk_executorÚ_sdk_executor_closingÚ
_ws_clientÚ
_ws_futureÚ_ws_supervisorrè  Ú_ws_restart_backoffrê  Ú_webhook_runnerÚ_webhook_siteÚ_event_handlerÚ_seen_message_idsÚ_seen_message_orderr'   Ú_dedup_state_pathÚ_dedup_lockrQ   Ú_dedup_persist_lockÚ_sender_name_cacheÚ_webhook_rate_countsÚ_webhook_anomaly_countsÚ_card_action_tokensÚ_pending_inbound_eventsÚ_pending_inbound_lockÚ_pending_drain_scheduledÚ_pending_inbound_max_depthÚcollectionsr   Ú_chat_locksÚ_chat_info_cacheÚ_message_text_cacheÚ_app_lock_identityrÂ   Ú_text_batch_staterÃ   Ú_pending_text_batchesrÅ   Ú_pending_text_batch_tasksrÆ   Ú_pending_text_batch_countsÚ_media_batch_stateÚ_pending_media_batchesÚ_pending_media_batch_tasksÚ_approval_stater�  ÚcountÚ_approval_counterÚ_update_prompt_stateÚ_update_prompt_counterÚ_pending_processing_reactionsÚ_load_seen_message_ids)r|   r;  Ú	__class__s   &&€rK   r�  ÚFeishuAdapter.__init__  s'  ø€ Ü‰Ñ˜¤§¡Ô1Ø×,Ñ,¨V¯\©\×-?Ð-?¸RÓ@ˆŒØ×Ñ˜TŸ^™^Ô,Ø&*ˆŒô #,§.¢.Ó"2ˆÔØNRˆÔØ%*ˆÔ"ØY]Ð]ˆŒÐ]˜$œ/Ð]¨DÔ,?À$ÔBVØ#&ˆÔ Ø:>ˆŒ
ØJNÐNˆÔÐN˜tÔ1°DÔ4GØ35ˆÔØ.0ˆÔ Ü!0Ó!2Ð5SÕ!SˆÔÜ$Ÿ>š>Ó+ˆÔô $+§<¢<£>ˆÔ Ø@BˆÔØBDˆÔ!ØJLˆÔ$Ø57ˆÔ à24ˆÔ$Ü%.§^¢^Ó%5ˆÔ"Ø(-ˆÔ%Ø*.ˆÔ'ÜGR×G^ÒG^ÓG`ˆÔØ;=ˆÔÜDOÃMˆÔ Ø15ˆÔÜ!1Ó!3ˆÔØ%)×%;Ñ%;×%BÑ%BˆÔ"Ø)-×)?Ñ)?×)EÑ)EˆÔ&Ø*.×*@Ñ*@×*GÑ*GˆÔ'Ü"2Ó"4ˆÔØ&*×&=Ñ&=×&DÑ&DˆÔ#Ø*.×*AÑ*A×*GÑ*GˆÔ'à:<ˆÔÜ!*§¢°Ó!3ˆÔØ?AˆÔ!Ü&/§o¢o°aÓ&8ˆÔ#äDOÃMˆÔ*Ø×#Ñ#Ö%rM   c               ó    € V ^8„  d   QhRRRR/# )rC   rQ  r’   rG   r–   rI   )rJ   s   "rK   rL   rK  H  s   € ÷ E
ñ E
˜nð E
Ð1Fñ E
rM   c                	ó”  a a
€ R  R lpRMR R llo
RMR V 3R lllpTpS P                  R/ 4      p/ p\        V\        4      '       dÇ   VP                  4        F²  w  rg\        V\        4      '       g   K  \	        \        VP                  RR	4      4      P                  4       P                  4       V! VP                  R
. 4      4      V! VP                  R. 4      4      RV9   d   \        VR,          4      MRR7      V\        V4      &   K´  	  \        V! RRR4      ;'       g    R4      P                  4       P                  4       pVRN9  d   \        P                  RV4       Rp\        ;QJ d    V
3R lRO 4       F  '       g   K   RM	  RM! V
3R lRO 4       4      p	\        RP/ RV! RR4      bRV! RR4      bRV! RRR4      P                  4       bRV! RRR 4      P                  4       bR!V! R!R"4      bR#V! R#R$4      bR%S
! R&R
4      P                  4       bR'\        V! \        R(R4      P                  R)4      4      4      bR*S
! R+4      bR,S
! R-4      bR.S
! R/4      bR0\!        ^ \#        R1\$        4      4      bR2\'        R3\(        4      bR4\'        R5R64      bR7\!        ^\#        R8\*        4      4      bR9\!        ^\#        R:\,        4      4      bR;\'        R<\.        4      bR=V! R=R>\0        4      bR?\3        S P                  R?4      ;'       g    \        R@\        \4        4      4      4      bRAV! RARB\6        4      ;'       g    \6        bRC\9        S P                  RC4      ^^ RD7      bRE\9        S P                  RE4      ^x^RD7      bRF\;        S P                  RF4      R^RD7      bRG\;        S P                  RG4      R^RD7      bRH\        V! S P                  RH. 4      4      4      bRI\        S P                  RIR4      4      P                  4       P                  4       bRVbRVbRJV	bR\        S P                  R\        RKRL4      4      4      b # )Qc               ó    € V ^8„  d   QhRRRR/# )rC   rƒ  r
   rG   r½   rI   )rJ   s   "rK   rL   Ú2FeishuAdapter._load_settings.<locals>.__annotate__I  s   € ÷ 	Fñ 	F˜Cð 	F Hñ 	FrM   c                ó    € V  Uu0 uF=  p\        V4      P                  4       '       g   K$  \        V4      P                  4       kK?  	  up# u upi r{   )rb   r  )rƒ  Úus   & rK   Ú_id_setÚ-FeishuAdapter._load_settings.<locals>._id_setI  s2   € Ù,2ÓE©F q´c¸!³f·l±l·n”N”C˜“F—L‘L–N©FÑEÐEùÒEs
   …!A«Ard   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rp   rb   r,  rG   rI   )rJ   s   "rK   rL   r†  L  s!   € ÷ 	=ñ 	=˜#ð 	=¨ð 	=°Sñ 	=rM   c                ó4   € \        W4      P                  4       # r{   )Ú_get_scoped_secretr  )rp   r,  s   &&rK   Ú_secretÚ-FeishuAdapter._load_settings.<locals>._secretL  s   € Ü% dÓ4×:Ñ:Ó<Ð<rM   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   rî   rb   Úenvr,  rG   rI   )rJ   s   "rK   rL   r†  O  s.   € ÷ 	Rñ 	R #ð 	R¨Cð 	R¸#ð 	RÀsñ 	RrM   c                óL   <€ \        \        SWV4      4      P                  4       # r{   )rb   Ú_shared_extra_or_secretr  )rî   r‘  r,  rQ  s   &&&€rK   Ú_extra_or_secretÚ6FeishuAdapter._load_settings.<locals>._extra_or_secretO  s!   ø€ ÜÔ.¨u°cÀÓHÓI×OÑOÓQÐQrM   r³   r¼   Úopenr¾   r¿   r¶   N)r¼   r¾   r¿   r¶   rµ   ÚFEISHU_ALLOW_BOTSr´   zS[Feishu] Unknown allow_bots=%r, falling back to 'none'. Valid: none, mentions, all.c              3  óV   <"  € T F  pS! V4      P                  4       R9   x € K   	  R# 5i)rê   N>   Ú1Úyesrê   )r±  )rÕ   ÚvarrŽ  s   & €rK   r×   Ú/FeishuAdapter._load_settings.<locals>.<genexpr>m  s(   øé € ð 
ÙDy¸S‰G�C‹L×ÑÓ Ð$8Ö8ÓDyùs   ƒ&)TFr—   ÚFEISHU_APP_IDr˜   ÚFEISHU_APP_SECRETr™   r,  r'  r[   rš   ÚFEISHU_CONNECTION_MODEÚ	websocketr›   ÚFEISHU_ENCRYPT_KEYrœ   ÚFEISHU_VERIFICATION_TOKENr�   ÚFEISHU_GROUP_POLICYrž   ÚFEISHU_ALLOWED_USERSÚ,rŸ   ÚFEISHU_BOT_OPEN_IDr    ÚFEISHU_BOT_USER_IDr¡   ÚFEISHU_BOT_NAMEr¢   ÚHERMES_FEISHU_DEDUP_CACHE_SIZEr¤   Ú&HERMES_FEISHU_TEXT_BATCH_DELAY_SECONDSr¥   Ú,HERMES_FEISHU_TEXT_BATCH_SPLIT_DELAY_SECONDSg       @r¦   Ú%HERMES_FEISHU_TEXT_BATCH_MAX_MESSAGESr§   Ú"HERMES_FEISHU_TEXT_BATCH_MAX_CHARSr¨   Ú'HERMES_FEISHU_MEDIA_BATCH_DELAY_SECONDSr©   ÚFEISHU_WEBHOOK_HOSTrª   ÚFEISHU_WEBHOOK_PORTr«   ÚFEISHU_WEBHOOK_PATHr¬   r5  r­   r¯   r°   r±   r²   r·   ÚFEISHU_REQUIRE_MENTIONrê   rÄ  >   Úallr´   r�   )ÚFEISHU_ALLOW_ALL_USERSÚGATEWAY_ALLOW_ALL_USERSrI   )rñ   r  r”   r  r»   rb   r  r±  rë   r¬  Úwarningr´  r–   r¹   r�  rQ  rø   r*   Ú_DEFAULT_DEDUP_CACHE_SIZEr)   Ú!_DEFAULT_TEXT_BATCH_DELAY_SECONDSÚ _DEFAULT_TEXT_BATCH_MAX_MESSAGESÚ_DEFAULT_TEXT_BATCH_MAX_CHARSÚ"_DEFAULT_MEDIA_BATCH_DELAY_SECONDSÚ_DEFAULT_WEBHOOK_HOSTrF   Ú_DEFAULT_WEBHOOK_PORTÚ_DEFAULT_WEBHOOK_PATHr6  r2  )rQ  r‰  r”  Ú_extra_or_envÚraw_group_rulesr³   rö  Úrule_cfgrµ   r·   rŽ  s   f         @rK   rP  ÚFeishuAdapter._load_settingsG  s]  ù€ õ	F÷	=÷	Rò 	Rð )ˆàŸ)™) M°2Ó6ˆØ24ˆÜ�o¤t×,Ò,Ø%4×%:Ñ%:Ö%<Ñ!�Ü! (¬D×1Ò1ÙÜ,;Ü˜xŸ|™|¨H°fÓ=Ó>×DÑDÓF×LÑLÓNÙ% h§l¡l°;ÀÓ&CÓDÙ% h§l¡l°;ÀÓ&CÓDàPaÐemÔPm¤K°Ð9JÕ0KÔ$LÐswô-�œC ›LÓ)ñ &=ô Ñ)¨,Ð8KÈVÓT×^Ð^ÐX^Ó_×eÑeÓg×mÑmÓoˆ
ØÐ8Ô8Ü�N‰NØeØôð  ˆJç“sô 
ÙDyó
—s—s’sô 
ÙDyó
ó 
ˆô %ò 
Ù# H¨oÔ>ð
á'¨Ð6IÔJð
ñ & h°ÀÓJ×PÑPÔRð
ñ *Ð*;Ð=UÐWbÓc×iÑiÔkð	
ñ
 )¨Ð8LÔMð
ñ  0Ð0DÐFaÔbð
ñ !Ð!6¸ÓD×JÑJÔLð
ô !*©'Ô2DÐE[Ð]_Ó2`×2fÑ2fÐgjÓ2kÓ*lÔ mð
ñ  Ð 4Ô5ð
ñ  Ð 4Ô5ð
ñ Ð.Ô/ð
ô ! ¤WÐ-MÔOhÓ%iÔjð
ô &/Ð/WÔYzÔ%{ð
ô ,5Ð5cÐehÔ+ið
ô %(¨¬7Ð3ZÔ\|Ó+}Ô$~ð
ô  "% Q¬Ð0TÔVsÓ(tÔ!uð!
ô" '0Ð0YÔ[}Ô&~ð#
ñ$ ' ~Ð7LÔNcÔdð%
ô& ˜UŸY™Y ~Ó6×ÐÔ:LÐMbÔdgÔh}Ód~Ó:ô  Að'
ñ( ' ~Ð7LÔNcÓd×}Ð}Ôh}øð)
ô*  4°E·I±IÐ>RÓ4SÐ]_ÐklÕmð+
ô, #7°u·y±yÐAXÓ7YÐcfÐrsÕ"tð-
ô. )¨¯©Ð3EÓ)FÐPTÐ`aÕbð/
ô0 (¨¯	©	Ð2CÓ(DÈdÐ^_Õ`ð1
ô2 ™W U§Y¡Y¨x¸Ó%<Ó=Ô>ð3
ô4 "% U§Y¡YÐ/EÀrÓ%JÓ!K×!QÑ!QÓ!S×!YÑ!YÔ![ð5
ñ6 $ð7
ñ6 1;ð7
ñ6 JVð7
ô8 (¨¯	©	Ð2CÔEWÐXpÐrxÓEyÓ(zÔ{ð9
ð 	
rM   c               ó    € V ^8„  d   QhRRRR/# )rC   Úsettingsr–   rG   rI  rI   )rJ   s   "rK   rL   rK  �  s   € ÷ \ñ \Ð(=ð \À$ñ \rM   c           	     	ó  € \         P                   F  p\        V R V 2\        W4      4       K  	  \	        VP
                  4      V n        \	        VP                  4      V n        VP                  ;'       g    VP                  V n        R# )Ú_N)r–   Ú__dataclass_fields__ÚsetattrrÎ   rÀ   rž   Ú_allowed_group_usersr±   Ú_adminsr²   r�   Ú_default_group_policy)r|   rÄ  rp   s   && rK   rS  ÚFeishuAdapter._apply_settings�  sh   € ä)×>Ô>ˆDÜ�D˜A˜d˜V˜*¤g¨hÓ&=Ö>ñ ?ä$'¨×(DÑ(DÓ$EˆÔ!Ü˜8Ÿ?™?Ó+ˆŒØ%-×%BÑ%B×%[Ð%[Àh×F[ÑF[ˆÖ"rM   c               ó   € V ^8„  d   QhRR/# r„  rI   )rJ   s   "rK   rL   rK  —  s   € ÷ 
ñ 
 cñ 
rM   c                	óš  a € \         f   R # \         P                  S P                  S P                  4      P	                  S P
                  4      P                  S P                  4      P                  V 3R l4      P                  V 3R l4      P                  S P                  4      P                  S P                  4      P                  S P                  4      P!                  S P"                  4      P%                  S P&                  4      P)                  RS P*                  4      P)                  RS P,                  4      P/                  4       # )Nc                ó(   <€ SP                  R V 4      # )úim.message.reaction.created_v1©Ú_on_reaction_event©Údr|   s   &€rK   r$  Ú4FeishuAdapter._build_event_handler.<locals>.<lambda>ž  ó   ø€ À$×BYÑBYÐZzÐ|}ÔB~rM   c                ó(   <€ SP                  R V 4      # )úim.message.reaction.deleted_v1rÑ  rÓ  s   &€rK   r$  rÕ  Ÿ  rÖ  rM   údrive.notice.comment_add_v1úvc.bot.meeting_invited_v1)ÚEventDispatcherHandlerr  Ú_encrypt_keyÚ_verification_tokenÚ&register_p2_im_message_message_read_v1Ú_on_message_read_eventÚ!register_p2_im_message_receive_v1Ú_on_message_eventÚ*register_p2_im_message_reaction_created_v1Ú*register_p2_im_message_reaction_deleted_v1Úregister_p2_card_action_triggerÚ_on_card_action_triggerÚ'register_p2_im_chat_member_bot_added_v1Ú_on_bot_added_to_chatÚ)register_p2_im_chat_member_bot_deleted_v1Ú_on_bot_removed_from_chatÚ8register_p2_im_chat_access_event_bot_p2p_chat_entered_v1Ú_on_p2p_chat_enteredÚ"register_p2_im_message_recalled_v1Ú_on_message_recalledÚregister_p2_customized_eventÚ_on_drive_comment_eventÚ_on_meeting_invited_eventr"  rˆ  s   frK   Ú_build_event_handlerÚ"FeishuAdapter._build_event_handler—  së   ø€ Ü!Ò)Ùä"×*Ñ*¨4×+<Ñ+<¸d×>VÑ>VÓWß3Ñ3°D×4OÑ4OÓPß.Ñ.¨t×/EÑ/EÓFß7Ñ7Ô8~Óß7Ñ7Ô8~Óß,Ñ,¨T×-IÑ-IÓJß4Ñ4°T×5OÑ5OÓPß6Ñ6°t×7UÑ7UÓVßEÑEÀd×F_ÑF_Ó`ß/Ñ/°×0IÑ0IÓJß)Ñ)Ð*GÈ×IeÑIeÓfß)Ñ)Ð*EÀt×GeÑGeÓfß‰U‹Wð	
rM   c               ó   € V ^8„  d   QhRR/# )rC   rG   z%concurrent.futures.ThreadPoolExecutorrI   )rJ   s   "rK   rL   rK  ª  s   € ÷ ñ Ð#Hñ rM   c                ó‚  € \        V RR4      pVf   \        P                  ! 4       ;qn        T;_uu_ 4        \        V RR4      '       d   \	        R4      h\        V RR4      pVe   \        VRR4      '       d(   \
        P                  P                  ^
RR	7      pW n        VuuRRR4       #   + '       g   i     R# ; i)
uk  Adapter-owned executor; recreated after an *external* shutdown, never after our own close.

Recreates the pool if it was never built or was shut down by an *external* teardown of the loop's
default executor, so that can no longer permanently wedge sends (#10849). Refuses to resurrect once
the adapter itself is closing â€” a real disconnect/shutdown stays shut.
rW  NrY  Fz9Feishu adapter is shutting down; SDK executor unavailablerX  Ú	_shutdownzhermes-feishu-sdk)Úmax_workersÚthread_name_prefix)	rÎ   rU  rV  rW  rÞ  Ú
concurrentÚfuturesÚThreadPoolExecutorrX  ©r|   ÚlockÚexecutors   &  rK   Ú_get_sdk_executorÚFeishuAdapter._get_sdk_executorª  sž   € ô �tÐ1°4Ó8ˆØŠ<Ü-6¯^ª^Ó-=Ð=ˆDÔ*ßŠTÜ�tÐ4°e×<Ò<Ü"Ð#^Ó_Ð_Ü˜t _°dÓ;ˆHØÒ¤7¨8°[À%×#HÒ#HÜ%×-Ñ-×@Ñ@ÈRÐdwÐ@Óx�Ø%-Ô"Ø÷ �T�T‹Tús   ·A+B-Â-B>	c              ‡  óÊ   "  € \         P                  ! 4       pVP                  ! V P                  4       \        P
                  ! 4       P                  V.VO5!  G Rj  x€L
 #  L5i)zëRun a blocking Feishu SDK call on the adapter-owned thread pool.

``copy_context().run`` mirrors ``asyncio.to_thread``: the worker sees the caller's
profile HERMES_HOME override / secret scope (multiplexed dedup flush, thread lookup).
N)rQ   r¯  Úrun_in_executorrþ  ÚcontextvarsÚcopy_contextrý   )r|   Úfuncr™  r†  s   &&* rK   Ú_run_blockingÚFeishuAdapter._run_blocking½  s^   é € ô ×'Ò'Ó)ˆØ×)Ò)Ø×"Ñ"Ó$¤k×&>Ò&>Ó&@×&DÑ&DÀdðSØMQóS÷ Sð 	Sñ Sùs   ‚AA#ÁA!ÁA#c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  Ç  s   € ÷ *ñ *¨ñ *rM   c                ó*  € \        V RR4      pVf   R# V;_uu_ 4        RV n        \        V RR4      pRV n        RRR4       Xf   R#  VP                  RRR7       R#   + '       g   i     L,; i  \         d    TP                  RR7        R# i ; i)zFStop the adapter-owned SDK executor without touching the loop default.rW  NTrX  F)ÚwaitÚcancel_futures)r	  )rÎ   rY  rX  Úshutdownr/  rû  s   &  rK   Ú_shutdown_sdk_executorÚ$FeishuAdapter._shutdown_sdk_executorÇ  s�   € ä�tÐ1°4Ó8ˆØŠ<ÙßŠTØ)-ˆDÔ&Ü˜t _°dÓ;ˆHØ!%ˆDÔ÷ ð ÒÙð	*Ø×Ñ 5¸ÐÖ>÷ �Tûô ô 	*Ø×Ñ 5Ð×)ð	*ús   žAÁ	A1 ÁA.	Á1BÂBÚis_reconnectFc               ó    € V ^8„  d   QhRRRR/# )rC   r  rr   rG   rI   )rJ   s   "rK   rL   rK  ×  s   € ÷ 2ñ 2¨Tð 2¸dñ 2rM   c             ƒ  óä  "  € RV n         V P                  '       d   V P                  '       g   \        P	                  R4       R# V P
                  R9  d#   \        P	                  RV P
                  4       R# V P
                  R8X  d<   V P                  '       g*   V P                  '       g   \        P	                  R4       R# \        P                  ! \        4      G Rj  x€L
 '       g   \        P	                  R4       R#  V P                  V n        \        \        V P                  R	V P                  P                  /R
7      w  r#V'       gt   \!        V\"        4      '       d   VP%                  R4      MRpRV'       d   RV R2MR,           R,           p\        P	                  RV4       V P'                  RVRR7       R# \        P(                  ! 4       V n        V P-                  4       G Rj  x€L
  V P
                  R8X  d*   \        P.                  ! V P1                  4       4      V n        V P5                  4        \        P7                  RV P
                  V P8                  4       V P;                  V P<                  4       R#  EL§ L™  \>         dV   pT PA                  4       G Rj  x€L 
  RT 2pT P'                  RTRR7       \        P	                  RTRR7        Rp?R# Rp?ii ; i5i)zConnect to Feishu/Lark.Fz3[Feishu] FEISHU_APP_ID or FEISHU_APP_SECRET not setr   ÚwebhookzT[Feishu] Unsupported FEISHU_CONNECTION_MODE=%s. Supported modes: websocket, webhook.zO[Feishu] Webhook mode requires FEISHU_VERIFICATION_TOKEN or FEISHU_ENCRYPT_KEY.Nz [Feishu] lark-oapi not installedÚplatform©r“   Úpidz@Another local Hermes gateway is already using this Feishu app_idz (PID z).Ú.zI Stop the other gateway before starting a second Feishu websocket client.z[Feishu] %sÚfeishu_app_lock)Ú	retryablez"[Feishu] Connected in %s mode (%s)TzFeishu startup failed: Úfeishu_connect_errorz[Feishu] Failed to connect: %sr©  >   r  r   )!rY  Ú_app_idÚ_app_secretr¬  ÚerrorÚ_connection_moderÝ  rÜ  rQ   Ú	to_threadr  rr  r%   Ú_FEISHU_APP_LOCK_SCOPEr  rè   r  r”   rñ   Ú_set_fatal_errorr¯  rê  Ú_connect_with_retryÚensure_futureÚ_supervise_websocket_threadr\  Ú_mark_connectedÚinfoÚ_domain_nameÚ_wire_plugin_handlersrT  r«  Ú_release_app_lock)r|   r  ÚacquiredÚexistingÚ	owner_pidr1   rW   s   &$     rK   r£  ÚFeishuAdapter.connect×  sU  é € à%*ˆÔ"Ø�|�|ˆ| 4×#3×#3Ð#3Ü�L‰LÐNÔOÙØ× Ñ Ð(@Ô@Ü�L‰LØfØ×%Ñ%ôñ Ø× Ñ  IÔ-°t×7O×7OÐ7OÐSW×Sd×SdÐSdÜ�L‰LÐjÔkÙÜ×&Ò&¤Ó7×7Ö7Ü�L‰LÐ;Ô<Ùð	Ø&*§l¡lˆDÔ#Ü!4Ü&¨×(?Ñ(?È:ÐW[×WdÑWd×WjÑWjÐJkô"ÑˆH÷ Ü3=¸hÌ×3MÒ3M˜HŸL™L¨Ô/ÐSW�	àVß1:˜ 	˜{¨"Ñ-ÀõEàaõbð ô
 —‘˜]¨GÔ4Ø×%Ñ%Ð&7¸ÈEÐ%ÔRÙä ×1Ò1Ó3ˆDŒJØ×*Ñ*Ó,×,Ð,Ø×$Ñ$¨Ô3ä&-×&;Ò&;¸D×<\Ñ<\Ó<^Ó&_�Ô#Ø× Ñ Ô"Ü�K‰KÐ<¸d×>SÑ>SÐUY×UfÑUfÔgà×&Ñ& t§|¡|Ô4Ùò; 8ñ* -øô ô 	Ø×(Ñ(Ó*×*Ñ*Ø/°¨uÐ5ˆGØ×!Ñ!Ð"8¸'ÈTÐ!ÔRÜ�L‰LÐ9¸3ÈˆLÔNÝûð	üs…   ‚+K0®A,K0ÂK0Â-4K0Ã!JÃ"	K0Ã,K0ÄA>J Æ?J ÇK0Ç-J Ç1JÇ2BJ ÊK0ÊJ ÊK-ÊK(Ê+J.Ê,6K(Ë"K0Ë(K-Ë-K0c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK    s   € ÷ -ñ - $ñ -rM   c              ƒ  óà  "  € RV n         V P                  e"   V P                  P                  4        RV n        V P                  V P                  4      G Rj  x€L
  V P                  V P
                  4      G Rj  x€L
  V P                  4        V P                  pV P                  pV P                  4        V P                  4       G Rj  x€L
  V P                  W4      G Rj  x€L
  RV n        RV n        RV n        RV n        V P                  4        V P!                  4        V P#                  4       G Rj  x€L
  V P%                  4        \&        P)                  R4       R#  EL Lë L� L† L45i)zDisconnect from Feishu/Lark.FNz[Feishu] Disconnected)r¨  r\  rî  Ú_cancel_pending_tasksru  ry  Ú_reset_batch_buffersrZ  rè  Ú!_disable_websocket_auto_reconnectÚ_stop_webhook_serverÚ_teardown_ws_threadr[  rê  r`  r  Ú_persist_seen_message_idsr'  Ú_mark_disconnectedr¬  r$  )r|   r¼  Úws_thread_loops   &  rK   Ú
disconnectÚFeishuAdapter.disconnect  s1  é € àˆŒØ×ÑÒ*Ø×Ñ×&Ñ&Ô(Ø"&ˆDÔØ×(Ñ(¨×)GÑ)GÓH×HÐHØ×(Ñ(¨×)HÑ)HÓI×IÐIØ×!Ñ!Ô#ð —O‘Oˆ	Ø×-Ñ-ˆØ×.Ñ.Ô0Ø×'Ñ'Ó)×)Ð)Ø×&Ñ& yÓA×AÐAØˆŒØ#ˆÔØˆŒ
Ø"ˆÔØ×#Ñ#Ô%Ø×&Ñ&Ô(Ø×$Ñ$Ó&×&Ð&Ø×ÑÔ!Ü�‰Ð+Ö,ò+ 	IÙIñ 	*ÙAñ 	'ùs\   ‚AE.ÁE#Á"E.Á:E&Á;AE.Ã
E(ÃE.Ã#E*Ã$AE.Ä7E,Ä8,E.Å&E.Å(E.Å*E.Å,E.c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r¼  r
   r5  rG   rI  rI   )rJ   s   "rK   rL   rK  (  s'   € ÷ +dñ +d°3ð +dÈð +dÐPTñ +drM   c              ƒ  ód  a"  € SRJ;'       d    SP                  4       '       * pVeŠ   V'       d‚   \        VR4      '       dp    \        P                  ! VP	                  4       S4      p\        P
                  ! \        P                  ! V4      RR7      G Rj  x€L
  \        P                  R4       V'       d0   \        P                  R
4       R V3R llpSP                  V4       V P                  pVeb    \        P                  R4       \        P
                  ! \        P                  ! V4      RR7      G Rj  x€L
  \        P                  R4       R# R#  LÃ  \         d    \        P                  R4        LÎ\         d#   p\        P                  RTRR	7        Rp?LõRp?ii ; i Lp  \         d    \        P                  R4        R# \        P                   d    \        P                  R4        R# \         d$   p\        P                  RTRR	7        Rp?R# Rp?ii ; i5i)uL   CLOSE frame â†’ cancel the WS thread's tasks â†’ wait for the thread future.NÚ_disconnectrM  ©Útimeoutz-[Feishu] Sent WebSocket CLOSE frame to Feishuu‡   [Feishu] CLOSE frame not acknowledged within 5s â€” Feishu may briefly route messages to the stale connection until server-side timeoutz1[Feishu] Could not send WebSocket CLOSE frame: %sTr©  z<[Feishu] Cancelling websocket thread tasks and stopping loopc               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   Ú7FeishuAdapter._teardown_ws_thread.<locals>.__annotate__?  s   € ÷ Dñ D dñ DrM   c                 ó4  <€ \         P                  ! S4       U u. uF  q P                  ! 4       '       d   K  V NK  	  pp \        P	                  R \        V4      4       V F  pVP                  4        K  	  SP                  RSP                  4       R# u up i )z3[Feishu] Found %d pending tasks in websocket threadgš™™™™™¹?N)	rQ   rì  rí  r¬  r®  rT   rî  Ú
call_laterr°  )r   rÅ   rô  r5  s      €rK   Úcancel_all_tasksÚ;FeishuAdapter._teardown_ws_thread.<locals>.cancel_all_tasks?  sq   ø€ Ü$+×$5Ò$5°nÔ$EÓVÑ$E˜qÏVÊVÏXŸ˜Ñ$E�ÐVÜ—‘ÐRÔTWÐX]ÓT^Ô_Û!�DØ—K‘K–Mñ "à×)Ñ)¨#¨~×/BÑ/BÖCùò	 Ws
   šB·Bz;[Feishu] Waiting for websocket thread to exit (timeout=10s)g      $@z([Feishu] Websocket thread exited cleanlyz@[Feishu] Websocket thread did not exit within 10s - may be stuckz5[Feishu] Websocket thread cancelled during disconnectz/[Feishu] Websocket thread exited with error: %s)rÐ  ÚhasattrrQ   Úrun_coroutine_threadsafer:  Úwait_forÚwrap_futurer¬  r®  ÚTimeoutErrorr¶  r«  rÑ  r[  ÚshieldÚCancelledError)r|   r¼  r5  Ú
loop_aliveÚfuturerW   rA  Ú	ws_futures   &&f     rK   r2  Ú!FeishuAdapter._teardown_ws_thread(  s¸  øé € ð $¨4Ð/×RÐR¸×8PÑ8PÓ8RÔ4Rˆ
ØÒ §Z´G¸IÀ}×4UÒ4UðfÜ ×9Ò9¸)×:OÑ:OÓ:QÐSaÓb�ä×&Ò&¤w×':Ò':¸6Ó'BÈCÔP×PÐPÜ—‘ÐLÔM÷ Ü�L‰LÐWÔX÷Dð Dð ×/Ñ/Ð0@ÔAà—O‘Oˆ	ØÒ ð	dÜ—‘ÐZÔ[Ü×&Ò&¤w§~¢~°iÓ'@È$ÔO×OÐOÜ—‘ÐGÖHñ	 !ñ1 Qøäô Ü—‘ð;öô
 ô fÜ—‘ÐPÐRUÐ`d�×eÑeûðfúñ& Pøäô cÜ—‘Ða×bÜ×)Ñ)ô VÜ—‘ÐT×UÜô dÜ—‘ÐNÐPSÐ^b�×cÒcûðdüsÀ   ƒ-H0±H0ÁAE ÂEÂE Â2H0Â:?H0Ã:AF1 Ä>F/Ä?F1 ÅH0ÅE Å F,Å>H0Æ F,Æ	F,Æ
F'Æ"H0Æ'F,Æ,H0Æ/F1 Æ1 H-ÇH0ÇH-Ç'H-Ç=H0È H-È	H-È
H(È"H0È(H-È-H0c               ó    € V ^8„  d   QhRRRR/# )rC   rÅ   rÄ   rG   rI  rI   )rJ   s   "rK   rL   rK  U  s   € ÷ ñ Ð1Hð ÈTñ rM   c              ƒ  	ó:  "  € VP                  4        Uu. uF&  q"'       g   K  VP                  4       '       d   K$  VNK(  	  ppV F  pVP                  4        K  	  V'       d   \        P                  ! VR R/ G Rj  x€L
  VP                  4        R# u upi  L5i)râ  TN)rƒ  rí  rî  rQ   rð  Úclear)r|   rÅ   rô  ró  s   &&  rK   r.  Ú#FeishuAdapter._cancel_pending_tasksU  so   é € Ø$)§L¡L¤NÓO¡N˜D³d”4À4Ç9Á9Ç;—4�4¡NˆÐOÛˆDØ�K‰KŽMñ çÜ—.’. 'ÐB¸TÑB×BÐBØ�‰Žùò Pñ Cùs,   ‚B•	B£B»BÁ"BÁ$BÁ=BÁ>Bc               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  ]  s   € ÷ ,ñ , dñ ,rM   c                	ó¢   € V P                   P                  4        V P                  P                  4        V P                  P                  4        R # r{   )rt  rP  rv  rx  rˆ  s   &rK   r/  Ú"FeishuAdapter._reset_batch_buffers]  s8   € Ø×"Ñ"×(Ñ(Ô*Ø×'Ñ'×-Ñ-Ô/Ø×#Ñ#×)Ñ)Ö+rM   c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  b  s   € ÷ #ñ #°4ñ #rM   c                	ó’   € V P                   f   R #  RV P                   n        R V n         R #   \         d     Li ; i  R T n         i ; i)NF)rZ  Ú_auto_reconnectr«  rˆ  s   &rK   r0  Ú/FeishuAdapter._disable_websocket_auto_reconnectb  sG   € Ø�?‰?Ò"Ùð	#Ø.3ˆD�O‰OÔ+ð #ˆDŽOøô ô 	Ùð	ûð #ˆD�Oús   ’, ¬:·= ¹:º= ½	Ac               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  l  s   € ÷ &ñ &¨Dñ &rM   c              ƒ  	óº   "  € V P                   f   R #  V P                   P                  4       G R j  x€L
  R V n         R V n        R #  L  R T n         R T n        i ; i5ir{   )r^  Úcleanupr_  rˆ  s   &rK   r1  Ú"FeishuAdapter._stop_webhook_serverl  sW   é € Ø×ÑÒ'Ùð	&Ø×&Ñ&×.Ñ.Ó0×0Ð0à#'ˆDÔ Ø!%ˆDÖñ 1øà#'ˆDÔ Ø!%ˆDÕüs+   ‚A”A ±A²A ¶AÁA ÁAÁANc          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
rC   rö  rb   rO   Úreply_toúOptional[str]r“   úOptional[dict[str, Any]]rG   r   rI   )rJ   s   "rK   rL   rK  v  s4   € ÷ 2=ñ 2=Øð2=Ø%(ð2=Ø4Að2=ØTlð2=à	ñ2=rM   c           
   ƒ  ó  a aaa"  € S P                   '       g   \        RRR7      # S P                  V4      pS P                  VS P                  4      p\        \        P                  V4      4      pRpR VVVV 3R llp	 V F³  p
S P                  W§R7      w  r¼ S P                  SW¼SSR7      G Rj  x€L
 pVR	8X  dv   S P                  V4      '       g_   \        P                  \        \!        VRR4      ;'       g    R4      4      '       d&   \        P                  R4       V	! V
4      G Rj  x€L
 pTpKµ  	  S P#                  VR4      #  L˜  \         d]   pTR	8w  g%   \        P                  \        T4      4      '       g   h \        P                  R
4       T	! T
4      G Rj  x€L 
 p Rp?LøRp?ii ; i Lˆ  \         d9   p\        P%                  RTRR7       \        R\        T4      R7      u Rp?# Rp?ii ; i5i)zSend a Feishu message.FúNot connected©Úsuccessr  Nc               ó    € V ^8„  d   QhRRRR/# )rC   Úchunkrb   rG   r
   rI   )rJ   s   "rK   rL   Ú(FeishuAdapter.send.<locals>.__annotate__‡  s   € ÷ 	ñ 	 Sð 	¨Sñ 	rM   c           
   “  óŽ   <"  € SP                  SR \        P                  ! R \        V 4      /RR7      SSR7      G Rj  x€L
 #  L5i)rŒ   Fr<  ©rö  r  r\  r^  r“   N)Ú_feishu_send_with_retryr?  r@  r*  )rf  rö  r“   r^  r|   s   &€€€€rK   Ú_send_plainÚ'FeishuAdapter.send.<locals>._send_plain‡  sN   øé € Ø×5Ñ5ØØÜŸ
š
 FÔ,IÈ%Ó,PÐ#QÐ`eÔfØ!Ø!ð 6ó ÷ ð ñ ùs   ƒ;A¾A¿A)Úprefer_postri  ru  zI[Feishu] Invalid post payload rejected by API; falling back to plain textÚmsgrd   zJ[Feishu] Post payload rejected by API response; falling back to plain textzsend failedz[Feishu] Send error: %sTr©  )rT  r   Úformat_messageÚtruncate_messageÚMAX_MESSAGE_LENGTHrr   Ú_MARKDOWN_HINT_REÚsearchÚ_build_outbound_payloadrj  r«  Ú_POST_CONTENT_INVALID_RErb   r¬  r¶  Ú_response_succeededrÎ   Ú_finalize_send_resultr  )r|   rö  rO   r^  r“   Ú	formattedÚchunksrm  Úlast_responserk  rf  r  r\  ÚresponserW   s   ff&ff          rK   ÚsendÚFeishuAdapter.sendv  sÆ  ûé € ð �|�|ˆ|Ü e°?ÔCÐCà×'Ñ'¨Ó0ˆ	Ø×&Ñ& y°$×2IÑ2IÓJˆô Ô,×3Ñ3°IÓ>Ó?ˆØˆ÷	ó 	ð	=Û�Ø$(×$@Ñ$@ÀÐ$@Ó$`Ñ!�ð8Ø%)×%AÑ%AØ '°(ÐV^Ðiqð &Bó &÷  �Hð  Ô&Ø ×4Ñ4°X×>Ò>Ü0×7Ñ7¼¼GÀHÈeÐUWÓ<X×<^Ð<^Ð\^Ó8_×`Ò`ä—N‘NÐ#oÔpÙ%0°Ó%7×7�HØ (’ñ%  ð( ×-Ñ-¨m¸]ÓKÐKñ# øô !ô 8Ø 6Ô)Ô1I×1PÑ1PÔQTÐUXÓQY×1ZÒ1ZØÜ—N‘NÐ#nÔoÙ%0°Ó%7×7Ð7•Hûð	8úñ  8øô ô 	=Ü�L‰LÐ2°CÀ$ˆLÔGÜ e´3°s³8Ô<Õ<ûð	=üs�   †A9G?Â F9 ÂEÂ2EÂ3EÂ7F9 Ã'F9 Ã=F9 Ä F9 Ä.F7Ä/F9 Å
G?ÅEÅF4ÅAF/Æ$F'Æ%F/Æ*F9 Æ/F4Æ4F9 Æ9G<Ç-G7Ç1G<Ç2G?Ç7G<Ç<G?Úfinalizec          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	rC   rö  rb   Ú
message_idrO   r~  rr   rG   r   rI   )rJ   s   "rK   rL   rK  ª  s1   € ÷ =ñ =¨#ð =¸3ð =Èð =Ð[_ð =Ðlvñ =rM   c          	   ƒ  ó´  a a"  € S P                   '       g   \        RRR7      # S P                  V4      pR VV 3R llp S P                  V4      w  rgV! Wg4      G Rj  x€L
 pVP                  '       g~   VR8X  dw   \
        P                  VP                  ;'       g    R4      '       dH   \        P                  R	4       V! R
\        P                  ! R
\        V4      /RR7      4      G Rj  x€L
 pVP                  '       d   SVn        V#  L® L!  \         d:   p	\        P                  RST	RR7       \        R\        T	4      R7      u Rp	?	# Rp	?	ii ; i5i)z0Edit a previously sent Feishu text/post message.Frb  rc  c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r  rb   r\  rG   r   rI   )rJ   s   "rK   rL   Ú0FeishuAdapter.edit_message.<locals>.__annotate__±  s&   € ÷ 	Iñ 	I Cð 	I°#ð 	I¸*ñ 	IrM   c              “  ó  <"  € SP                  WR 7      pSP                  SVR7      pSP                  SP                  P                  P
                  P                  P                  V4      G Rj  x€L
 pSP                  VR4      #  L5i)©r  rO   ©r€  Úrequest_bodyNzupdate failed)	Ú_build_update_message_bodyÚ_build_update_message_requestr  rT  ÚimÚv1r1   r  rw  )r  r\  rV   rD   r{  r€  r|   s   &&   €€rK   Ú_updateÚ+FeishuAdapter.edit_message.<locals>._update±  sx   øé € Ø×2Ñ2¸HÐ2ÓVˆDØ×8Ñ8ÀJÐ]aÐ8ÓbˆGØ!×/Ñ/°·±·±×0BÑ0B×0JÑ0J×0QÑ0QÐSZÓ[×[ˆHØ×-Ñ-¨h¸ÓHÐHñ \ùs   ƒA-B	Á0BÁ1B	Nru  rd   zP[Feishu] Invalid post update payload rejected by API; falling back to plain textrŒ   r<  z&[Feishu] Failed to edit message %s: %sTr©  )rT  r   ro  rt  rd  ru  rs  r  r¬  r¶  r?  r@  r*  r€  r«  rb   )
r|   rö  r€  rO   r~  rŒ  r  r\  re  rW   s
   f&f&$     rK   Úedit_messageÚFeishuAdapter.edit_messageª  s   ùé € à�|�|ˆ|Ü e°?ÔCÐCà×%Ñ% gÓ.ˆ÷	Iñ 	Ið	=Ø $× <Ñ <¸WÓ EÑˆHÙ" 8Ó5×5ˆFØ—>—>�> h°&Ô&8Ô=U×=\Ñ=\Ð]c×]iÑ]i×]oÐ]oÐmo×=pÒ=pÜ—‘ÐqÔrÙ&ØœDŸJšJ¨Ô0MÈgÓ0VÐ'WÐfkÔló ÷ �ð �~�~ˆ~Ø$.�Ô!ØˆMñ 6ñøô ô 	=Ü�L‰LÐAÀ:ÈsÐ]aˆLÔbÜ e´3°s³8Ô<Õ<ûð	=üsr   „;EÁ D ÁDÁD Á5(D ÂD Â+AD Ã-DÃ.D ÄD ÄEÄD ÄD ÄEÄ.EÅ
EÅEÅEÅEc               ó$   € V ^8„  d   QhRRRRRR/# )rC   rö  rb   r€  rG   rr   rI   )rJ   s   "rK   rL   rK  Æ  s!   € ÷ ñ ¨Cð ¸Sð ÀTñ rM   c           
   ƒ  óè  "  € V P                   '       d	   V'       g   R#  V P                  V4      pV P                  V P                   P                  P                  P
                  P                  V4      G Rj  x€L
 pV P                  V4      '       d   R# \        P                  RV\        VRR4      \        VRR4      4       R#  LM  \         d    \        P                  RTRR7        R# i ; i5i)	zFDelete a bot-posted message (used by stream-consumer preview cleanup).FNTz6[Feishu] Delete of message %s rejected: code=%s msg=%sr  rn  z$[Feishu] Failed to delete message %sr©  )rT  Ú_build_delete_message_requestr  rŠ  r‹  r1   Údeleterv  r¬  r®  rÎ   r«  )r|   rö  r€  rD   r{  s   &&&  rK   Údelete_messageÚFeishuAdapter.delete_messageÆ  sÇ   é € à�|�|ˆ|§:Ùð	Ø×8Ñ8¸ÓDˆGØ!×/Ñ/°·±·±×0BÑ0B×0JÑ0J×0QÑ0QÐSZÓ[×[ˆHØ×'Ñ'¨×1Ò1ÙÜ�L‰LØHØœG H¨f°dÓ;¼WÀXÈuÐVZÓ=[ôñ ñ \øô ô 	Ü�L‰LÐ?ÀÐVZˆLÔ[Úð	üsL   ‚C2�C2 AC Á8CÁ9C ÂC2Â.C ÃC2ÃC Ã#C/Ã+C2Ã.C/Ã/C2rd   i¸  c               ó   € V ^8„  d   QhRR/# r�  rI   )rJ   s   "rK   rL   rK  ß  s   € ÷ Bñ B #ñ BrM   c                	ó    € R \        R4       R2# )ú**z"gateway.exec_approval.reason_labelz:** r   rˆ  s   &rK   Ú_EA_REASON_LABELÚFeishuAdapter._EA_REASON_LABELÞ  s   € à”AÐ:Ó;Ð<¸DÐAÐArM   c               ó   € V ^8„  d   QhRR/# r�  rI   )rJ   s   "rK   rL   rK  ã  s   € ÷ Eñ E Sñ ErM   c                	ó‚   € \        R 4      pVP                  R4      w  r#pRV'       d   RV V RV 2,           # T,           # )z%gateway.exec_approval.smart_deny_liner¤  ú

r˜  )r   Ú	partition)r|   r
  r¶  ÚsepÚrests   &    rK   Ú_EA_SMART_DENY_LINEÚ!FeishuAdapter._EA_SMART_DENY_LINEâ  sF   € äÐ8Ó9ˆØŸ>™>¨#Ó.Ñˆ�DØ·c˜2˜e˜W S E¨¨D¨6Ð2ÕDÐD¸tÕDÐDrM   c               ó   € V ^8„  d   QhRR/# )rC   rG   r?   rI   )rJ   s   "rK   rL   rK  é  s   € ÷ Iñ I >ñ IrM   c                	ó–   € R R\        R4      ,           RR\        R4      ,           RR\        R4      ,           RR\        R	4      ,           /# )
r9   u   âœ… z!gateway.exec_approval.action_oncer;   z'platform.feishu.approval.action_sessionr=   z&platform.feishu.approval.action_alwaysr>   u   â�Œ z!gateway.exec_approval.action_denyr   rˆ  s   &rK   Ú_EA_ACTION_LABELSÚFeishuAdapter._EA_ACTION_LABELSè  sN   € à˜¤Ð#FÓ!GÕGØ˜6¤AÐ&OÓ$PÕPØ˜&¤1Ð%MÓ#NÕNØ˜¤Ð#FÓ!GÕGðIð 	IrM   r9   r8   r;   r:   r=   r<   r>   c               ó    € V ^8„  d   QhRRRR/# )rC   Úpromptr   rG   r   rI   )rJ   s   "rK   rL   rK  ð  s   € ÷ =ñ =Ð7Ið =Èjñ =rM   c              ƒ  óz  "  € V P                   '       g   \        RRR7      #  \        V P                  4      pVP                   UUUu. uF1  w  r4p\        Y5;'       g    RRV P                  V,          RV/4      NK3  	  pppp\        R\        R4       2R	VP                  VR
7      pV P                  VP                  WqP                  RV P                  W!P                  R7      G Rj  x€L
 # u upppi  L  \         d7   p\         P#                  RT4       \        R\%        T4      R7      u Rp?# Rp?ii ; i5i)z¢Approval-button card; ``hermes_action`` in each button value lets the click callback
route to ``resolve_gateway_approval()`` and unblock the waiting agent thread.Frb  rc  r,  Úhermes_actionÚapproval_idu   âš ï¸� zgateway.exec_approval.headerÚorange©r  zsend_exec_approval failed©Ú	state_mapÚstate_idÚsession_keyNz&[Feishu] send_exec_approval failed: %s)rT  r   r³  r|  r  r5  Ú_EA_CARD_ACTIONSr>  r   rŒ   Ú_send_interactive_cardrö  r“   rz  r±  r«  r¬  r¶  rb   )	r|   r¨  r«  r¶  Úchoicerí   r  rÏ  rW   s	   &&       rK   Ú_send_exec_approval_promptÚ(FeishuAdapter._send_exec_approval_promptð  s(  é € ð �|�|ˆ|Ü e°?ÔCÐCð	=Ü˜t×5Ñ5Ó6ˆKð -3¯NªNõ<ñ -;Ñ(�E 5ô ˜U×$6Ð$6¨YØ-¨t×/DÑ/DÀVÕ/LÈmÐ]hÐiöká,:ð ò <ô ˜7¤1Ð%CÓ#DÐ"EÐFÈÐRX×R]ÑR]ÐgnÔoˆDØ×4Ñ4Ø—‘ §o¡oÐ7RØ×.Ñ.¸×RdÑRdð 5ó ÷ ð ùô<ñ
øô ô 	=Ü�N‰NÐCÀSÔIÜ e´3°s³8Ô<Õ<ûð	=üsS   ‚ D;£%C7 Á7C.Á?A*C7 Ã)C5Ã*C7 Ã-D;Ã.C7 Ã7D8Ä+D3Ä-D8Ä.D;Ä3D8Ä8D;c               ó8   € V ^8„  d   QhRRRRRRRRRR	R
RRRRR/# )rC   rö  rb   rÏ  r’   r“   r`  Úfailure_messager¯  údict[int, dict[str, str]]r°  rF   r±  rG   r   rI   )rJ   s   "rK   rL   rK    sN   € ÷ ñ ØðØ"0ðØ<TðØgjðà,ðà8;ðàJMðð 
ñrM   c          	   ƒ  óü   "  € V P                  VR\        P                  ! VRR7      RVR7      G Rj  x€L
 pV P                  W„4      p	V	P                  '       d   RTRV	P
                  ;'       g    RR	V/WV&   V	#  LG5i)
zWSend a button card and, on success, remember where it went so a click can be validated.rÐ  Fr<  Nri  r±  r€  rd   rö  )rj  r?  r@  rw  rd  r€  )
r|   rö  rÏ  r“   r¸  r¯  r°  r±  r{  re  s
   &&&&&$$$  rK   r³  Ú$FeishuAdapter._send_interactive_card  s‡   é € ð
 ×5Ñ5Ø m¼T¿ZºZÈÐ[`Ô=aØ Hð 6ó 
÷ 
ˆð ×+Ñ+¨HÓFˆØ�>�>ˆ>à˜{Ø˜f×/Ñ/×5Ð5°2Ø˜7ð#ˆIÑð
 ˆñ
ùs   ‚0A<²A:³<A<Á0A<c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   r¨  rb   r,  Ú	prompt_idrF   rG   r’   rI   )rJ   s   "rK   rL   rK    s/   € ÷ uñ u¨Sð u¸3ð uÈ3ð uÐSañ urM   c                	óÈ   a€ V'       d   \        R VR7      MRpR V3R llpV! \        R4      RR4      V! \        R4      R	R
4      .p\        \        R4      RV  V 2VR7      # )z*platform.feishu.update_prompt.default_hint©r,  rd   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   r¶  rb   Úanswerr2  rG   r”   rI   )rJ   s   "rK   rL   Ú=FeishuAdapter._build_update_prompt_card.<locals>.__annotate__  s.   € ÷ 	yñ 	y˜ð 	y Sð 	y°Cð 	y¸Dñ 	yrM   c                ó$   <€ \        WR VRS/4      # )Úhermes_update_prompt_actionÚupdate_prompt_id)r5  )r¶  rÁ  r2  r½  s   &&&€rK   Ú_btnÚ5FeishuAdapter._build_update_prompt_card.<locals>._btn  s   ø€ Ü Ð2OÐQWÐYkÐmvÐ1wÓxÐxrM   z(platform.feishu.update_prompt.answer_yesÚyÚprimaryz'platform.feishu.update_prompt.answer_norž  Údangerz#platform.feishu.update_prompt.titler¬  r­  ©r   r>  )r¨  r,  r½  Údefault_hintrÆ  r  s   $$d   rK   Ú_build_update_prompt_cardÚ'FeishuAdapter._build_update_prompt_card  sr   ø€ ç[b”qÐEÈwÕWÐhjˆ÷	yð 	yñ œÐDÓEÀsÈIÓVÙœÐCÓDÀcÈ8ÓTðVˆä”QÐ<Ó=¸xÈFÈ8ÐT`ÐSaÐIbÐlsÔtÐtrM   c               ó0   € V ^8„  d   QhRRRRRRRRRRRR	/# )
rC   rö  rb   r¨  r,  r±  r“   r`  rG   r   rI   )rJ   s   "rK   rL   rK  !  s>   € ÷ =ñ =Øð=Ø$'ð=Ø25ð=ØILð=à*ð=ð 
ñ=rM   c           
   ƒ  óv  "  € V P                   '       g   \        RRR7      #  \        V P                  4      pV P	                  W#VR7      pV P                  WVRV P                  WdR7      G Rj  x€L
 #  L  \         d7   p\        P                  RT4       \        R\        T4      R7      u Rp?# Rp?ii ; i5i)	z6Send an interactive update prompt with Yes/No buttons.Frb  rc  )r¨  r,  r½  zsend_update_prompt failedr®  Nz&[Feishu] send_update_prompt failed: %s)rT  r   r³  r~  rÍ  r³  r}  r«  r¬  r¶  rb   )	r|   rö  r¨  r,  r±  r“   r½  rÏ  rW   s	   &&&&&&   rK   Úsend_update_promptÚ FeishuAdapter.send_update_prompt!  s®   é € ð
 �|�|ˆ|Ü e°?ÔCÐCð		=Ü˜T×8Ñ8Ó9ˆIØ×1Ñ1¸Ð\eÐ1ÓfˆDØ×4Ñ4Ø˜xÐ)DØ×3Ñ3¸ið 5ó ÷ ð ñ øô ô 	=Ü�N‰NÐCÀSÔIÜ e´3°s³8Ô<Õ<ûð	=üsG   ‚ B9£AA5 Á.A3Á/A5 Á2B9Á3A5 Á5B6Â +B1Â+B6Â,B9Â1B6Â6B9c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r´  rb   r•  rG   r’   rI   )rJ   s   "rK   rL   rK  4  s&   € ÷ mñ m°ð mÀð mÈñ mrM   c                ó¨   € V R8X  d   RMRp\         P                  V R4      p\        V4      p\        V RV 2V R8X  d   RMR\        RW$VR	7      4      # )
zIRaw card JSON shown in place of the buttons once an approval is resolved.r>   õ   â�Œõ   âœ…z*platform.feishu.approval.resolved_fallbackr÷   ÚredÚgreenz)platform.feishu.approval.resolved_by_user)Úiconr¶  r”  )rA   rñ   r   r>  )r´  r•  rÙ  rî   r¶  s   $$   rK   Ú_build_resolved_approval_cardÚ+FeishuAdapter._build_resolved_approval_card3  sc   € ð  &Ô(‰u¨eˆÜ"×&Ñ& vÐ/[Ó\ˆÜ�#“ˆÜ˜�v˜Q˜u˜gÐ&°¸6Ô1A©ÀwÜÐBÈÐajÔkómð 	mrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rÁ  rb   r•  rG   r’   rI   )rJ   s   "rK   rL   rK  =  s&   € ÷ wñ w°cð wÀcð wÈnñ wrM   c           	     	ó¤   € V R 8H  p\        RV'       d   RMR\        V'       d   RMR4      R7      p\        Y2'       d   RMR\        R	VR
7      4      # )rÈ  z,platform.feishu.update_prompt.answered_titlerÖ  rÕ  z&platform.feishu.update_prompt.word_yesz%platform.feishu.update_prompt.word_no)rÙ  rÁ  rØ  r×  z)platform.feishu.update_prompt.answered_by)r”  rË  )rÁ  r•  rš  r_  s   $$  rK   Ú"_build_resolved_update_prompt_cardÚ0FeishuAdapter._build_resolved_update_prompt_card<  sK   € à˜‰mˆÜÐ@×PSÁuÐY^ÜÇsÑCÐPwÓxôzˆä�U¦s™G°´qÐ9dÐktÔ7uÓvÐvrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rÁ  rb   rG   rI  rI   )rJ   s   "rK   rL   rK  D  s   € ÷ (ñ (¨cð (°dñ (rM   c                	ó’   € \        4       R ,          pVP                  R4      pVP                  V RR7       VP                  V4       R# )z.update_responsez.tmpúutf-8©ÚencodingN)r'   Úwith_suffixÚ
write_textr  )rÁ  Úresponse_pathÚtmp_paths   &  rK   Ú_write_update_prompt_responseÚ+FeishuAdapter._write_update_prompt_responseC  sA   € ä'Ó)Ð,>Õ>ˆØ ×,Ñ,¨VÓ4ˆØ×Ñ˜F¨WÐÔ5Ø×Ñ˜Ö'rM   c               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )rC   rö  rb   Ú
audio_pathÚcaptionr_  r^  r“   r`  rG   r   rI   )rJ   s   "rK   rL   rK  J  s>   € ÷ ñ ØðØ(+ðØ6CðØVcðà*ðð 
ñrM   c           	   ‹  óØ  "  € Rp\        V4      P                  P                  4       pV\        9  d/   ^ RIHp	 \        P                  ! W’4      G Rj  x€L
 pV'       d   Tp V P                  WWEVRR7      G Rj  x€L
 V'       d    \        P                  ! V4       # #  LL L&  \         d     # i ; i  T'       d*    \        P                  ! T4       i   \         d     i i ; ii ; i5i)zŸNative voice message (Feishu only accepts Opus): non-opus audio is transcoded via ffmpeg
first; without ffmpeg the original file goes out as a file attachment.N)Útranscode_to_ogg_opusrª  ©rö  Ú	file_pathr^  r“   rí  Úoutbound_message_type)r   r  r±  Ú_FEISHU_OPUS_UPLOAD_EXTENSIONSÚgateway.platforms.baserï  rQ   r  Ú_send_uploaded_file_messageÚosÚunlinkÚOSError)
r|   rö  rì  rí  r^  r“   rš  Útranscoded_pathÚextrï  s
   &&&&&&,   rK   Ú
send_voiceÚFeishuAdapter.send_voiceJ  sÛ   é € ð *.ˆÜ�:Ó×%Ñ%×+Ñ+Ó-ˆØÔ4Ô4ÝDÜ$+×$5Ò$5Ð6KÓ$X×XˆOßØ,�
ð
	Ø×9Ñ9ØÀØ°wð :ó ÷ ÷
 ðÜ—I’I˜oÕ.ð ñ Yñøô ô Ùðû÷ ðÜ—I’I˜oÕ.øÜô Ùðúð üsŠ   ‚AC*ÁBÁC*ÁC*Á"B4 Á:B!Á;B4 Á>C*ÂB#ÂC*Â!B4 Â#B1Â.C*Â0B1Â1C*Â4	C'Â>CÃC'ÃC#Ã C'Ã"C#Ã#C'Ã'C*c               ó4   € V ^8„  d   QhRRRRRRRRRRRR	R
R/# )rC   rö  rb   rñ  rí  r_  re   r^  r“   r`  rG   r   rI   )rJ   s   "rK   rL   rK  c  sF   € ÷ 
ñ 
Øð
Ø'*ð
Ø5Bð
ØVcð
àð
à2Jð
ð 
ñ
rM   c           	   ‹  óF   "  € V P                  WWVW4R7      G Rj  x€L
 #  L5i)z*Send a document/file attachment to Feishu.)rö  rñ  r^  r“   rí  re   N©rõ  )r|   rö  rñ  rí  re   r^  r“   rš  s   &&&&&&&,rK   Úsend_documentÚFeishuAdapter.send_documentc  s1   é € ð
 ×5Ñ5Ø¸8Øð 6ó 
÷ 
ð 	
ñ 
ùs   ‚!š›!c               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )rC   rö  rb   Ú
video_pathrí  r_  r^  r“   r`  rG   r   rI   )rJ   s   "rK   rL   rK  m  s>   € ÷ 
ñ 
Øð
Ø(+ð
Ø6Cð
ØVcð
à*ð
ð 
ñ
rM   c           	   ‹  óH   "  € V P                  WWEVRR7      G Rj  x€L
 #  L5i)zSend a video file to Feishu.r«  rð  Nrÿ  )r|   rö  r  rí  r^  r“   rš  s   &&&&&&,rK   Ú
send_videoÚFeishuAdapter.send_videom  s3   é € ð
 ×5Ñ5Ø¸HØ°7ð 6ó 
÷ 
ð 	
ñ 
ùs   ‚"› œ"c               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )rC   rö  rb   Ú
image_pathrí  r_  r^  r“   r`  rG   r   rI   )rJ   s   "rK   rL   rK  w  s>   € ÷ =ñ =Øð=Ø(+ð=Ø6Cð=ØVcð=à*ð=ð 
ñ=rM   c              ‹  óÎ  "  € V P                   '       g   \        RRR7      # \        P                  P	                  V4      '       g   \        RRV 2R7      #  ^ RIpTP                  \        P                  ! \        V4      P                  4      G Rj  x€L
 4      p\        P                  P                  V4      Vn        V P                  \        VR7      p	V P                  V	4      p
V P!                  V P                   P"                  P$                  P&                  P(                  V
4      G Rj  x€L
 pV P+                  VR4      pV'       g   V P-                  VRR	R
7      # V P/                  WWSRRV/RRRV/R7      G Rj  x€L
 pV P1                  VR4      #  EL Lk L  \2         d9   p\4        P7                  RY.RR7       \        R\9        T4      R7      u Rp?# Rp?ii ; i5i)z"Send a local image file to Feishu.Frb  rc  zImage file not found: N©Ú
image_typer©  r—  zimage upload failedz%Feishu image upload missing image_key©Údefault_messageÚoverride_errorr©  rE  r¨  ©rö  r^  r“   rí  Úkey_msg_typeÚkey_payloadÚ	media_tagzimage send failedz$[Feishu] Failed to send image %s: %sTr©  )rT  r   rö  ÚpathÚexistsÚioÚBytesIOrQ   r  r   Ú
read_bytesÚbasenamerp   Ú_build_image_upload_bodyÚ_FEISHU_IMAGE_UPLOAD_TYPEÚ_build_image_upload_requestr  rŠ  r‹  r©  ÚcreateÚ_extract_response_fieldÚ_response_error_resultÚ_send_uploaded_keyrw  r«  r¬  r  rb   )r|   rö  r  rí  r^  r“   rš  Ú_ioÚ
image_filerV   rD   Úupload_responser—  Úmessage_responserW   s   &&&&&&,        rK   Úsend_image_fileÚFeishuAdapter.send_image_filew  s­  é € ð
 �|�|ˆ|Ü e°?ÔCÐCÜ�w‰w�~‰~˜j×)Ò)Ü eÐ5KÈJÈ<Ð3XÔYÐYð	=ÛØŸ™¬7×+<Ò+<¼TÀ*Ó=M×=XÑ=XÓ+Y×%YÓZˆJÜ Ÿg™g×.Ñ.¨zÓ:ˆJŒOØ×0Ñ0Ô<UÐ]gÐ0ÓhˆDØ×6Ñ6°tÓ<ˆGØ$(×$6Ñ$6°t·|±|·±×7IÑ7I×7OÑ7O×7VÑ7VÐX_Ó$`×`ˆOØ×4Ñ4°_ÀkÓRˆIßØ×2Ñ2Ø#Ð5JØ#Jð 3ó ð ð &*×%<Ñ%<Ø¸XØ$°;À	Ð2JØ  %¨°iÐ@ð &=ó &÷  Ðð
 ×-Ñ-Ð.>Ð@SÓTÐTò! &Zñ añ øô ô 	=Ü�L‰LÐ?ÀÐ[_ˆLÔ`Ü e´3°s³8Ô<Õ<ûð	=üs…   ‚AG%ÁG%Á;F ÂFÂBF Ä/FÄ0F ÅF Å!G%Å"F ÆFÆF ÆG%ÆF ÆF ÆF ÆG"Æ*-GÇG"ÇG%ÇG"Ç"G%c               ó    € V ^8„  d   QhRRRR/# ©rC   rö  rb   rG   rI  rI   )rJ   s   "rK   rL   rK  —  s   € ÷ ñ ¨ð Àñ rM   c              ƒ  ó   "  € R# 5i)z2Feishu bot API does not expose a typing indicator.NrI   )r|   rö  r“   s   &&&rK   Úsend_typingÚFeishuAdapter.send_typing—  s   é € áùs   ‚c               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )rC   rö  rb   Ú	image_urlrí  r_  r^  r“   r`  rG   r   rI   )rJ   s   "rK   rL   rK  ›  s>   € ÷ 
ñ 
Øð
Ø'*ð
Ø5Bð
ØUbð
à*ð
ð 
ñ
rM   c           	   ƒ  ó  <"  €  V P                  V4      G Rj  x€L
 pT P                  YY4TR7      G Rj  x€L
 #  L   \         d>   p\        P                  RY'RR7       \        ST `  YY4TR7      G Rj  x€L 
 u Rp?# Rp?ii ; i LQ5i)zJDownload a remote image then send it through the native Feishu image flow.Nz([Feishu] Failed to download image %s: %sTr©  )rö  r,  rí  r^  r“   )rö  r  rí  r^  r“   )Ú_download_remote_imager«  r¬  r  rN  Ú
send_imager$  )	r|   rö  r,  rí  r^  r“   r  rW   r�  s	   &&&&&&  €rK   r/  ÚFeishuAdapter.send_image›  s�   øé € ð
	Ø#×:Ñ:¸9ÓE×EˆJð ×)Ñ)Ø¸GÐaið *ó 
÷ 
ð 	
ñ FøÜô 	Ü�L‰LÐCÀYÐ^bˆLÔcÜ™Ñ+Ø¸gÐckð ,ó ÷ ð õ ûð	úñ

ùsS   ƒB	…< ™:š< žB	µB¶B	º< ¼BÁ-A?Á4A7Á5A?Á9BÁ:B	Á?BÂB	c               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )rC   rö  rb   Úanimation_urlrí  r_  r^  r“   r`  rG   r   rI   )rJ   s   "rK   rL   rK  «  s>   € ÷ 
ñ 
Øð
Ø+.ð
Ø9Fð
ØYfð
à*ð
ð 
ñ
rM   c           	   ƒ  ó€  <"  €  V P                  VRRR7      G Rj  x€L
 w  rgT P                  T'       d   \        R	TR
7      M
\        R4      T4      p	T P                  YYyYER7      G Rj  x€L
 #  LR  \         d>   p\        P                  RY(RR7       \        S
T `  YY4TR7      G Rj  x€L 
 u Rp?# Rp?ii ; i LQ5i)z@Feishu has no native GIF bubble; degrade to a downloadable file.ú.gifzanimation.gif)Údefault_extÚpreferred_nameNz,[Feishu] Failed to download animation %s: %sTr©  )rö  r2  rí  r^  r“   z,platform.feishu.media.gif_downgraded_caption)rí  z$platform.feishu.media.gif_downgraded)rö  rñ  re   rí  r^  r“   )	Ú_download_remote_documentr«  r¬  r  rN  Úsend_animationÚwarning_textr   r   )r|   rö  r2  rí  r^  r“   rñ  re   rW   Údegraded_captionr�  s   &&&&&&    €rK   r8  ÚFeishuAdapter.send_animation«  sÜ   øé € ð
	Ø)-×)GÑ)GØ¨6À/ð *Hó *÷ $Ñ ˆIð  ×,Ñ,ßRYŒAÐ<ÀgÕNÜÐ9Ó:¸GóEÐð ×'Ñ'Ø¸IØð (ó 
÷ 
ð 	
ñ$øô ô 	Ü�L‰LÐGÈÐfjˆLÔkÜ™Ñ/ØÀgÐksð 0ó ÷ ð õ ûð	úñ
ùs`   ƒB>…A1 œA/�A1 £B>¶4B>Á*B<Á+B>Á/A1 Á1B9Á<-B4Â)B,Â*B4Â.B9Â/B>Â4B9Â9B>c               ó    € V ^8„  d   QhRRRR/# )rC   rö  rb   rG   r’   rI   )rJ   s   "rK   rL   rK  Á  s   € ÷ ñ ¨3ð °>ñ rM   c           
   ƒ  ó–  "  € RVRVRR/pV P                   '       g   V# V P                  P                  V4      pVe   \        V4      #  V P	                  V4      pV P                  V P                   P                  P                  P                  P                  V4      G Rj  x€L
 pV'       d   \        VRR 4      ! 4       RJ d4   \        VR	R
4      p\        VRR4      p\        P                  RWV4       V# \        VRR4      p\        \        VRR4      ;'       g    R4      P                  4       P                  4       p	RTR\        \        VRR4      ;'       g    T4      RV P                  V	4      RT	;'       g    R/p
W P                  V&   \        V
4      #  Lù  \          d    \        P                  RTRR7       Tu # i ; i5i)z5Return real chat metadata from Feishu when available.rö  rp   r   ÚdmNrd  c                 ó   € R # rð   rI   rI   rM   rK   r$  Ú-FeishuAdapter.get_chat_info.<locals>.<lambda>Ì  ó   € ÁErM   Fr  ri  rn  zchat lookup failedz0[Feishu] Failed to get chat info for %s: [%s] %sÚdataÚ	chat_typerd   r‹   z'[Feishu] Failed to get chat info for %sTr©  )rT  rp  rñ   r”   Ú_build_get_chat_requestr  rŠ  r‹  ÚchatrÎ   r¬  r¶  rb   r  r±  Ú_map_chat_typer«  )r|   rö  r|  ÚcachedrD   r{  r  rn  rB  Úraw_chat_typer$  s   &&         rK   Úget_chat_infoÚFeishuAdapter.get_chat_infoÁ  s¢  é € à˜w¨°¸ÀÐFˆØ�|�|ˆ|ØˆOØ×&Ñ&×*Ñ*¨7Ó3ˆØÒÜ˜“<Ðð	Ø×2Ñ2°7Ó;ˆGØ!×/Ñ/°·±·±×0BÑ0B×0GÑ0G×0KÑ0KÈWÓU×UˆHßœw x°¹MÔJÓLÐPUÓUÜ˜x¨°Ó;�Ü˜h¨Ð/CÓD�Ü—‘ÐQÐSZÐbeÔfØ�Ü˜8 V¨TÓ2ˆDÜ¤¨¨k¸2Ó >× DÐ DÀ"ÓE×KÑKÓM×SÑSÓUˆMà˜7 F¬C´¸¸fÀdÓ0K×0VÐ0VÈwÓ,WØ˜×+Ñ+¨MÓ:¸JÈ×H]ÐH]ÐY]ðˆDð .2×!Ñ! 'Ñ*Ü˜“:Ðñ Vøô ô 	Ü�N‰NÐDÀgÐX\ˆNÔ]ØŠOð	üs]   ‚AG	Á
AF Â"FÂ#F Â/A	F Ã8G	Ã9A$F Å F Å?F ÆG	ÆF Æ%GÇG	ÇGÇG	c               ó    € V ^8„  d   QhRRRR/# r8  rI   )rJ   s   "rK   rL   rK  Ý  s   € ÷ ñ  cð ¨cñ rM   c                ó"   € VP                  4       # )z/Feishu text messages are plain text by default.)r  )r|   rO   s   &&rK   ro  ÚFeishuAdapter.format_messageÝ  s   € à�}‰}‹ÐrM   c               ó    € V ^8„  d   QhRRRR/# ©rC   rB  r
   rG   rI  rI   )rJ   s   "rK   rL   rK  â  s   € ÷ Jñ J cð J¨dñ JrM   c                ó^  € V P                   pV P                  V4      '       gj   V P                  V4      '       dQ   \        P                  ! \
        P                  ! 4       P                  V P                  3RRR7      P                  4        R# V P                  W P                  V4      4       R# )zZSDK dispatcher callback (background thread); queues for replay while the loop isn't ready.zfeishu-pending-inbound-drainerT)Útargetr™  rp   ÚdaemonN)rê  Ú_loop_accepts_callbacksÚ_enqueue_pending_inbound_eventrU  ÚThreadr  r  rý   Ú_drain_pending_inbound_eventsrë  Ú_submit_on_loopÚ_handle_message_event_data)r|   rB  r†  s   && rK   rá  ÚFeishuAdapter._on_message_eventâ  s„   € à�z‰zˆØ×+Ñ+¨D×1Ò1Ø×2Ñ2°4×8Ò8ô × Ò Ü&×3Ò3Ó5×9Ñ9À×AcÑAcÐ@eØ9À$ô÷ ‘%”'ÙØ×Ñ˜T×#BÑ#BÀ4Ó#HÖIrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rB  r
   rG   rr   rI   )rJ   s   "rK   rL   rK  ð  s   € ÷ ñ °3ð ¸4ñ rM   c           	     óz  € V P                   ;_uu_ 4        \        V P                  4      V P                  8¼  dv   V P                  P	                  ^ 4      p \        \        VRR4      RR4      p\        \        VRR4      ;'       g    R4      p\        P                  RV P                  V4       V P                  P                  V4       \        V P                  4      pV P                  '       * pRV n        RRR4       \        P                  R	X4       X#   \         d    Rp L˜i ; i  + '       g   i     L;; i)
zYQueue an event for replay; True when the caller should spawn the (single) drainer thread.ÚeventNr1   r€  rd   ri  zA[Feishu] Pending-inbound queue full (%d); dropped oldest event %sTzI[Feishu] Queued inbound event for replay (loop not ready, queue depth=%d))rk  rT   rj  rm  ÚpoprÎ   rb   r«  r¬  r  rM  rl  r¶  )r|   rB  Údroppedr1   r€  ÚdepthÚshould_starts   &&     rK   rT  Ú,FeishuAdapter._enqueue_pending_inbound_eventð  s	  € à×'×'Ó'Ü�4×/Ñ/Ó0°D×4SÑ4SÔSà×6Ñ6×:Ñ:¸1Ó=�ð+Ü%¤g¨g°wÀÓ&EÀyÐRVÓW�GÜ!$¤W¨W°lÀBÓ%G×%TÐ%TÈ9Ó!U�Jô —‘ØWØ×3Ñ3°Zôð ×(Ñ(×/Ñ/°Ô5Ü˜×4Ñ4Ó5ˆEØ#×<Ñ<Ô<ˆLØ,0ˆDÔ)÷! (ô" 	�‰ÐbÐdiÔjØÐøô !ô +Ø!*’Jð+ú÷ (×'ús1   •A D*Á8DÂA)D*ÄD'Ä$D*Ä&D'Ä'D*Ä*D:	c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK    s   € ÷ 36ñ 36¨tñ 36rM   c           	     ó  a € RpRpRpR V 3R llpR V 3R llp  \        S R	R4      '       gV   \        V! 4       4      pV'       d   \        P                  R
V4        S P                  ;_uu_ 4        RS n        RRR4       R# S P                  pS P                  V4      '       EdC   V! 4       pV'       g7   V! 4       '       d(    S P                  ;_uu_ 4        RS n        RRR4       R# KÒ  V U	u. uF.  p	S P                  VS P                  V	4      4      '       d   K,  V	NK0  	  p
p	V
'       d-   S P                  ;_uu_ 4        V
S P                  R&   RRR4       \        V4      \        V
4      ,
          '       d0   \        P                  R\        V4      \        V
4      ,
          4       V
'       g5   V! 4       '       d(    S P                  ;_uu_ 4        RS n        RRR4       R# EKÏ  W28¼  dM   \        P                  RV\        V! 4       4      4        S P                  ;_uu_ 4        RS n        RRR4       R# \        P                  ! V4       W1,          pEKB    + '       g   i     R# ; i  + '       g   i     R# ; iu up	i   + '       g   i     EL@; i  + '       g   i     R# ; i  + '       g   i     R# ; i  S P                  ;_uu_ 4        RS n        RRR4       i   + '       g   i     i ; i; i)ziDaemon-thread drainer: replay queued inbound events once the loop is ready (or drop on shutdown/timeout).g      Ð?g      ^@ç        c               ó   € V ^8„  d   QhRR/# )rC   rG   ú	list[Any]rI   )rJ   s   "rK   rL   ÚAFeishuAdapter._drain_pending_inbound_events.<locals>.__annotate__  s   € ÷ 	ñ 	˜9ñ 	rM   c                 óÄ   <€ SP                   ;_uu_ 4        SP                  R ,          p SP                  P                  4        RRR4       V #   + '       g   i     X # ; i):NNNN)rk  rj  rP  )Úbatchr|   s    €rK   Ú	_take_allÚ>FeishuAdapter._drain_pending_inbound_events.<locals>._take_all  sM   ø€ Ø×+×+Ó+Ø×4Ñ4°QÕ7�Ø×,Ñ,×2Ñ2Ô4÷ ,ð ˆL÷ ,Ö+ð ˆLús   –.AÁA	c               ó   € V ^8„  d   QhRR/# rø  rI   )rJ   s   "rK   rL   rg    s   € ÷ 	8ñ 	8˜dñ 	8rM   c                 óŒ   <€ S P                   ;_uu_ 4        S P                  '       * uuR R R 4       #   + '       g   i     R # ; ir{   )rk  rj  rˆ  s   €rK   Ú_queue_emptyÚAFeishuAdapter._drain_pending_inbound_events.<locals>._queue_empty  s*   ø€ Ø×+×+Ó+Ø×7Ñ7Ô7÷ ,×+×+Ó+ús	   –2²A	Tr¨  z;[Feishu] Dropped %d queued inbound event(s) during shutdownFN:Nrõ   Nz,[Feishu] Replayed %d queued inbound event(s)zO[Feishu] Adapter loop unavailable for %.0fs; dropped %d queued inbound event(s))rÎ   rT   r¬  r¶  rk  rl  rê  rS  rW  rX  rj  r$  r  ÚtimeÚsleep)r|   Úpoll_intervalÚmax_wait_secondsÚwaitedrj  rn  r^  r†  ri  ÚeÚrequeues   f          rK   rV  Ú+FeishuAdapter._drain_pending_inbound_events  s@  ø€ àˆØ ÐØˆ÷	ð 	÷	8ð 	8ð#	6ØÜ˜t Z°×6Ò6ä!¡)£+Ó.�GßÜŸ™Ð'dÐfmÔnØð6 ×+×+Ó+Ø05�Ô-÷ ,Ñ+ð5 —z‘z�Ø×/Ñ/°×5Ó5Ù%›K�Eß Ù'Ÿ>š>Ø"ð* ×+×+Ó+Ø05�Ô-÷ ,Ñ+ñ) !á*/Óv©% Q°t×7KÑ7KÈDÐRV×RqÑRqÐrsÓRt×7uŸq˜q©%�GÐvßØ!×7×7Ó7Ø?F˜D×8Ñ8¸Ñ<÷ 8ä˜5“z¤C¨£L×0Ô0ÜŸ™Ð$RÔTWÐX]ÓT^ÔadÐelÓamÕTmÔnß"¡|§~¢~Øð ×+×+Ó+Ø05�Ô-÷ ,Ñ+ò ØÔ-Ü—L‘LØiØ(¬#©i«kÓ*:ôð ð ×+×+Ó+Ø05�Ô-÷ ,Ñ+ô —
’
˜=Ô)ØÕ'“ç+×+Ð+ú×+×+Ð+üò% wç7×7Ð7ú÷  ,×+Ð+ú×+×+Ð+û�×+×+Ó+Ø05�Ô-÷ ,×+×+Ð+ýs¯   ›AK Á2IÂ#K Â(K Â7K ÃI1Ã+K Ã1)JÄJÄ%K ÅJ
ÅAK Æ3K ÇJÇ'.K È*J2È<!K ÉI.	É1J	ÊK Ê
J	Ê	K ÊJ/	Ê2K	ËK?ËK,	Ë#	K?Ë,K<Ë7K?c               ó    € V ^8„  d   QhRRRR/# rO  rI   )rJ   s   "rK   rL   rK  ;  s   € ÷ 
ñ 
°Sð 
¸Tñ 
rM   c           
   ƒ  óž  "  € \        VRR4      p\        VRR4      p\        VRR4      pV'       d   V'       d   \        VRR4      '       g   \        P                  R4       R# \        VRR4      pV'       d    V P                  V4      G Rj  x€L
 '       d   \        P                  RV4       R# V P	                  WC4      pVeF   \        P                  R	V4       VR
8X  d'   T P                  \        VRR4      ;'       g    R4       R# V P                  W\        VRR4      \        VRR4      V\        V4      R7      G Rj  x€L
  R#  L» L5i)zEShared inbound message handling for websocket and webhook transports.r\  Nr1   rÈ   rÒ   zA[Feishu] Dropping malformed inbound event: missing message/senderr€  z2[Feishu] Dropping duplicate/missing message_id: %sz#[Feishu] dropping inbound event: %sÚgroup_policy_rejectedrö  rd   rC  Úp2p)rB  r1   rÒ   rC  r€  Úis_bot)rÎ   r¬  r®  Ú_is_duplicateÚ_admitÚ_warn_once_empty_allowlist_denyÚ_process_inbound_messagerÏ   )r|   rB  r\  r1   rÈ   r€  Úreasons   &&     rK   rX  Ú(FeishuAdapter._handle_message_event_data;  s%  é € ä˜˜g tÓ,ˆÜ˜% ¨DÓ1ˆÜ˜ ¨$Ó/ˆßŸf¬G°F¸KÈ×,NÒ,NÜ�L‰LÐ\Ô]ÙÜ˜W l°DÓ9ˆ
ß 4×#5Ñ#5°jÓ#A×AÖAÜ�L‰LÐMÈzÔZÙØ—‘˜VÓ-ˆØÒÜ�L‰LÐ>ÀÔGØÐ0Ô0Ø×4Ñ4´W¸WÀiÐQSÓ5T×5ZÐ5ZÐXZÔ[ÙØ×+Ñ+Ø´'¸&À+ÈtÓ2TÜ˜g {°EÓ:ÀzÔZhÐioÓZpð ,ó 
÷ 	
ò 	
ñ Bñ	
ùs7   ‚7EºAEÂE	Â	EÂA(EÄAEÅEÅEÅEc               ó    € V ^8„  d   QhRRRR/# )rC   rB  ÚP2ImMessageMessageReadV1rG   rI  rI   )rJ   s   "rK   rL   rK  R  s   € ÷ mñ mÐ+Cð mÈñ mrM   c                óŒ   € \        \        VRR4      RR4      p\        P                  R\        VRR4      ;'       g    R4       R# )z7Ignore read-receipt events that Hermes does not act on.r\  Nr1   z([Feishu] Ignoring message_read event: %sr€  rd   )rÎ   r¬  r®  )r|   rB  r1   s   && rK   rß  Ú$FeishuAdapter._on_message_read_eventR  s<   € äœ' $¨°Ó6¸	À4ÓHˆÜ�‰Ð?ÄÈÐR^Ð`dÓAe×AkÐAkÐikÖlrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rB  r
   Úverbrb   rG   rI  rI   )rJ   s   "rK   rL   rK  W  s!   € ÷ 1ñ 1¨cð 1¸ð 1Àñ 1rM   c           	     	óÀ   € \        \        \        VR R4      RR4      ;'       g    R4      p\        P                  RW#4       V P                  P                  VR4       R# )r\  Nrö  rd   z[Feishu] Bot %s chat: %s)rb   rÎ   r¬  r$  rp  r]  )r|   rB  rˆ  rö  s   &&& rK   Ú_on_bot_membership_changeÚ'FeishuAdapter._on_bot_membership_changeW  sK   € Ü”gœg d¨G°TÓ:¸IÀrÓJ×PÐPÈbÓQˆÜ�‰Ð.°Ô>Ø×Ñ×!Ñ! '¨4Ö0rM   c               ó    € V ^8„  d   QhRRRR/# rO  rI   )rJ   s   "rK   rL   rK  \  s   € ÷ 9ñ 9¨#ð 9°$ñ 9rM   c                	ó*   € V P                  VR 4       R# )zadded toN©rŠ  ©r|   rB  s   &&rK   rç  Ú#FeishuAdapter._on_bot_added_to_chat\  s   € Ø×&Ñ& t¨ZÖ8rM   c               ó    € V ^8„  d   QhRRRR/# rO  rI   )rJ   s   "rK   rL   rK  _  s   € ÷ =ñ =¨cð =°dñ =rM   c                	ó*   € V P                  VR 4       R# )zremoved fromNrŽ  r�  s   &&rK   ré  Ú'FeishuAdapter._on_bot_removed_from_chat_  s   € Ø×&Ñ& t¨^Ö<rM   c               ó    € V ^8„  d   QhRRRR/# rO  rI   )rJ   s   "rK   rL   rK  b  s   € ÷ @ñ @¨ð @°ñ @rM   c                	ó0   € \         P                  R 4       R# )z'[Feishu] User entered P2P chat with botN©r¬  r®  r�  s   &&rK   rë  Ú"FeishuAdapter._on_p2p_chat_enteredb  s   € Ü�‰Ð>Ö?rM   c               ó    € V ^8„  d   QhRRRR/# rO  rI   )rJ   s   "rK   rL   rK  e  s   € ÷ :ñ :¨ð :°ñ :rM   c                	ó0   € \         P                  R 4       R# )z![Feishu] Message recalled by userNr–  r�  s   &&rK   rí  Ú"FeishuAdapter._on_message_recallede  s   € Ü�‰Ð8Ö9rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r¶  rb   Ú	make_coror
   rG   rI  rI   )rJ   s   "rK   rL   rK  h  s!   € ÷ 0ñ 0 cð 0°cð 0¸dñ 0rM   c                ó¨   € V P                   pV P                  V4      '       g   \        P                  RV4       R# V P	                  W2! 4       4       R# )zXSchedule ``make_coro()`` on the adapter loop, or log-and-drop when the loop isn't ready.z1[Feishu] Dropping %s before adapter loop is readyN)rê  rS  r¬  r¶  rW  )r|   r¶  rœ  r†  s   &&& rK   Ú_submit_if_readyÚFeishuAdapter._submit_if_readyh  sA   € à�z‰zˆØ×+Ñ+¨D×1Ò1Ü�N‰NÐNÐPUÔVÙØ×Ñ˜T 9£;Ö/rM   c               ó    € V ^8„  d   QhRRRR/# rO  rI   )rJ   s   "rK   rL   rK  p  s   € ÷ xñ x¨Cð x°Dñ xrM   c                óH   a aa€ ^ RI Ho S P                  RVVV 3R l4       R# )u^   drive.notice.comment_add_v1 â†’ feishu_comment.handle_drive_comment_event on the adapter loop.)Úhandle_drive_comment_eventzdrive comment eventc                 ól   <€ S! SP                   S SP                  \        \        SR R4      4      R7      # )Ú_owner_profileN)Úself_open_idÚ	secondary)rT  Ú_bot_open_idrr   rÎ   )rB  r¢  r|   s   €€€rK   r$  Ú7FeishuAdapter._on_drive_comment_event.<locals>.<lambda>s  s0   ø€ Ñ=WØ�L‰L˜$¨T×->Ñ->Ì$ÌwÐW[Ð]mÐosÓOtÓJuõ>wrM   N)Ú'plugins.platforms.feishu.feishu_commentr¢  rž  )r|   rB  r¢  s   ff@rK   rï  Ú%FeishuAdapter._on_drive_comment_eventp  s   ú€ åVØ×ÑÐ3ö 6wö 	xrM   c               ó    € V ^8„  d   QhRRRR/# rO  rI   )rJ   s   "rK   rL   rK  v  s   € ÷ hñ h¨cð h°dñ hrM   c                óH   a aa€ ^ RI Ho S P                  RVVV 3R l4       R# )uQ   vc.bot.meeting_invited_v1 â†’ feishu_meeting_invite.handle_meeting_invited_event.)Úhandle_meeting_invited_eventzmeeting invite eventc                 ó   <€ S! SS 4      # r{   rI   )rB  r­  r|   s   €€€rK   r$  Ú9FeishuAdapter._on_meeting_invited_event.<locals>.<lambda>y  s   ø€ Ñ>ZÐ[_ÐaeÔ>frM   N)Ú.plugins.platforms.feishu.feishu_meeting_inviter­  rž  )r|   rB  r­  s   ff@rK   rð  Ú'FeishuAdapter._on_meeting_invited_eventv  s   ú€ å_Ø×ÑÐ4Ö6fÖgrM   c               ó$   € V ^8„  d   QhRRRRRR/# ©rC   Ú
event_typerb   rB  r
   rG   rI  rI   )rJ   s   "rK   rL   rK  {  s&   € ÷ Rñ R¨Sð R¸ð RÀñ RrM   c                óæ  € \        VRR4      p\        \        VRR4      ;'       g    R4      p\        \        VRR4      ;'       g    R4      p\        VRR4      p\        \        VRR4      ;'       g    R4      pRV9   d   R	MR
p\        P                  RW„WW4       V P                  p	VR9   g    V'       d   V P                  V	4      '       g   R# V P                  W�P                  W4      4       R# )z>Route user reactions on bot messages as synthetic text events.r\  Nr€  rd   Úoperator_typeÚreaction_typer£  ÚcreatedÚaddedÚremovedz?[Feishu] Reaction %s on message %s (operator_type=%s, emoji=%s)>   rË   rÌ   )rÎ   rb   r¬  r®  rê  rS  rW  Ú_handle_reaction_event)
r|   r´  rB  r\  r€  r¶  Úreaction_type_objr£  r:  r†  s
   &&&       rK   rÒ  Ú FeishuAdapter._on_reaction_event{  sÕ   € ä˜˜g tÓ,ˆÜœ ¨°bÓ9×?Ð?¸RÓ@ˆ
ÜœG E¨?¸BÓ?×EÐEÀ2ÓFˆÜ# E¨?¸DÓAÐÜœÐ!2°LÀ"ÓE×KÐKÈÓLˆ
Ø%¨Ô3‘¸ˆÜ�‰ØMØ ô	
ð �z‰zˆØ˜NÔ*·*ÀD×D`ÑD`Ðae×DfÒDfÙØ×Ñ˜T×#>Ñ#>¸zÓ#PÖQrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rB  r
   rG   rI   )rJ   s   "rK   rL   rK  Ž  s   € ÷ %ñ %¨Cð %°Cñ %rM   c                ó(  € V P                   pV P                  V4      '       g&   \        P                  R4       V P	                  4       # \        VRR4      p\        VRR4      p\        VR/ 4      ;'       g    / p\        V\        4      '       dU   VP                  R4      '       d   V P                  W5VR7      # VP                  R4      '       d   V P                  W5VR7      # V P                  W P                  V4      4       V P	                  4       # )	a  Synchronous SDK card-action callback.

Approval/update-prompt buttons return the resolved card inline (the only reliable way
to sync all clients) and schedule the async resolution; other clicks are routed as
synthetic commands via ``_handle_card_action_event``.
z:[Feishu] Dropping card action before adapter loop is readyr\  Nr:  rè   rª  )r\  Úaction_valuer†  rÄ  )rê  rS  r¬  r¶  Ú_card_responserÎ   r  r”   rñ   Ú_handle_approval_card_actionÚ!_handle_update_prompt_card_actionrW  Ú_handle_card_action_event)r|   rB  r†  r\  r:  rÀ  s   &&    rK   rå  Ú%FeishuAdapter._on_card_action_triggerŽ  sò   € ð �z‰zˆØ×+Ñ+¨D×1Ò1Ü�N‰NÐWÔXØ×&Ñ&Ó(Ð(Ü˜˜g tÓ,ˆÜ˜ ¨$Ó/ˆÜ˜v w°Ó3×9Ð9°rˆÜ�l¤D×)Ò)Ø×Ñ ×0Ò0Ø×8Ñ8¸uÐfjÐ8ÓkÐkØ×ÑÐ =×>Ò>Ø×=Ñ=ÀEÐkoÐ=ÓpÐpØ×Ñ˜T×#AÑ#AÀ$Ó#GÔHØ×"Ñ"Ó$Ð$rM   c               ó    € V ^8„  d   QhRRRR/# )rC   r†  r
   rG   rr   rI   )rJ   s   "rK   rL   rK  ¥  s   € ÷ Zñ Z cð Z¨dñ ZrM   c                ó\   € V RJ;'       d"    \        \        V RR 4      ! 4       4      '       * # )zEReturn True when the adapter loop can accept thread-safe submissions.NrÐ  c                 ó   € R # rð   rI   rI   rM   rK   r$  Ú7FeishuAdapter._loop_accepts_callbacks.<locals>.<lambda>§  s   € ÑPUrM   ©rr   rÎ   )r†  s   &rK   rS  Ú%FeishuAdapter._loop_accepts_callbacks¤  s+   € ð ˜4Ð×YÐY¬¬W°T¸;ÉÔ-VÓ-XÓ(YÔ$YÐYrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r†  r
   ÚcororG   rr   rI   )rJ   s   "rK   rL   rK  ©  s!   € ÷ 
ñ 
 Cð 
¨sð 
°tñ 
rM   c                ó�   € ^ RI Hp V! W!\        R\        P                  R7      pVf   R# VP                  V P                  4       R# )zISchedule background work on the adapter loop with shared failure logging.)Úsafe_schedule_threadsafez4[Feishu] Failed to schedule background callback work)r¬  Úlog_messager-  FT)Úagent.async_utilsrÏ  r¬  Úloggingr/  Úadd_done_callbackÚ_log_background_failure)r|   r†  rÍ  rÏ  rK  s   &&&  rK   rW  ÚFeishuAdapter._submit_on_loop©  s?   € å>Ù)ØœvÐ3iÜ—o‘oô
ˆð Š>ÙØ× Ñ  ×!=Ñ!=Ô>ÙrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rq   rb   rG   rr   rI   )rJ   s   "rK   rL   rK  µ  s   € ÷ ?ñ ?¸3ð ?À4ñ ?rM   c                óð   € \        T;'       g    R4      P                  4       pV'       g   R# \        V P                  4      \        V P                  4      ,          pV'       g   R# RV9   ;'       g    W#9   # )zBReturn whether this card-action operator may answer gated prompts.rd   FTÚ*)rb   r  rÀ   rÊ  rÉ  )r|   rq   r  Úallowed_idss   &&  rK   Ú#_is_interactive_operator_authorizedÚ1FeishuAdapter._is_interactive_operator_authorizedµ  s[   € ä˜Ÿ˜ BÓ'×-Ñ-Ó/ˆ
ßÙÜ˜$Ÿ,™,Ó'¬#¨d×.GÑ.GÓ*HÕHˆßÙØ�kÑ!×>Ð> ZÑ%>Ð>rM   c               ó    € V ^8„  d   QhRRRR/# )rC   Ú	card_datar`  rG   r
   rI   )rJ   s   "rK   rL   rK  À  s   € ÷ 
ñ 
Ð":ð 
Àcñ 
rM   c                ó€   € \         f   R# \        4       pV e&   \        e   \        4       pRVn        Wn        W!n        V# )zJSynchronous card-callback response; ``card_data`` updates the card inline.NÚraw)ÚP2CardActionTriggerResponseÚCallBackCardr   rB  rÏ  )rÝ  r{  rÏ  s   &  rK   rÁ  ÚFeishuAdapter._card_response¿  s=   € ô 'Ò.ÙÜ.Ó0ˆØÒ ¤\Ò%=Ü“>ˆDØˆDŒIØ!ŒIØ ŒMØˆrM   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
rC   r\  r
   Ústater?   r¶  rb   ÚidentrG   zOptional[tuple[str, str, str]]rI   )rJ   s   "rK   rL   rK  Ì  s;   € ÷ [ñ [Øð[Ø$2ð[Ø;>ð[ØGJð[à	'ñ[rM   c          	     ó$  € \        VRR4      p\        \        VRR4      ;'       g    R4      pV P                  V4      '       g#   \        P	                  RY6;'       g    R4       R# \        \        \        VRR4      RR4      ;'       g    R4      p\        VP                  R	R4      ;'       g    R4      pV'       d7   V'       d/   Wx8w  d)   \        P	                  R
VP                  4       WHV4       R# YgV P                  V4      ;'       g    T3# )z�Shared operator/chat checks for approval + update-prompt clicks.

Returns ``(open_id, callback_chat_id, user_name)`` or None (already logged).
ÚoperatorNrq   rd   z$[Feishu] Unauthorized %s click by %sú	<unknown>Úcontextr÷  rö  z?[Feishu] %s callback chat mismatch for %s (expected=%s, got=%s))rÎ   rb   rÚ  r¬  r¶  rñ   Ú
capitalizeÚ_get_cached_sender_name)	r|   r\  rä  r¶  rå  rç  rq   Úcallback_chat_idÚexpected_chat_ids	   &$$$$    rK   Ú_validate_card_actionÚ#FeishuAdapter._validate_card_actionÌ  sî   € ô ˜5 *¨dÓ3ˆÜ”g˜h¨	°2Ó6×<Ð<¸"Ó=ˆØ×7Ñ7¸×@Ò@Ü�N‰NÐAÀ5×J`ÐJ`ÐU`ÔaÙÜœw¤w¨u°iÀÓ'FÈÐXZÓ[×aÐaÐ_aÓbÐÜ˜uŸy™y¨°BÓ7×=Ð=¸2Ó>Ðß× 0Ð5EÔ5YÜ�N‰NØQØ× Ñ Ó" EÐ=Môñ Ø¨$×*FÑ*FÀwÓ*O×*ZÐ*ZÐSZÐZÐZrM   c               ó(   € V ^8„  d   QhRRRRRRRR/# ©rC   r\  r
   rÀ  r’   r†  rG   rI   )rJ   s   "rK   rL   rK  â  s0   € ÷ kñ k°Sð kÈð kÐ^að kÐfiñ krM   c               ód  € VP                  R4      pVf&   \        P                  R4       V P                  4       # V P                  P                  V4      pV'       g'   \        P                  RV4       V P                  4       # \
        P                  VP                  R4      R4      pV P                  WRVR7      pVf   V P                  4       # Vw  r‰p
V P                  WFW¨V	R7      pV P                  W;4      '       g   V P                  4       # V P                  V P                  WjR	7      4      # )
zISchedule approval resolution and build the synchronous callback response.r«  z2[Feishu] Card action missing approval_id, ignoringz0[Feishu] Approval %s already resolved or unknownrª  r>   Úapproval©r\  rä  r¶  rå  )r«  r´  r•  rq   rö  )r´  r•  )
rñ   r¬  r®  rÁ  rz  r@   rî  Ú_resolve_approvalrW  rÚ  )r|   r\  rÀ  r†  r«  rä  r´  Úcheckedrq   rö  r•  rÍ  s   &$$$        rK   rÂ  Ú*FeishuAdapter._handle_approval_card_actionâ  s  € à"×&Ñ& }Ó5ˆØÒÜ�L‰LÐMÔNØ×&Ñ&Ó(Ð(Ø×$Ñ$×(Ñ(¨Ó5ˆßÜ�L‰LÐKÈ[ÔYØ×&Ñ&Ó(Ð(Ü%×)Ñ)¨,×*:Ñ*:¸?Ó*KÈVÓTˆØ×,Ñ,°5ÈZÐ_jÐ,ÓkˆØŠ?Ø×&Ñ&Ó(Ð(Ø&-Ñ#ˆ˜)Ø×%Ñ%Ø#¸iÐbið &ó 
ˆð ×#Ñ# D×/Ò/Ø×&Ñ&Ó(Ð(Ø×"Ñ" 4×#EÑ#EÈVÐ#EÓ#iÓjÐjrM   c               ó(   € V ^8„  d   QhRRRRRRRR/# rñ  rI   )rJ   s   "rK   rL   rK  ø  s0   € ÷ pñ p¸#ð pÈ^ð pÐcfð pÐknñ prM   c               óö  € VP                  R4      pVf&   \        P                  R4       V P                  4       # V P                  P                  V4      pV'       g'   \        P                  RV4       V P                  4       # \        VP                  RR4      ;'       g    R4      P                  4       P                  4       pVR9  d'   \        P                  RV4       V P                  4       # V P                  WRVR7      pVf   V P                  4       # Vw  r‰p
V P                  WFW¨V	R	7      pV P                  W;4      '       g   V P                  4       # V P                  V P                  WjR
7      4      # )zNSchedule update prompt resolution and build the synchronous callback response.rÅ  z7[Feishu] Card action missing update_prompt_id, ignoringz5[Feishu] Update prompt %s already resolved or unknownrÄ  rd   z8[Feishu] Card action has invalid update prompt answer=%rzupdate promptrô  )rq   rö  )rÁ  r•  >   rž  rÈ  )rñ   r¬  r®  rÁ  r}  rb   r  r±  rî  Ú_resolve_update_promptrW  rÞ  )r|   r\  rÀ  r†  r½  rä  rÁ  rö  rq   rö  r•  rÍ  s   &$$$        rK   rÃ  Ú/FeishuAdapter._handle_update_prompt_card_actionø  sT  € à ×$Ñ$Ð%7Ó8ˆ	ØÒÜ�L‰LÐRÔSØ×&Ñ&Ó(Ð(Ø×)Ñ)×-Ñ-¨iÓ8ˆßÜ�L‰LÐPÐR[Ô\Ø×&Ñ&Ó(Ð(Ü�\×%Ñ%Ð&CÀRÓH×NÐNÈBÓO×UÑUÓW×]Ñ]Ó_ˆØ˜Ô#Ü�L‰LÐSÐU[Ô\Ø×&Ñ&Ó(Ð(Ø×,Ñ,°5È_ÐdmÐ,ÓnˆØŠ?Ø×&Ñ&Ó(Ð(Ø&-Ñ#ˆ˜)Ø×*Ñ*¨9¸iÐbiÐ*ÓjˆØ×#Ñ# D×/Ò/Ø×&Ñ&Ó(Ð(Ø×"Ñ" 4×#JÑ#JÐRXÐ#JÓ#nÓoÐorM   c               ó8   € V ^8„  d   QhRRRRRRRRRRR	RR
RRR/# )rC   Ústatesr¹  rå  r
   r¶  rb   rq   rö  Úunauthorized_fmtÚoperator_reprrG   úOptional[dict[str, str]]rI   )rJ   s   "rK   rL   rK  	  sN   € ÷ ñ Ø2ðØ;>ðØGJðØUXðØcfðàðà.1ðð 
"ñrM   c               óÎ  € VP                  V4      pV'       g   \        P                  RW24       R# V P                  V4      '       g   \        P	                  WgV4       R# \        VP                  RR4      ;'       g    R4      p	V	'       d(   V'       d    W•8w  d   \        P	                  RW2W•4       R# VP                  VR4      pV'       g   \        P                  RW24       V# )zSRe-validate on the loop thread (state may have changed since the callback) and pop.z*[Feishu] %s %s already resolved or unknownNrö  rd   z2[Feishu] %s %s chat mismatch (expected=%s, got=%s)z9[Feishu] %s %s already resolved while validating callback)rñ   r¬  r®  rÚ  r¶  rb   r]  )
r|   rý  rå  r¶  rq   rö  rþ  rÿ  rä  rí  s
   &$$$$$$$  rK   Ú_pop_validated_prompt_stateÚ)FeishuAdapter._pop_validated_prompt_state	  s±   € ð
 —
‘
˜5Ó!ˆßÜ�L‰LÐEÀuÔTÙØ×7Ñ7¸×@Ò@Ü�N‰NÐ+¸EÔBÙÜ˜uŸy™y¨°BÓ7×=Ð=¸2Ó>Ðß§Ð,<Ô,GÜ�N‰NÐOÐQVÐ_oÔyÙØ—
‘
˜5 $Ó'ˆßÜ�L‰LÐTÐV[ÔcØˆrM   rq   rö  c               ó0   € V ^8„  d   QhRRRRRRRRRRRR	/# )
rC   r«  r
   r´  rb   r•  rq   rö  rG   rI  rI   )rJ   s   "rK   rL   rK  $	  sD   € ÷  [ñ  [Øð [Ø(+ð [Ø8;ð [ØILð [Ø\_ð [à	ñ [rM   c          
   ƒ  óv  "  € T P                  V P                  TRYERT;'       g    RR7      pV'       g   R#  ^ RIHp V! VR,          V4      p\        P                  RW†R,          W#4       V'       gi   VR	8w  d`   \        VP                  R
R4      ;'       g    T;'       g    R4      p	V	'       d'    V P                  V	\        R4      4      G Rj  x€L
  R# R# R# R#  L  \         d    \        P                  RRR7        R# i ; i  \         d"   p
\        P                  RT
4        Rp
?
R# Rp
?
ii ; i5i)z8Pop approval state and unblock the waiting agent thread.ÚApprovalz:[Feishu] Unauthorized approval click by %s for approval %srè  ©rý  rå  r¶  rq   rö  rþ  rÿ  N)Úresolve_gateway_approvalr±  zIFeishu button resolved %d approval(s) for session %s (choice=%s, user=%s)r>   rö  rd   z platform.shared.approval_expiredz'[Feishu] expired-approval notice failedTr©  z9Failed to resolve gateway approval from Feishu button: %s)r  rz  Útools.approvalr  r¬  r$  rb   rñ   r|  r   r«  r®  r  )r|   r«  r´  r•  rq   rö  rä  r  r{  Ú_chatrW   s   &&&&$$     rK   rõ  ÚFeishuAdapter._resolve_approval$	  s,  é € ð ×0Ñ0Ø×'Ñ'¨{À*ÐV]ØYØ!×0Ð0 [ð 1ó 
ˆ÷
 Ùð	[Ý?Ù,¨U°=Õ-AÀ6ÓJˆEÜ�K‰KØ[Ø˜]Õ+¨Vô÷ ˜V vÔ-ô ˜EŸI™I i°Ó4×EÐE¸×EÐEÀ2ÓF�ßð_Ø"Ÿi™iØ!ÜÐ@ÓAó÷ ò ñ ñ .‘5ñøô %ô _ÜŸ™Ð%NÐY]˜×^ð_ûäô 	[Ü�L‰LÐTÐVY×ZÒZûð	[üsv   ‚3D9¶D9¹A D
 Â	D
 Â$D
 Â4C! ÃCÃC! ÃD9ÃC! Ã!"DÄD
 ÄD9ÄDÄD
 Ä
D6ÄD1Ä+D9Ä1D6Ä6D9c               ó0   € V ^8„  d   QhRRRRRRRRRRRR	/# )
rC   r½  r
   rÁ  rb   r•  rq   rö  rG   rI  rI   )rJ   s   "rK   rL   rK  F	  sD   € ÷ Lñ LØðLØ&)ðLØ69ðLØGJðLØZ]ðLà	ñLrM   c          
   ƒ  ó$  "  € V P                  V P                  VRVVRVR7      pV'       g   R#  V P                  V4       \        P	                  RVR,          W#4       R#   \
         d"   p\        P                  RT4        Rp?R# Rp?ii ; i5i)z@Persist an update prompt answer for the detached update process.zUpdate promptz=[Feishu] Unauthorized update prompt click by %s for prompt %sr  NzAFeishu update prompt resolved for session %s (answer=%s, user=%s)r±  z*Failed to resolve Feishu update prompt: %s)r  r}  ré  r¬  r$  r«  r  )r|   r½  rÁ  r•  rq   rö  rä  rW   s   &&&&$$  rK   rú  Ú$FeishuAdapter._resolve_update_promptF	  s�   é € ð ×0Ñ0Ø×,Ñ,°IÀ_Ð^eØÐ.mØ!ð 1ó 
ˆ÷
 Ùð	LØ×.Ñ.¨vÔ6Ü�K‰KØSØ�mÕ$ föøô ô 	LÜ�L‰LÐEÀs×KÒKûð	Lüs.   ‚-B°/A! ÁBÁ!BÁ,BÂBÂBÂBc               ó$   € V ^8„  d   QhRRRRRR/# r³  rI   )rJ   s   "rK   rL   rK  Z	  s!   € ÷ '
ñ '
°sð '
À#ð '
È$ñ '
rM   c           
   ƒ  óž  "  € V P                   '       g   R# \        VRR4      p\        \        VRR4      ;'       g    R4      pV'       g   R#  V P                  V4      pV P	                  V P                   P
                  P                  P                  P                  V4      G Rj  x€L
 pV P                  V4      '       g   R# \        \        VRR4      RR4      ;'       g    . pV'       d
   V^ ,          MRpV'       g   R# \        VRR4      p	\        \        V	RR4      ;'       g    R4      V P                  8w  d   R# \        \        VR	R4      ;'       g    R4      p
\        \        VR
R4      ;'       g    R4      pV
'       g   R#  \        TRR4      p\        TRR4      p\        \        TRR4      ;'       g    R4      pRT9   d   RMRpRT RT 2p\        P                  RYþT4       T P                  T\         P"                  Y¬Y²TR7      G Rj  x€L
  R#  ELx  \         d    \        P                  RRR7        R# i ; i L25i)zVFetch the reacted-to message; if it was sent by this bot, emit a synthetic text event.Nr\  r€  rd   rB  r  rÈ   r]  rö  rC  r{  z5[Feishu] Failed to fetch message for reaction routingTr©  rw   r·  r£  ÚUNKNOWNr¸  r¹  rº  z	reaction:r¤  zD[Feishu] Routing reaction %s:%s on bot message %s as synthetic event©rŒ   rÆ  rö  rÒ   Úevent_chat_typeÚraw_messager€  )rT  rÎ   rb   Ú_build_get_message_requestr  rŠ  r‹  r1   rñ   rv  r  r«  r¬  r®  r$  Ú_dispatch_synthetic_eventr#   ÚTEXT)r|   r´  rB  r\  r€  rD   r{  r  rn  rÈ   rö  Úchat_type_rawÚuser_id_objr¼  r£  r:  Úsynthetic_texts   &&&              rK   r»  Ú$FeishuAdapter._handle_reaction_eventZ	  s  é € à�|�|ˆ|ÙÜ˜˜g tÓ,ˆÜœ ¨°bÓ9×?Ð?¸RÓ@ˆ
ßÙð	Ø×5Ñ5°jÓAˆGØ!×/Ñ/°·±·±×0BÑ0B×0JÑ0J×0NÑ0NÐPWÓX×XˆHØ×+Ñ+¨H×5Ò5ÙÜœG H¨f°dÓ;¸WÀdÓK×QÐQÈrˆEß#�%˜–(¨ˆCßÙô ˜S (¨DÓ1ˆFÜ”7˜6 4¨Ó,×2Ð2°Ó3°t·|±|ÔCÙÜœ' # y°"Ó5×;Ð;¸Ó<ˆGÜ¤¨¨[¸%Ó @× IÐ IÀEÓJˆMßÙð ô
 ˜e Y°Ó5ˆÜ# E¨?¸DÓAÐÜœÐ!2°LÀ"ÓE×RÐRÈÓSˆ
Ø%¨Ô3‘¸ˆØ$ V H¨A¨j¨\Ð:ˆÜ�‰ÐZÐ\bÐpzÔ{Ø×,Ñ,Ø¬k×.>Ñ.>ÈØ)È
ð -ó 
÷ 	
ò 	
ò3 Yøô  ô 	Ü�L‰LÐPÐ[_ˆLÔ`Úð	úñ	
ùsŒ   ‚A	IÁIÁAH" Â'HÂ(H" ÃIÃH" Ã$
H" Ã/H" ÄIÄ<H" Å IÅH" ÅH" Å;H" Æ
BIÈIÈIÈH" È""IÉIÉIÉIc               ó    € V ^8„  d   QhRRRR/# )rC   Útokenrb   rG   rr   rI   )rJ   s   "rK   rL   rK  ƒ	  s   € ÷ 
ñ 
¨sð 
°tñ 
rM   c                ó(  € \         P                   ! 4       pV P                  P                  4        UUu. uF  w  r4W$,
          \        8”  g   K  VNK  	  pppV F  pV P                  V K  	  WP                  9   d   R# W P                  V&   R# u uppi )zTReturn True if this card action token was already processed within the dedup window.TF)rp  ri  r  Ú%_FEISHU_CARD_ACTION_DEDUP_TTL_SECONDS)r|   r  Únowr   ÚtsÚexpireds   &&    rK   Ú_is_card_action_duplicateÚ'FeishuAdapter._is_card_action_duplicateƒ	  s~   € ä�iŠi‹kˆà"&×":Ñ":×"@Ñ"@Ô"BÔwÑ"B™˜ÀcÅhÔQvÑFv—1�1Ñ"BˆÑwÛˆAØ×(Ñ(¨Ò+ñ à×,Ñ,Ô,ÙØ*-× Ñ  Ñ'Ùùó xs   ³BÁBc               ó    € V ^8„  d   QhRRRR/# rO  rI   )rJ   s   "rK   rL   rK  �	  s   € ÷ 
ñ 
°Cð 
¸Dñ 
rM   c              ƒ  óÒ  "  € \        VRR4      p\        \        VRR4      ;'       g    R4      pV'       d0   V P                  V4      '       d   \        P	                  RV4       R# \        VRR4      p\        \        VRR4      ;'       g    R4      p\        VRR4      p\        \        VR	R4      ;'       g    R4      pV'       d	   V'       g   \        P	                  R
4       R# \        VRR4      p\        \        VRR4      ;'       g    R4      p	\        VR/ 4      ;'       g    / p
RV	 2pV
'       d$    VR\
        P                  ! V
RR7       2,          p\        P                  RW—V4       T P                  T\        P                  T\        VRRR7      RY;'       g    \        \        P                  ! 4       4      R7      G Rj  x€L
  R#   \         d     L…i ; i L5i)zHRoute Feishu interactive card button clicks as synthetic COMMAND events.r\  Nr  rd   z1[Feishu] Dropping duplicate card action token: %sré  r÷  rç  rq   zB[Feishu] Card action missing chat_id or operator open_id, droppingr:  rE  r!  rè   z/card r÷   Fr<  zB[Feishu] Routing card action %r from %s in %s as synthetic commandrÞ   r"  r  )rÎ   rb   r#  r¬  r®  r?  r@  r«  r$  r  r#   ÚCOMMANDr	   ÚuuidÚuuid4)r|   rB  r\  r  ré  rö  rç  rq   r:  Ú
action_tagrÀ  r  s   &&          rK   rÄ  Ú'FeishuAdapter._handle_card_action_event�	  s§  é € ä˜˜g tÓ,ˆÜ”G˜E 7¨BÓ/×5Ð5°2Ó6ˆß�T×3Ñ3°E×:Ò:Ü�L‰LÐLÈeÔTÙÜ˜% ¨DÓ1ˆÜ”g˜g ~°rÓ:×@Ð@¸bÓAˆÜ˜5 *¨dÓ3ˆÜ”g˜h¨	°2Ó6×<Ð<¸"Ó=ˆßŸgÜ�L‰LÐ]Ô^ÙÜ˜ ¨$Ó/ˆÜœ ¨°Ó3×?Ð?°xÓ@ˆ
Ü˜v w°Ó3×9Ð9°rˆØ! * Ð.ˆßðØ A¤d§j¢j°ÈEÔ&RÐ%SÐ"TÕT�ô 	�‰ÐXÐZdÐovÔwØ×,Ñ,Ø¬k×.AÑ.AÈ7Ü%¨g¸tÈdÔSÐelØ×)CÐ)C´#´d·j²j³lÓ2Cð -ó 
÷ 	
ò 	
øô ô Ùðúñ	
ùsU   ‚5G'¸G'ÁA9G'Ã	G'ÃAG'Ä)G'Ä:"G ÅA1G'ÇG%ÇG'ÇG"ÇG'Ç!G"Ç"G'c               ó8   € V ^8„  d   QhRRRRRRRRRRR	RR
RRR/# )rC   rŒ   rb   rÆ  r#   rö  rÒ   r
   r  r  r€  rG   rI  rI   )rJ   s   "rK   rL   rK  ­	  sX   € ÷ @ñ @Øð@Ø*5ð@Ø@Cð@ØPSð@Øfið@àð@à&)ð@ð 
ñ@rM   c          
   ƒ  óÒ  "  € V P                  V4      G Rj  x€L
 pV P                  V4      G Rj  x€L
 p	T P                  TV	P                  R4      ;'       g    T;'       g    RV P	                  W•R7      VR,          VR,          RVR,          R7      p
\        WW¦WpP                  V4      \        P                  ! 4       R	7      pV P                  V4      G Rj  x€L
  R#  LÉ L² L
5i)
zUWrap a reaction/card click as a MessageEvent and run it through the guarded pipeline.Nrp   úFeishu Chat©Ú	chat_infor  rw   r•  Úuser_id_alt)rö  rõ  rC  rw   r•  Ú	thread_idr1  )rŒ   rÆ  Úsourcer  r€  Úchannel_promptÚ	timestamp)
Ú_resolve_sender_profilerI  Úbuild_sourcerñ   Ú_resolve_source_chat_typer"   Ú_resolve_channel_promptr   r   Ú_handle_message_with_guards)r|   rŒ   rÆ  rö  rÒ   r  r  r€  Úsender_profiler0  r3  Úsynthetic_events   &$$$$$$$    rK   r  Ú'FeishuAdapter._dispatch_synthetic_event­	  sÚ   é € ð
  $×;Ñ;¸IÓF×FˆØ×,Ñ,¨WÓ5×5ˆ	Ø×"Ñ"ØØ—m‘m FÓ+×GÐG¨w×GÐG¸-Ø×4Ñ4¸yÐ4ÓjØ" 9Õ-Ø$ [Õ1ØØ& }Õ5ð #ó 
ˆô 'Ø¸Ø!×2NÑ2NÈwÓ2WÜ—l’l“nô
ˆð
 ×.Ñ.¨Ó?×?Ò?ñ! GÙ5ñ 	@ùs>   ‚C'—C!˜C'°C#±'C'Á	C'Á#A7C'ÃC%ÃC'Ã#C'Ã%C'c               ó    € V ^8„  d   QhRRRR/# )rC   rö  rb   rG   úasyncio.LockrI   )rJ   s   "rK   rL   rK  Å	  s   € ÷ ñ  cð ¨lñ rM   c                óÐ  € V P                   P                  V4      pVe   V P                   P                  V4       V# \        V P                   4      V P                  8¼  dc   \        R V P                   P                  4        4       \        \        V P                   4      4      4      pV P                   P                  V4       \        P                  ! 4       pW P                   V&   V# )zbPer-chat asyncio.Lock for serial processing; LRU-bounded, never evicts a held lock if any is free.c              3  óZ   "  € T F!  w  rVP                  4       '       d   K  Vx € K#  	  R # 5ir{   )Úlocked)rÕ   rÛ   Úlks   &  rK   r×   Ú/FeishuAdapter._get_chat_lock.<locals>.<genexpr>Ì	  s   é € ÐVÑ*B¡ È"Ï)É)Ï+Ÿ1š1Ó*Bùs   ‚+¡
+)ro  rñ   Úmove_to_endrT   rI  r³  r  Úiterr]  rQ   rV  )r|   rö  rü  Úvictims   &&  rK   Ú_get_chat_lockÚFeishuAdapter._get_chat_lockÅ	  s¶   € à×Ñ×#Ñ# GÓ,ˆØÒØ×Ñ×(Ñ(¨Ô1ØˆKÜˆt×ÑÓ  D×$;Ñ$;Ô;ÜÑV¨$×*:Ñ*:×*@Ñ*@Ô*BÓVÔX\Ô]aÐbf×brÑbrÓ]sÓXtÓuˆFØ×Ñ× Ñ  Ô(Ü�|Š|‹~ˆØ$(×Ñ˜Ñ!ØˆrM   c               ó    € V ^8„  d   QhRRRR/# ©rC   r\  r"   rG   rI  rI   )rJ   s   "rK   rL   rK  Ò	  s   € ÷ -ñ -°|ð -Èñ -rM   c              ƒ  óX  "  € VP                   '       d"   \        VP                   RR4      ;'       g    RMRpV P                  V4      pT;_uu_4       GRj  x€L
  V P                  V4      G Rj  x€L
  RRR4      GRj  x€L
  R#  L/ L L
  + GRj  x€L 
 '       g   i     R# ; i5i)z\Run one event through the agent pipeline under the per-chat lock (openclaw createChatQueue).rö  rd   N)r3  rÎ   rH  Úhandle_message)r|   r\  rö  Ú	chat_locks   &&  rK   r:  Ú)FeishuAdapter._handle_message_with_guardsÒ	  sm   é € à@EÇÇÀ”'˜%Ÿ,™,¨	°2Ó6×<Ð<¸"øÐRTˆØ×'Ñ'¨Ó0ˆ	ß—9’9Ø×%Ñ% eÓ,×,Ð,÷ —9“9Ù,÷ —9—9“9üsd   ‚0B*³$B*ÁBÁB*ÁBÁ0B	Á1BÁ5B*Â BÂB*Â	BÂB*ÂB'	ÂBÂ
B'	ÂB'	Â!	B*c               ó   € V ^8„  d   QhRR/# rø  rI   )rJ   s   "rK   rL   rK  Ú	  s   € ÷ oñ o Dñ orM   c                	ój   € \        \        R R4      4      P                  4       P                  4       R9  # )ÚFEISHU_REACTIONSrê   >   Ú0ÚnoÚfalse)rb   r�  r  r±  rˆ  s   &rK   Ú_reactions_enabledÚ FeishuAdapter._reactions_enabledÚ	  s.   € ÜÔ%Ð&8¸&ÓAÓB×HÑHÓJ×PÑPÓRÐZnÑnÐnrM   c               ó0   € V ^8„  d   QhRRRRRRRRRRRR/# )	rC   rˆ  rb   r€  rå  Úbuild_requestr
   ÚapirG   rI   )rJ   s   "rK   rL   rK  Ý	  s9   € ÷ ñ ¨ð ¸#ð Àcð ÐZ]ð Ðdgð Ðloñ rM   c              ƒ  ó`  "  €  V P                  WT! 4       4      G Rj  x€L
 pV P                  V4      '       d   \        VRR4      ;'       g    R# \        P	                  RWV\        VRR4      \        VRR4      4       R#  Lc  \
         d    \        P                  RYTRR7        R# i ; i5i)	z]Shared add/remove reaction wrapper: returns the response data on success, else None (logged).NrB  Tz6[Feishu] %s reaction %s on %s rejected: code=%s msg=%sr  rn  z$[Feishu] %s reaction %s on %s raisedr©  )r  rv  rÎ   r¬  r®  r«  r¶  )r|   rˆ  r€  rå  rY  rZ  r{  s   &&&&&& rK   Ú_reaction_callÚFeishuAdapter._reaction_callÝ	  s®   é € ð		kØ!×/Ñ/°°]³_ÓE×EˆHØ×'Ñ'¨×1Ò1Ü˜x¨°Ó6×>Ð>¸$Ð>Ü�L‰LØHØ˜Z¬°¸6À4Ó)HÌ'ÐRZÐ\aÐcgÓJhôñ ñ Føô ô 	kÜ�N‰NÐAÀ4ÐPZÐeiˆNÕjÙð	küsO   ‚B.„B �BžB ¹B ÁB ÁB.Á/B Á?B.ÂB Â$B+Â'B.Â*B+Â+B.c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r€  rb   r£  rG   r_  rI   )rJ   s   "rK   rL   rK  ë	  s&   € ÷ Pñ P¨cð P¸sð PÀ}ñ PrM   c              ƒ  ó0  aa"  € V P                   '       d   S'       d	   S'       g   R# R VV3R llpV P                  RSSW0P                   P                  P                  P                  P
                  4      G Rj  x€L
 pVe   \        VRR4      # R#  L5i)zRReturn the reaction_id on success, else None. The id is needed later for deletion.Nc               ó   € V ^8„  d   QhRR/# r„  rI   )rJ   s   "rK   rL   Ú1FeishuAdapter._add_reaction.<locals>.__annotate__ð	  s   € ÷ 	lñ 	l˜ñ 	lrM   c                 óê   <€ ^ RI Hp Hp VP                  4       P	                  RS/4      P                  4       pV P                  4       P                  S4      P                  V4      P                  4       # )rõ   )ÚCreateMessageReactionRequestÚ CreateMessageReactionRequestBodyr£  )Úlark_oapi.api.im.v1rc  rd  r  r·  r"  r€  r‡  )rc  rd  rV   r£  r€  s      €€rK   Ú_buildÚ+FeishuAdapter._add_reaction.<locals>._buildð	  s]   ø€ ßjØ3×;Ñ;Ó=×KÑKÈ\Ð[eÐLfÓg×mÑmÓoˆDØ/×7Ñ7Ó9×DÑDÀZÓP×]Ñ]Ð^bÓc×iÑiÓkÐkrM   ÚAddÚreaction_id)rT  r\  rŠ  r‹  Úmessage_reactionr  rÎ   )r|   r€  r£  rf  rB  s   &ff  rK   Ú_add_reactionÚFeishuAdapter._add_reactionë	  sz   ùé € à�|�|ˆ|§:·ZÙ÷	lñ 	lð
 ×(Ñ(¨°
¸JÈ×P\ÑP\×P_ÑP_×PbÑPb×PsÑPs×PzÑPzÓ{×{ˆØ59Ò5EŒw�t˜]¨DÓ1ÐOÈ4ÐOñ |ùs   „BŸB§ABÁ<BÁ=Bc               ó$   € V ^8„  d   QhRRRRRR/# )rC   r€  rb   ri  rG   rr   rI   )rJ   s   "rK   rL   rK  ø	  s!   € ÷ 	 ñ 	 °ð 	 À3ð 	 È4ñ 	 rM   c              ƒ  	ó  aa"  € V P                   '       d   S'       d	   S'       g   R # R VV3R llpV P                  RSSW0P                   P                  P                  P                  P
                  4      G Rj  x€L
 pVRJ#  L5i)Fc               ó   € V ^8„  d   QhRR/# r„  rI   )rJ   s   "rK   rL   Ú4FeishuAdapter._remove_reaction.<locals>.__annotate__ü	  s   € ÷ 	rñ 	r˜ñ 	rrM   c                 óˆ   <€ ^ RI Hp  V P                  4       P                  S4      P	                  S4      P                  4       # )rõ   )ÚDeleteMessageReactionRequest)re  rr  r  r€  ri  r"  )rr  r€  ri  s    €€rK   rf  Ú.FeishuAdapter._remove_reaction.<locals>._buildü	  s5   ø€ ÝHØ/×7Ñ7Ó9×DÑDÀZÓP×\Ñ\Ð]hÓi×oÑoÓqÐqrM   ÚRemoveN)rT  r\  rŠ  r‹  rj  r“  )r|   r€  ri  rf  rB  s   &ff  rK   Ú_remove_reactionÚFeishuAdapter._remove_reactionø	  sl   ùé € Ø�|�|ˆ|§:·[Ù÷	rñ 	rð ×(Ñ(¨°:¸{ÈF×T`ÑT`×TcÑTc×TfÑTf×TwÑTw×T~ÑT~Ó×ˆØ˜4ÐÐñ @ùs   „BŸB§ABÁ<BÁ=	Bc               ó    € V ^8„  d   QhRRRR/# rK  rI   )rJ   s   "rK   rL   rK  
  s   € ÷ 
*ñ 
*¨|ð 
*Àñ 
*rM   c              ƒ  	ól  "  € VP                   pV P                  4       '       d   V'       d   W P                  9   d   R # V P                  V\        4      G R j  x€L
 pV'       dL   V P                  pW4V&   VP                  V4       \        V4      \        8”  d   VP                  RR7       K(  R # R #  LY5i)NF©Úlast)	r€  rV  r  rk  Ú_FEISHU_REACTION_IN_PROGRESSrE  rT   Ú&_FEISHU_PROCESSING_REACTION_CACHE_SIZEÚpopitem)r|   r\  r€  ri  Úcaches   &&   rK   Úon_processing_startÚ!FeishuAdapter.on_processing_start
  s•   é € Ø×%Ñ%ˆ
Ø×&Ñ&×(Ò(·
¸j×LnÑLnÔ>nÙØ ×.Ñ.¨zÔ;WÓX×XˆßØ×6Ñ6ˆEØ +�*ÑØ×Ñ˜jÔ)Ü�e“*ÔEÔEØ—‘ 5�Ö)ñ Fñ	 ñ Yùs   ‚*B4­+B4ÁB2ÁB4Á%AB4c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r\  r"   Úoutcomer$   rG   rI  rI   )rJ   s   "rK   rL   rK  
  s(   € ÷ Kñ K°,ð KÐIZð KÐ_cñ KrM   c              ƒ  	ó–  "  € VP                   pV P                  4       '       d	   V'       g   R # V P                  P                  V4      pV'       d>   V P	                  W44      G R j  x€L
 '       g   R # V P                  P                  VR 4       V\        P                  J d!   V P                  V\        4      G R j  x€L
  R # R #  L^ L
5ir{   )
r€  rV  r  rñ   ru  r]  r$   ÚFAILURErk  Ú_FEISHU_REACTION_FAILURE)r|   r\  r‚  r€  Ústart_reaction_ids   &&&  rK   Úon_processing_completeÚ$FeishuAdapter.on_processing_complete
  s¤   é € Ø×%Ñ%ˆ
Ø×&Ñ&×(Ò(·
ÙØ ×>Ñ>×BÑBÀ:ÓNÐßØ×.Ñ.¨zÓM×MÖMñ Ø×.Ñ.×2Ñ2°:¸tÔDØÔ'×/Ñ/Ó/Ø×$Ñ$ ZÔ1IÓJ×JÒJñ 0ñ Nñ Kùs5   ‚*C	­$C	ÁC	Á&CÁ'	C	Á1AC	Â<CÂ=	C	ÃC	c               ó$   € V ^8„  d   QhRRRRRR/# )rC   Ú	remote_iprb   ÚstatusrG   rI  rI   )rJ   s   "rK   rL   rK  
  s&   € ÷ Nñ N°ð N¸cð NÀdñ NrM   c                óR  € \         P                   ! 4       pV P                  P                  V4      ;'       g    ^ RV3w  rEpV'       d   W6,
          \        8¼  d   ^ TrdV^,          pV\        ,          ^ 8X  d   \
        P                  RWBWV,
          4       WBV3V P                  V&   R# )zfCount consecutive error responses per IP (openclaw createWebhookAnomalyTracker); WARN every threshold.rd   zY[Feishu] Webhook anomaly: %d consecutive error responses (%s) from %s over the last %.0fsN)rp  rh  rñ   Ú#_FEISHU_WEBHOOK_ANOMALY_TTL_SECONDSÚ!_FEISHU_WEBHOOK_ANOMALY_THRESHOLDr¬  r¶  )r|   rŠ  r‹  r   r{  Ú_last_statusÚ
first_seens   &&&    rK   Ú_record_webhook_anomalyÚ%FeishuAdapter._record_webhook_anomaly
  s–   € ä�iŠi‹kˆØ*.×*FÑ*F×*JÑ*JÈ9Ó*U×*eÐ*eÐZ[Ð]_ÐadÐYeÑ'ˆ˜Zß�SÕ%Ô)LÔLØ ! 3�:Ø��
ˆØÔ4Õ4¸Ô9Ü�N‰NØkØ˜y°
Õ*:ôð 49À*Ð2Mˆ×$Ñ$ YÓ/rM   c               ó    € V ^8„  d   QhRRRR/# )rC   rŠ  rb   rG   rI  rI   )rJ   s   "rK   rL   rK  ,
  s   € ÷ :ñ :°ð :¸ñ :rM   c                ó>   € V P                   P                  VR4       R# )zCReset the anomaly counter for remote_ip after a successful request.N)rh  r]  )r|   rŠ  s   &&rK   Ú_clear_webhook_anomalyÚ$FeishuAdapter._clear_webhook_anomaly,
  s   € à×$Ñ$×(Ñ(¨°DÖ9rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rö  rb   Ú	parent_idz
str | NonerG   rI   )rJ   s   "rK   rL   rK  1
  s'   € ÷ Añ A¨sð A¸zð AÐU_ñ ArM   c                ód   € ^ RI Hp \        \        V RR4      RR4      ;'       g    / pV! WAV4      # )zbHonour ``channel_prompts: {<chat_id>: "<prompt>"}`` in PlatformConfig.extra (as Discord/Slack do).)Úresolve_channel_promptr;  NrQ  )rô  rš  rÎ   )r|   rö  r˜  rš  rQ  s   &&&  rK   r9  Ú%FeishuAdapter._resolve_channel_prompt1
  s1   € åAÜœ  h°Ó5°wÀÓE×KÐKÈˆÙ% e°iÓ@Ð@rM   r|  c               ó4   € V ^8„  d   QhRRRRRRRRRRRR	R
R/# )rC   rB  r
   r1   rÒ   rC  rb   r€  r|  rr   rG   rI  rI   )rJ   s   "rK   rL   rK  7
  sD   € ÷ :7ñ :7Øð:7Ø%(ð:7Ø58ð:7ØEHð:7ØVYð:7Øcgð:7à	ñ:7rM   c             ƒ  	óô  "  € V P                  V4      G R j  x€L
 w  rxršr¼V\        P                  8X  d3   \        W|4      pVP	                  R4      '       d   \        P
                  pV\        P                  8X  d)   V'       g!   V	'       g   \        P                  RV4       R # V\        P
                  8w  d%   \        V4      pV'       d   V'       d   V RV 2MTp\        VRR 4      ;'       g    R p\        VRR 4      ;'       g-    \        VRR 4      ;'       g    \        VRR 4      ;'       g    R pV'       d   V P                  V4      G R j  x€L
 MR p\        VRR 4      ;'       g-    \        VR	R 4      ;'       g    \        VR
R 4      ;'       g    Rp\        VRR4      ;'       g    Rp\        P                  RVR8X  d   RMRYXP                  TV'       d   RMRVVR,          \        V	4      4	       V P                  V4      G R j  x€L
 pV P                  W6R7      G R j  x€L
 pT P!                  TVP#                  R4      ;'       g    T;'       g    RV P%                  VVR7      VR	,          VR,          VVR,          VVR7	      p\'        YxTTYYT
TTTT P)                  TT;'       g    R 4      \*        P,                  ! 4       R7      pV P/                  V4      G R j  x€L
  R #  ELÕ ELž Lä LÌ L5i)NÚ/z*[Feishu] Ignoring empty text message id=%sr�  r2  r˜  Úupper_message_idÚroot_idrq   rw   rß   rè  rö  rd   z\[Feishu] Inbound %s message received: id=%s type=%s chat_id=%s sender=%s:%s text=%r media=%dr{  r>  r"  rÌ   r”  :Néx   N©r|  rp   r.  r/  r•  r1  )	rö  rõ  rC  rw   r•  r2  r1  r|  r€  )rŒ   rÆ  r3  r  r€  Ú
media_urlsÚmedia_typesÚmedia_text_inlinedÚreply_to_message_idÚreply_to_textr4  r5  )Ú_extract_message_contentr#   r  rx  rû   r'  r¬  r®  rk  rÎ   Ú_fetch_message_textr$  rè   rT   rI  r6  r7  rñ   r8  r"   r9  r   r   Ú_dispatch_inbound_event)r|   rB  r1   rÒ   rC  r€  r|  rŒ   Úinbound_typer£  r¤  r¥  r�   Úhintr2  r¦  r§  Úsender_primaryrö  r0  r;  r3  r  s   &$$$$$$                rK   r€  Ú&FeishuAdapter._process_inbound_message7
  sÞ  é € ð [_×ZwÑZwÐxó  [A÷  UAÑQˆ˜JÐ5GØœ;×+Ñ+Ô+Ü,¨TÓ<ˆDØ�‰˜s×#Ò#Ü*×2Ñ2�àœ;×+Ñ+Ô+·DÇÜ�L‰LÐEÀzÔRÙØœ;×.Ñ.Ô.Ü& xÓ0ˆDßß.2˜$˜˜t D 6Ñ*¸�ô
 ˜G [°$Ó7×?Ð?¸4ˆ	ä�G˜[¨$Ó/÷ 9ð 9´7¸7ÐDVÐX\Ó3]÷ 9ð 9Ü�w 	¨4Ó0÷9ð 9Ø48ð 	÷ Pc˜d×6Ñ6Ð7JÓK×KÐKÐhlˆä�I˜y¨$Ó/÷ Cð C´7¸9ÀiÐQUÓ3V÷ Cð CÜ�y *¨dÓ3÷Cð CØ7Bð 	ô ˜' 9¨bÓ1×7Ð7°RˆÜ�‰ØjØ Ô&‰D¨G°Z×ASÑASÐU\ß‰E ¨¸¸d½ÄSÈÃ_ô	
ð ×,Ñ,¨WÓ5×5ˆ	Ø#×;Ñ;¸IÐ;ÓU×UˆØ×"Ñ"ØØ—m‘m FÓ+×GÐG¨w×GÐG¸-Ø×4Ñ4¸yÐZcÐ4ÓdØ" 9Õ-Ø$ [Õ1ØØ& }Õ5ØØ!ð #ó 

ˆô "Ø¸ÈTØ!ÀkØ1Ø 3À=Ø×7Ñ7¸À×ARÐARÈdÓSÜ—l’l“nô
ˆ
ð ×*Ñ*¨:Ó6×6Ò6òo UAò, Lñ 6ÙUñ( 	7ùs¯   ‚K8—K,˜A+K8ÂK8ÂAK8ÃK8Ã1K8ÄK8ÄK8Ä2
K8Ä=K8ÅK/ÅK8Å,K8ÆK8ÆK8Æ-A K8ÈK2ÈK8È'K4È('K8É	K8ÉBK8Ë%K6Ë&K8Ë/K8Ë2K8Ë4K8Ë6K8c               ó    € V ^8„  d   QhRRRR/# rK  rI   )rJ   s   "rK   rL   rK  s
  s   € ÷ 6ñ 6°<ð 6ÀDñ 6rM   c              ƒ  óP  "  € VP                   \        P                  8X  d2   VP                  4       '       g   V P	                  V4      G Rj  x€L
  R# V P                  V4      '       d   V P                  V4      G Rj  x€L
  R# V P                  V4      G Rj  x€L
  R#  LS L# L
5i)zHApply Feishu-specific burst protection before entering the base adapter.N)rÆ  r#   r  Ú
is_commandÚ_enqueue_text_eventÚ_should_batch_media_eventÚ_enqueue_media_eventr:  ©r|   r\  s   &&rK   rª  Ú%FeishuAdapter._dispatch_inbound_events
  s‡   é € à×Ñ¤×!1Ñ!1Ô1¸%×:JÑ:J×:LÒ:LØ×*Ñ*¨5Ó1×1Ð1ÙØ×)Ñ)¨%×0Ò0Ø×+Ñ+¨EÓ2×2Ð2ÙØ×.Ñ.¨uÓ5×5Ò5ñ 2ñ 3á5ùs@   ‚5B&¸B&ÁB ÁB&Á*B&Á>B"Á?B&ÂB$ÂB&Â"B&Â$B&c               ó    € V ^8„  d   QhRRRR/# )rC   r\  r"   rG   rr   rI   )rJ   s   "rK   rL   rK  ~
  s   € ÷ Jñ J¨|ð JÀñ JrM   c                	óÖ   € \         P                  \         P                  \         P                  \         P                  0p\        VP                  ;'       d    VP                  V9   4      # r{   )r#   ÚPHOTOÚVIDEOÚDOCUMENTÚAUDIOrr   r£  rÆ  )r|   r\  Ú	batchables   && rK   r³  Ú'FeishuAdapter._should_batch_media_event~
  sM   € Ü ×&Ñ&¬×(9Ñ(9¼;×;OÑ;OÔQ\×QbÑQbÐcˆ	Ü�E×$Ñ$×HÐH¨×);Ñ);¸yÑ)HÓIÐIrM   c               ó    € V ^8„  d   QhRRRR/# )rC   r\  r"   rG   rb   rI   )rJ   s   "rK   rL   rK  ‚
  s   € ÷ Qñ Q lð Q°sñ QrM   c                	óV   € V P                  V4       R VP                  P                   2# )z:media:)Ú_text_batch_keyrÆ  rè   rµ  s   &&rK   Ú_media_batch_keyÚFeishuAdapter._media_batch_key‚
  s,   € Ø×&Ñ& uÓ-Ð.¨g°e×6HÑ6H×6NÑ6NÐ5OÐPÐPrM   c               ó$   € V ^8„  d   QhRRRRRR/# ©rC   r)  r"   ÚincomingrG   rr   rI   )rJ   s   "rK   rL   rK  †
  s'   € ÷ ~ñ ~¨\ð ~À\ð ~ÐVZñ ~rM   c                	ón   € V P                   VP                   8H  ;'       d    \        P                  W4      # r{   )rÆ  rE  Ú_text_batch_is_compatible©r)  rÆ  s   &&rK   Ú_media_batch_is_compatibleÚ(FeishuAdapter._media_batch_is_compatible…
  s-   € à×$Ñ$¨×(=Ñ(=Ñ=×}Ð}Ä-×BiÑBiÐjrÓB}Ð}rM   c               ó    € V ^8„  d   QhRRRR/# rK  rI   )rJ   s   "rK   rL   rK  ‰
  s   € ÷ .ñ .°ð .Àñ .rM   c              ƒ  	óp  "  € V P                  V4      pV P                  P                  V4      pVf"   WP                  V&   V P                  V4       R # V P	                  W14      '       g;   V P                  V4      G R j  x€L
  WP                  V&   V P                  V4       R # VP                  P                  VP                  4       VP                  P                  VP                  4       VP                  P                  VP                  4       VP                  '       d,   V P                  VP                  VP                  4      Vn
        VP                  Vn        VP                  '       d-   VP                  Vn        VP                  VP                  n        V P                  V4       R #  EL45ir{   )rÂ  rx  rñ   Ú_schedule_media_batch_flushrÊ  Ú_flush_media_batch_nowr£  r  r¤  r¥  rŒ   Ú_merge_captionr5  r€  r3  )r|   r\  rî   r)  s   &&  rK   r´  Ú"FeishuAdapter._enqueue_media_event‰
  sR  é € Ø×#Ñ# EÓ*ˆØ×.Ñ.×2Ñ2°3Ó7ˆØÒØ/4×'Ñ'¨Ñ,Ø×,Ñ,¨SÔ1ÙØ×.Ñ.¨x×?Ò?Ø×-Ñ-¨cÓ2×2Ð2Ø/4×'Ñ'¨Ñ,Ø×,Ñ,¨SÔ1ÙØ×Ñ×"Ñ" 5×#3Ñ#3Ô4Ø×Ñ×#Ñ# E×$5Ñ$5Ô6Ø×#Ñ#×*Ñ*¨5×+CÑ+CÔDØ�:�:ˆ:Ø ×/Ñ/°·±¸u¿z¹zÓJˆHŒMØ"Ÿ_™_ˆÔØ××ÐØ"'×"2Ñ"2ˆHÔØ).×)9Ñ)9ˆH�O‰OÔ&Ø×(Ñ(¨Ö-ò 3ùs!   ‚A=F6Á?F3Â B%F6Ä&AF6Å4A F6c               ó    € V ^8„  d   QhRRRR/# ©rC   rî   rb   rG   rI  rI   )rJ   s   "rK   rL   rK   
  s   € ÷ cñ c¨sð c°tñ crM   c                	óR   € V P                  V P                  WP                  4       R # r{   )Ú_reschedule_batch_taskry  Ú_flush_media_batch©r|   rî   s   &&rK   rÎ  Ú)FeishuAdapter._schedule_media_batch_flush 
  s   € Ø×#Ñ# D×$CÑ$CÀS×JaÑJaÖbrM   c               ó    € V ^8„  d   QhRRRR/# rÓ  rI   )rJ   s   "rK   rL   rK  £
  s   € ÷ 
ñ 
¨Cð 
°Dñ 
rM   c              ƒ  	ó„   "  € V P                  V P                  WP                  V P                  4      G R j  x€L
  R #  L5ir{   )Ú_delayed_flushry  Ú_media_batch_delay_secondsrÏ  r×  s   &&rK   rÖ  Ú FeishuAdapter._flush_media_batch£
  s7   é € Ø×!Ñ!Ø×+Ñ+¨S×2QÑ2QÐSW×SnÑSnó
÷ 	
ô 	
ùs   ‚5A ·>¸A c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )rC   Útask_maprÄ   rî   rb   Údelayr£   Ú	flush_nowr
   rG   rI  rI   )rJ   s   "rK   rL   rK  ©
  s3   € ÷ (ñ (Ð'>ð (ÀSð (ÐQVð (Ðcfð (Ðkoñ (rM   c              ƒ  óJ  "  € \         P                  ! 4       p \         P                  ! V4      G Rj  x€L
  V! V4      G Rj  x€L
  V P                  V4      VJ d   V P	                  VR4       R# R#  L? L1  T P                  T4      TJ d   T P	                  TR4       i i ; i5i)z[Sleep ``delay`` then flush; drop our own task handle from ``task_map`` (not a successor's).N)rQ   Úcurrent_taskrq  rñ   r]  )rß  rî   rà  rá  rã  s   &&&& rK   rÛ  ÚFeishuAdapter._delayed_flush¨
  sŠ   é € ô ×+Ò+Ó-ˆð	(Ü—-’- Ó&×&Ð&Ù˜C“.× Ð à�|‰|˜CÓ  LÓ0Ø—‘˜S $Ö'ñ 1ñ 'Ù øà�|‰|˜CÓ  LÓ0Ø—‘˜S $Õ'ð 1üs>   ‚B#™A6 ²A2³A6 ÁA4ÁA6 Á+B#Á2A6 Á4A6 Á6*B Â B#c               ó    € V ^8„  d   QhRRRR/# rÓ  rI   )rJ   s   "rK   rL   rK  ³
  s   € ÷ 6ñ 6°ð 6¸ñ 6rM   c              ƒ  	óä   "  € V P                   P                  VR 4      pV'       g   R # \        P                  RV\	        VP
                  4      4       V P                  V4      G R j  x€L
  R #  L5i)Nz6[Feishu] Flushing media batch %s with %d attachment(s))rx  r]  r¬  r$  rT   r£  r:  )r|   rî   r\  s   && rK   rÏ  Ú$FeishuAdapter._flush_media_batch_now³
  sU   é € Ø×+Ñ+×/Ñ/°°TÓ:ˆßÙÜ�‰ÐLÈcÔSVÐW\×WgÑWgÓShÔiØ×.Ñ.¨uÓ5×5Ô5ùs   ‚A%A0Á'A.Á(A0c               ó    € V ^8„  d   QhRRRR/# )rC   r,  rb   rG   rI   )rJ   s   "rK   rL   rK  º
  s   € ÷ >ñ >°cð >¸cñ >rM   c              ƒ  	ó\   "  € V P                  VR R7      p\        WR7      G Rj  x€L
 #  L5i)ú.jpgr¿  ©rú  N)Ú_guess_remote_extensionr   )r|   r,  rú  s   && rK   r.  Ú$FeishuAdapter._download_remote_imageº
  s+   é € Ø×*Ñ*¨9¸fÐ*ÓEˆÜ)¨)Ô=×=Ð=Ñ=ùs   ‚#,¥*¦,c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   Úfile_urlrb   r5  r6  rG   r[  rI   )rJ   s   "rK   rL   rK  ¾
  s0   € ÷ Oñ O¸ð OÈSð OÐbeð OÐjyñ OrM   c          	   ƒ  	ó&  "  € ^ RI Hp ^ RIHpHp V! V4      '       g   \        RVR,           24      hV! RRRV./R7      ;_uu_4       GR	j  x€L
 pVP                  VR
RRR/R7      G R	j  x€L
 pVP                  4        \        VP                  P                  RR4      4      p	VP                  p
R	R	R	4      GR	j  x€L
  V P                  VX	W2R7      p\        X
V4      G R	j  x€L
 V3#  Lž L� L2  + GR	j  x€L 
 '       g   i     LI; i L(5i)rõ   )Ússrf_redirect_guard)Úcreate_ssrf_safe_async_clientÚis_safe_urlz&Blocked unsafe URL (SSRF protection): :NéP   Ng      >@Tr{  )r<  Úfollow_redirectsÚevent_hooksNz
User-Agentz)Mozilla/5.0 (compatible; HermesAgent/1.0)ÚAcceptz*/*)ÚheadersúContent-Typerd   )Úcontent_typeÚdefault_namer5  )rô  rñ  Útools.url_safetyrò  ró  rU   rñ   Úraise_for_statusrb   rø  rO   Ú_derive_remote_filenamer   )r|   rï  r5  r6  rñ  rò  ró  rå  r{  Úcontent_type_hdrrV   Úfilenames   &&$$        rK   r7  Ú'FeishuAdapter._download_remote_document¾
  s  é € Ý>ßOÙ˜8×$Ò$ÜÐEÀhÈsÅmÀ_ÐUÓVÐVÙ0Ø¨4¸jÐK^ÐJ_Ð=`÷
÷ 
õ 
àØ#ŸZ™ZØ <Ð1\Ð^fÐhmÐ"nð (ó ÷ ˆHð ×%Ñ%Ô'ô  # 8×#3Ñ#3×#7Ñ#7¸ÈÓ#KÓLÐØ×#Ñ#ˆD÷
÷ 
ð ×/Ñ/ØÐ#3À.ð 0ó 
ˆô 5°T¸8ÓD×DÀhÐNÐNñ
ñ÷
÷ 
÷ 
ò 
úñ Eùsm   ‚ADÁC-ÁDÁC3Á-C/Á.AC3Â3DÂ>C1Â?'DÃ&DÃ'DÃ/C3Ã1DÃ3D	Ã9C<Ã:
D	ÄD	Ä	Dc               ó$   € V ^8„  d   QhRRRRRR/# )rC   Úurlrb   r,  rG   rI   )rJ   s   "rK   rL   rK  Ô
  s&   € ÷ Fñ F Sð F°cð F¸cñ FrM   c               	óü   € \        T ;'       g    R P                  R^4      ^ ,          4      P                  P                  4       pV\        \
        ,          \        ,          \        \        4      ,          9   d   V# T# )rd   Ú?)	r   rQ  r  r±  Ú_IMAGE_EXTENSIONSÚ_AUDIO_EXTENSIONSÚ_VIDEO_EXTENSIONSrÀ   r   )r  r,  rú  s   &$ rK   rì  Ú%FeishuAdapter._guess_remote_extensionÓ
  si   € ä�C—I�I˜2×$Ñ$ S¨!Ó,¨QÕ/Ó0×7Ñ7×=Ñ=Ó?ˆØÔ/Ô2CÕCÔFWÕWÔZ]Ô^vÓZwÕwÔxˆsð  	Fð  Fð  	FrM   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )rC   rï  rb   rú  rû  r5  rG   rI   )rJ   s   "rK   rL   rK  Ù
  s2   € ÷ ñ ¨#ð Àð ÐSVð Ðehð Ðmpñ rM   c               	ó¶  € \        T ;'       g    R P                  R^4      ^ ,          4      P                  ;'       g    Tp\        V4      P                  P	                  4       pV'       gn   \
        P                  ! T;'       g    R P                  R^4      ^ ,          P                  4       P	                  4       ;'       g    R 4      ;'       g    TpV V 2pV# )rd   r  Ú;)r   rQ  rp   r  r±  Ú	mimetypesÚguess_extensionr  )rï  rú  rû  r5  r…  rú  Úguesseds   &$$$   rK   rþ  Ú%FeishuAdapter._derive_remote_filenameØ
  s±   € ä˜(Ÿ.˜. b×/Ñ/°°QÓ7¸Õ:Ó;×@Ñ@×PÐPÀLˆ	Ü�9‹o×$Ñ$×*Ñ*Ó,ˆßÜ×/Ò/°×1CÐ1CÀ×0JÑ0JÈ3ÐPQÓ0RÐSTÕ0U×0[Ñ0[Ó0]×0cÑ0cÓ0e×0kÐ0kÐikÓl×{Ð{Ðp{ˆGØ$˜+ g YÐ/ˆIØÐrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rè   r
   rG   rI   )rJ   s   "rK   rL   rK  â
  s   € ÷ ñ  sð ¨sñ rM   c                	ó@  € \        V \        4      '       dB   \        R/ V P                  4        UUu/ uF  w  rV\        P                  V4      bK  	  uppB # \        V \        4      '       d&   V  Uu. uF  p\        P                  V4      NK  	  up# V # u uppi u upi )NrI   )r  r”   r	   r  rE  Ú_namespace_from_mappingrˆ   )rè   rî   rc  s   &  rK   r  Ú%FeishuAdapter._namespace_from_mappingá
  sˆ   € ä�eœT×"Ò"Ü"ÑwÐhm×hsÑhsÔhuÔ%vÑhuÑ[dÐ[^ c¬=×+PÑ+PÐQUÓ+VÒ&VÑhuÒ%vÑwÐwÜ�eœT×"Ò"ÙLQÓRÉEÀD”M×9Ñ9¸$Ö?ÉEÑRÐRØˆùó &wùâRs   ±!BÁ2Bc               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )rC   rŠ  rb   Úanomalyr‹  rF   rŒ   r_  Újson_msgrG   r
   rI   )rJ   s   "rK   rL   rK  é
  s8   € ÷ 6ñ 6¨ð 6°sð 6ÀCð 6È}ð 6Ø"/ð6Ø;>ñ6rM   c                ó’   € V P                  W4       Ve   \        P                  ! RVRV/VR7      # \        P                  ! W4R7      # )zRRecord an anomaly for ``remote_ip`` and build the matching aiohttp error response.r  rn  )r‹  )r‹  rŒ   )r‘  r   Újson_responseÚResponse)r|   rŠ  r  r‹  rŒ   r  s   &&&&&&rK   Ú_webhook_rejectÚFeishuAdapter._webhook_rejecté
  sC   € ð 	×$Ñ$ YÔ8ØÒÜ×$Ò$ f¨f°e¸XÐ%FÈvÔVÐVÜ�|Š| 6Ô5Ð5rM   c               ó    € V ^8„  d   QhRRRR/# )rC   rD   r
   rG   rI   )rJ   s   "rK   rL   rK  ñ
  s   € ÷ L;ñ L;°Sð L;¸Sñ L;rM   c              ƒ  	ó\
  "  € \        VR R4      ;'       g    RpV P                  V P                   RV P                   RV 24      '       g+   \        P                  RV4       V P                  VRRR4      # \        VR/ 4      ;'       g    / p\        VP                  R	R
4      ;'       g    R
4      P                  R4      ^ ,          P                  4       P                  4       pV'       d2   VR8w  d+   \        P                  RWB4       V P                  VRRR4      # \        VRR4      pVe6   V\        8”  d+   \        P                  RWR4       V P                  VRRR4      #  \        P                  ! \        V\        4      \         R7      G Rj  x€L
 p \(        P*                  ! TP-                  R 4      4      pT P2                  '       dÎ   TP                  R"4      ;'       g    / p\        TP                  R#4      ;'       g    TP                  R#4      ;'       g    R
4      p	T	'       dD   \4        P6                  ! T	P9                  4       T P2                  P9                  4       4      '       g+   \        P                  R$T4       T P                  TR%R&R'4      # TP                  R(4      R)8X  d)   \:        P<                  ! R*TP                  R*R
4      /4      # T P>                  '       dM   T PA                  TPB                  T4      '       g+   \        P                  R+T4       T P                  TR,R&R-4      # TP                  R.4      '       d+   \        PE                  R/4       T P                  TR0RR1R7      # T PG                  T4       \        TP                  R"4      ;'       g    / P                  R24      ;'       g    R
4      p
T PI                  T4      pT
R79   d   T PK                  Y«4       MQT PL                  P                  T
4      pTf"   \        PO                  R3T
;'       g    R4       M\        Y4      ! T4       \:        P<                  ! R4^ R5R6/4      #  ELÊ  \"         d.    \        P                  RT4       T P                  TRRR4      u # \$         d3    \        P                  R\         T4       T P                  TRRR4      u # \&         d    T P                  TRRRR7      u # i ; i  \(        P.                  \0        3 d    T P                  TRRR!R7      u # i ; i5i)8ÚremoteNri  r¤  z+[Feishu] Webhook rate limit exceeded for %sÚ429i­  zToo Many Requestsrø  rù  rd   r  úapplication/jsonz=[Feishu] Webhook rejected: unexpected Content-Type %r from %sÚ415iŸ  zUnsupported Media TypeÚcontent_lengthz2[Feishu] Webhook body too large (%d bytes) from %sÚ413i�  zRequest body too larger;  z+[Feishu] Webhook body exceeds limit from %sz6[Feishu] Webhook body read timed out after %ds from %sÚ408i˜  zRequest TimeoutÚ400i�  zfailed to read body)r  râ  zinvalid jsonr9  r  z=[Feishu] Webhook rejected: invalid verification token from %sz	401-tokeni‘  zInvalid verification tokenr   Úurl_verificationÚ	challengez4[Feishu] Webhook rejected: invalid signature from %sz401-sigzInvalid signatureÚencryptzL[Feishu] Encrypted webhook payloads are not supported by Hermes webhook modez400-encryptedz,encrypted webhook payloads are not supportedr´  z([Feishu] Ignoring webhook event type: %sr  rn  Úok>   rÐ  rØ  )(rÎ   Ú_check_webhook_rate_limitr  Ú_webhook_pathr¬  r¶  r  rb   rñ   rQ  r  r±  Ú_FEISHU_WEBHOOK_MAX_BODY_BYTESrQ   rE  rX   Ú$_FEISHU_WEBHOOK_BODY_TIMEOUT_SECONDSrU   rG  r«  r?  rá  Údecoderâ  ÚUnicodeDecodeErrorrÝ  ÚhmacÚcompare_digestÚencoder   r  rÜ  Ú_is_webhook_signature_validrø  r  r•  r  rÒ  Ú_WEBHOOK_EVENT_HANDLERSr®  )r|   rD   rŠ  rø  rú  r#  Ú
body_bytesr\  r9  Úincoming_tokenr´  rB  Úhandlers   &&           rK   Ú_handle_webhook_requestÚ%FeishuAdapter._handle_webhook_requestñ
  s‰  é € Ü˜W h°Ó5×BÐB¸ˆ	ð ×-Ñ-°·±°¸aÀ×@RÑ@RÐ?SÐSTÐU^ÐT_Ð.`×aÒaÜ�N‰NÐHÈ)ÔTØ×'Ñ'¨	°5¸#Ð?RÓSÐSä˜' 9¨bÓ1×7Ð7°RˆÜ˜7Ÿ;™; ~°rÓ:×@Ð@¸bÓA×GÑGÈÓLÈQÕO×UÑUÓW×]Ñ]Ó_ˆß˜LÐ,>Ô>Ü�N‰NÐZÐ\hÔtØ×'Ñ'¨	°5¸#Ð?WÓXÐXä  Ð*:¸DÓAˆØÒ%¨.Ô;YÔ*YÜ�N‰NÐOÐQ_ÔkØ×'Ñ'¨	°5¸#Ð?WÓXÐXð	_Ü&-×&6Ò&6Ü1°'Ô;YÓZÜ<ô'÷ !ˆJð	XÜ—j’j ×!2Ñ!2°7Ó!;Ó<ˆGð
 ×#×#Ð#Ø—[‘[ Ó*×0Ð0¨bˆFÜ  §¡¨GÓ!4×!RÐ!R¸¿¹ÀGÓ8L×!RÐ!RÐPRÓSˆNç!¬×)<Ò)<Ø×%Ñ%Ó'¨×)AÑ)A×)HÑ)HÓ)J÷*ò *ô —‘Ð^Ð`iÔjØ×+Ñ+¨I°{ÀCÐIeÓfÐfð �;‰;�vÓÐ"4Ô4Ü×$Ò$ k°7·;±;¸{ÈBÓ3OÐ%PÓQÐQà××Ð T×%EÑ%EÀgÇoÁoÐWa×%bÒ%bÜ�N‰NÐQÐS\Ô]Ø×'Ñ'¨	°9¸cÐCVÓWÐWà�;‰;�y×!Ò!Ü�L‰LÐgÔhØ×'Ñ'Ø˜?¨CÐ:hð (ó ð ð 	×#Ñ# IÔ.ä˜'Ÿ+™+ hÓ/×5Ð5°2×:Ñ:¸<ÓH×NÐNÈBÓOˆ
Ø×+Ñ+¨GÓ4ˆØÐ]Ô]Ø×#Ñ# JÕ5à×2Ñ2×6Ñ6°zÓBˆGØŠÜ—‘ÐGÈ×I`ÐI`ÐW`Õaä˜Ô& tÔ,Ü× Ò  &¨!¨U°DÐ!9Ó:Ð:òq!øô ô 	YÜ�N‰NÐHÈ)ÔTØ×'Ñ'¨	°5¸#Ð?WÓXÒXÜô 	RÜ�N‰NÐSÔUyð  |Eô  FØ×'Ñ'¨	°5¸#Ð?PÓQÒQÜô 	_Ø×'Ñ'¨	°5¸#ÐH]Ð'Ó^Ò^ð	_ûô
 ×$Ñ$Ô&8Ð9ô 	XØ×'Ñ'¨	°5¸#ÈÐ'ÓWÒWð	Xüså   ‚A
T,Á=T,Â T,Â,A T,Ã-A7T,Å%-Q ÆQÆQ Æ%S6 Æ=T,ÇT,Ç'T,ÈT,È T,È/AT,É2A9T,Ë,!T,ÌA T,ÍAT,Î'T,Ï A(T,Ð)3T,ÑQ Ñ5S3ÒT,ÒS3Ò0S3ÓT,ÓS3ÓS3Ó0T,Ó2S3Ó3T,Ó60T)Ô&T,Ô(T)Ô)T,zim.message.receive_v1rá  zim.message.message_read_v1rß  zim.chat.member.bot.added_v1rç  zim.chat.member.bot.deleted_v1ré  zcard.action.triggerrå  rÙ  rï  rÚ  rð  c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rø  r
   r6  rH   rG   rr   rI   )rJ   s   "rK   rL   rK  J  s!   € ÷ ñ °3ð ÀEð Èdñ rM   c                ó¾  a€ V3R lR	 4       w  r4pV'       d   V'       d	   V'       g   R#  VP                  RRR7      p\        P                  ! V V V P                   V 2P	                  4       4      P                  4       p\        P                  ! VP	                  4       VP	                  4       4      #   \         d    \        P                  RRR7        R# i ; i)
zXTiming-safe check of x-lark-signature == SHA256(timestamp + nonce + encrypt_key + body).c              3  ón   <"  € T F*  p\        SP                  VR 4      ;'       g    R 4      x € K,  	  R# 5ir›  )rb   rñ   )rÕ   rp   rø  s   & €rK   r×   Ú<FeishuAdapter._is_webhook_signature_valid.<locals>.<genexpr>L  s3   øé € ð '
á`�ô �—‘˜D "Ó%×+Ð+¨×,Ð,Û`ùs   ƒ"5¦5Frâ  r  )Úerrorsz3[Feishu] Signature verification raised an exceptionTr©  )zx-lark-request-timestampzx-lark-request-noncezx-lark-signature)r/  ÚhashlibÚsha256rÜ  r3  Ú	hexdigestr1  r2  r«  r¬  r®  )r|   rø  r6  r5  Únoncerj  Úbody_strÚcomputeds   &f&     rK   r4  Ú)FeishuAdapter._is_webhook_signature_validJ  s¼   ø€ ô'
á`ó'
Ñ#ˆ	˜)÷ §¯YÙð	Ø!×(Ñ(¨¸Ð(ÓCˆHÜ—~’~¨¨°E°7¸4×;LÑ;LÐ:MÈhÈZÐ&X×&_Ñ&_Ó&aÓb×lÑlÓnˆHä×&Ò& x§¡Ó'8¸)×:JÑ:JÓ:LÓMÐMøÜô 	Ü�L‰LÐNÐY]ˆLÔ^Úð	ús   ¬B	B6 Â6"CÃCc               ó    € V ^8„  d   QhRRRR/# )rC   Úrate_keyrb   rG   rr   rI   )rJ   s   "rK   rL   rK  [  s   € ÷ ñ °#ð ¸$ñ rM   c                óš  € \         P                   ! 4       pV P                  P                  V4      pVe=   Vw  rEW%,
          \        8  d(   V\        8¼  d   R# V^,           V3V P                  V&   R# \        V P                  4      \        8¼  d¥   V P                  P                  4        UUUu. uF  w  pw  rxW(,
          \        8¼  g   K  VNK  	  uppp F  pV P                  V K  	  WP                  9  d;   \        V P                  4      \        8¼  d   \        P                  R\        4       R# ^V3V P                  V&   R# u upppi )zdSliding-window limiter keyed by "{app_id}:{path}:{remote_ip}" (openclaw); table capped, fail-closed.FTuQ   [Feishu] Webhook rate-limit table at capacity (%d keys) â€” denying untracked key)
rp  rg  rñ   Ú#_FEISHU_WEBHOOK_RATE_WINDOW_SECONDSÚ_FEISHU_WEBHOOK_RATE_LIMIT_MAXrT   Ú_FEISHU_WEBHOOK_RATE_MAX_KEYSr  r¬  r¶  )	r|   rH  r   ro  r{  Úwindow_startrÛ   rÆ  rä  s	   &&       rK   r+  Ú'FeishuAdapter._check_webhook_rate_limit[  s  € ä�iŠi‹kˆØ×)Ñ)×-Ñ-¨hÓ7ˆØÒØ"'ÑˆEØÕ!Ô$GÔGØÔ:Ô:Ù Ø7<¸qµyÀ,Ð6O�×)Ñ)¨(Ñ3Ùäˆt×(Ñ(Ó)Ô-JÔJØ*.×*CÑ*C×*IÑ*IÔ*KÕÑ*K™J˜A™w ÈsÍxÔ[~ÑO~—a�aÑ*KÖ�Ø×-Ñ-¨aÒ0ñ @ð ×8Ñ8Ô8¼SÀ×AZÑAZÓ=[Ô_|Ô=|Ü—‘ØgÜ1ôñ Ø/0°#¨hˆ×!Ñ! (Ñ+Ùùô @s   Â-EÃ
Ec               ó$   € V ^8„  d   QhRRRRRR/# rÅ  rI   )rJ   s   "rK   rL   rK  w  s"   € ÷ 
ñ 
¨Lð 
ÀLð 
ÐUYñ 
rM   c                óà   € V P                   VP                   8H  ;'       dO    V P                  VP                  8H  ;'       d.    V P                  P                  VP                  P                  8H  # )z>Only merge text events when reply/thread context is identical.)r¦  r§  r3  r2  rÉ  s   &&rK   rÈ  Ú'FeishuAdapter._text_batch_is_compatiblev  se   € ð ×(Ñ(¨H×,HÑ,HÑH÷ Gð GØ×&Ñ&¨(×*@Ñ*@Ñ@÷Gð Gà—‘×)Ñ)¨X¯_©_×-FÑ-FÑFð	
rM   c               ó    € V ^8„  d   QhRRRR/# rK  rI   )rJ   s   "rK   rL   rK    s   € ÷ &-ñ &-¨|ð &-Àñ &-rM   c              ƒ  óÈ  a aa"  € S P                  S4      o\        SP                  ;'       g    R4      pR VVV 3R llpS P                  P	                  S4      pVf   VSn        V! 4        R# S P                  VS4      '       g#   S P                  S4      G Rj  x€L
  V! 4        R# S P                  P	                  S^4      ^,           pSP                  ;'       g    RpVP                  '       d   V'       d   VP                   RV 2MVP                  ;'       g    TpVS P                  8”  g   \        V4      S P                  8”  d#   S P                  S4      G Rj  x€L
  V! 4        R# Wtn        VP                  P                  SP                  4       VP                  P                  SP                  4       VP                  P                  SP                  4       W$n        SP                  Vn        SP                   '       d-   SP                   Vn        SP                   VP"                  n        VS P                  S&   S P%                  S4       R#  ELÁ Lü5i)z=Debounce rapid Feishu text bursts into a single MessageEvent.rd   c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   Ú7FeishuAdapter._enqueue_text_event.<locals>.__annotate__„  s   € ÷ 	1ñ 	1˜dñ 	1rM   c                 óf   <€ S SP                   S&   ^SP                  S&   SP                  S4       R# )r   N)rt  rv  Ú_schedule_text_batch_flush)r\  rî   r|   s   €€€rK   Ú_start_batchÚ7FeishuAdapter._enqueue_text_event.<locals>._start_batch„  s1   ø€ Ø.3ˆD×&Ñ& sÑ+Ø34ˆD×+Ñ+¨CÑ0Ø×+Ñ+¨CÖ0rM   Nr  )rÁ  rT   rŒ   rt  rñ   Ú_last_chunk_lenrÈ  Ú_flush_text_batch_nowrv  Ú_text_batch_max_messagesÚ_text_batch_max_charsr£  r  r¤  r¥  r5  r€  r3  rW  )	r|   r\  Ú	chunk_lenrX  r)  Ú
next_countÚappended_textÚ	next_textrî   s	   ff      @rK   r²  Ú!FeishuAdapter._enqueue_text_event  så  úé € à×"Ñ" 5Ó)ˆÜ˜Ÿ
™
×(Ð( bÓ)ˆ	÷	1ò 	1ð
 ×-Ñ-×1Ñ1°#Ó6ˆØÒØ$-ˆEÔ!ÙŒNÙØ×-Ñ-¨h¸×>Ò>Ø×,Ñ,¨SÓ1×1Ð1ÙŒNÙà×4Ñ4×8Ñ8¸¸aÓ@À1ÕDˆ
ØŸ
™
×(Ð( bˆØ;C¿=¿=¸=Ï]�x—}‘}�o R¨ Ñ7Ðai×anÑan×aÐaÐrˆ	Ø˜×5Ñ5Ô5¼¸Y»È$×JdÑJdÔ9dØ×,Ñ,¨SÓ1×1Ð1ÙŒNÙà!ŒØ×Ñ×"Ñ" 5×#3Ñ#3Ô4Ø×Ñ×#Ñ# E×$5Ñ$5Ô6Ø×#Ñ#×*Ñ*¨5×+CÑ+CÔDØ#,Ô Ø"Ÿ_™_ˆÔØ××ÐØ"'×"2Ñ"2ˆHÔØ).×)9Ñ)9ˆH�O‰OÔ&Ø/9ˆ×'Ñ'¨Ñ,Ø×'Ñ'¨Ö,ò- 2ñ 2ùsE   …BI"ÂI"ÂIÂAI"Ã I"Ã5I"Ã=#I"Ä!AI"Å#I Å$C:I"É I"c               ó    € V ^8„  d   QhRRRR/# rÓ  rI   )rJ   s   "rK   rL   rK  §  s   € ÷ añ a¨cð a°dñ arM   c                óR   € V P                  V P                  WP                  4       R# )z9Reset the debounce timer for a pending Feishu text batch.N)rÕ  ru  Ú_flush_text_batchr×  s   &&rK   rW  Ú(FeishuAdapter._schedule_text_batch_flush§  s   € à×#Ñ# D×$BÑ$BÀC×I_ÑI_Ö`rM   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	rC   rß  rÄ   rî   rb   Úflush_fnr
   rG   rI  rI   )rJ   s   "rK   rL   rK  ¬  s+   € ÷ ;ñ ;Ð)@ð ;Àsð ;ÐVYð ;Ð^bñ ;rM   c                	óÀ   € V P                  V4      pV'       d'   VP                  4       '       g   VP                  4        \        P                  ! V! V4      4      W&   R # r{   )rñ   rí  rî  rQ   Úcreate_task)rß  rî   rh  Ú
prior_tasks   &&& rK   rÕ  Ú$FeishuAdapter._reschedule_batch_task«  sA   € à—\‘\ #Ó&ˆ
ß˜jŸo™o×/Ò/Ø×ÑÔÜ×+Ò+©H°S«MÓ:ˆ‹rM   c               ó    € V ^8„  d   QhRRRR/# )rC   rî   rb   rG   zOptional[MessageEvent]rI   )rJ   s   "rK   rL   rK  ²  s   € ÷ 9ñ 9 3ð 9Ð+Añ 9rM   c                	ór   € V P                   P                  VR 4       V P                  P                  VR 4      # r{   )rv  r]  rt  r×  s   &&rK   Ú_pop_text_batchÚFeishuAdapter._pop_text_batch²  s1   € Ø×'Ñ'×+Ñ+¨C°Ô6Ø×)Ñ)×-Ñ-¨c°4Ó8Ð8rM   c               ó    € V ^8„  d   QhRRRR/# rK  rI   )rJ   s   "rK   rL   rK  ¶  s   € ÷ 6ñ 6°ð 6Àñ 6rM   c              ƒ  	óD   "  € V P                  V4      G R j  x€L
  R #  L5ir{   )r:  rµ  s   &&rK   Ú_dispatch_text_batchÚ"FeishuAdapter._dispatch_text_batch¶  s   é € Ø×.Ñ.¨uÓ5×5Ô5ùs   ‚ —˜ c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   rÆ  r
   rÇ  r�   rG   rŠ   rI   )rJ   s   "rK   rL   rK  º  s)   € ÷ 
ñ 
 sð 
¸ð 
Èð 
ÐPgñ 
rM   c                	ó8   € \        WW0P                  4       R 7      # ))rÆ  rÇ  r�   rÌ   )rÞ  Ú_bot_identity)r|   rÆ  rÇ  r�   s   &&&&rK   Ú
_normalizeÚFeishuAdapter._normalizeº  s   € Ü'Ø%È×WiÑWiÓWkô
ð 	
rM   c               ó    € V ^8„  d   QhRRRR/# )rC   r1   r
   rG   zQtuple[str, MessageType, list[str], list[str], list[bool], list[FeishuMentionRef]]rI   )rJ   s   "rK   rL   rK  ¿  s    € ÷ jñ jØðjà	ZñjrM   c           	   ƒ  	óØ  "  € \        VR R4      ;'       g    Rp\        VRR4      ;'       g    Rp\        \        VRR4      ;'       g    R4      p\        P                  RW44       V P	                  W2\        VRR4      4      pV P                  WER7      G Rj  x€L
 w  rgV P                  WW4      pVP                  p	. p
. p\        Wg4       FS  w  rÍV P                  WÍ4      G Rj  x€L
 pV
P                  \        V4      4       V'       g   KB  VP                  V4       KU  	  V'       d#   RP                  V4      pV	'       d   V	 RV 2MTp	W˜WgV
\        VP                  4      3#  LÌ L‚5i)	rO   rd   rÆ  r€  z3[Feishu] Received raw message type=%s message_id=%sr�   N)r€  r  r�  )rÎ   rb   r¬  r$  rx  Ú"_download_feishu_message_resourcesÚ _resolve_normalized_message_typer�   ÚzipÚ_maybe_extract_text_documentrM  rr   rL  rˆ   r�   )r|   r1   rÇ  r‹   r€  r  r£  r¤  r«  rŒ   r¥  Úinlined_partsÚ	media_urlÚ
media_typeÚ	extractedÚextracted_texts   &&              rK   r¨  Ú&FeishuAdapter._extract_message_content¿  s[  é € ô ˜g y°"Ó5×;Ð;¸ˆÜ˜7 N°BÓ7×=Ð=¸2ˆÜœ ¨,¸Ó;×AÐA¸rÓBˆ
Ü�‰ÐIÈ8Ô`Ø—_‘_ X¼GÀGÈZÐY]Ó<^Ó_ˆ
Ø(,×(OÑ(OØ!ð )Pó )
÷ #
Ñˆ
ð ×<Ñ<¸ZÓUˆØ×&Ñ&ˆØ)+ÐØ#%ˆÜ%(¨Ö%AÑ!ˆIØ"×?Ñ?À	ÓV×VˆIØ×%Ñ%¤d¨9£oÔ6ß‰yØ×$Ñ$ YÖ/ñ	 &B÷
 Ø#Ÿ[™[¨Ó7ˆNß48�d�V˜4 Ð/Ñ0¸nˆDØ :Ð<NÔPTÐU_×UhÑUhÓPiÐiÐiñ#
ñ WùsB   ‚+E*®E*Á
AE*ÂE&ÂAE*Ã%E(Ã&#E*ÄE*Ä+E*Å#E*Å(E*c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r€  rb   r  rŠ   rG   ztuple[list[str], list[str]]rI   )rJ   s   "rK   rL   rK  Ø  s$   € ÷ 'ñ 'Ø ð'Ø.Eð'à	$ñ'rM   c          
   ƒ  	ó>  aa"  € . o. oR  VV3R llpVP                    F!  pT! V P                  WR7      G Rj  x€L
 !   K#  	  VP                   FA  pT! V P                  WP                  VP
                  VP                  R7      G Rj  x€L
 !   KC  	  SS3#  L_ L5i)c               ó$   € V ^8„  d   QhRRRRRR/# )rC   Úcached_pathrb   r‚  rG   rI  rI   )rJ   s   "rK   rL   ÚFFeishuAdapter._download_feishu_message_resources.<locals>.__annotate__Þ  s!   € ÷ 	/ñ 	/ #ð 	/°3ð 	/¸4ñ 	/rM   c                ó`   <€ V '       d%   SP                  V 4       SP                  V4       R # R # r{   r=  )r‰  r‚  r¤  r£  s   &&€€rK   Ú_collectÚBFeishuAdapter._download_feishu_message_resources.<locals>._collectÞ  s'   ø€ ßØ×!Ñ! +Ô.Ø×"Ñ" :Ö.ñ rM   )r€  r—  N)r€  rc   rg   Úfallback_filename)r…   Ú_download_feishu_imager‡   Ú!_download_feishu_message_resourcerc   rg   re   )r|   r€  r  rŒ  r—  r¡  r¤  r£  s   &$$   @@rK   r|  Ú0FeishuAdapter._download_feishu_message_resourcesØ  s¥   ùé € ð !#ˆ
Ø!#ˆ÷	/ñ 	/ð
 $×.Ô.ˆIÙ˜D×7Ñ7À:Ð7Óc×cÔdñ /à×(Ô(ˆCÙ˜D×BÑBØ%·±ÈC×L]ÑL]Ø"%§-¡-ð Có ÷ ô ñ )ð
 ˜;Ð&Ð&ñ dñùs"   „5B¹B
ºABÂ
B
ÂBÂBc               ó$   € V ^8„  d   QhRRRRRR/# )rC   r‚  rb   r,  r#   rG   rI   )rJ   s   "rK   rL   rK  í  s"   € ÷ ñ °ð Àð ÐQ\ñ rM   c               	ó$  € T ;'       g    R P                  4       pVP                  R4      '       d   \        P                  # VP                  R4      '       d   \        P                  # VP                  R4      '       d   \        P
                  # V# )rd   úimage/úaudio/úvideo/)r±  rû   r#   r¹  r¼  rº  )r‚  r,  r  s   &$ rK   Ú_resolve_media_message_typeÚ)FeishuAdapter._resolve_media_message_typeì  st   € à ×&Ð& B×-Ñ-Ó/ˆ
Ø× Ñ  ×*Ò*Ü×$Ñ$Ð$Ø× Ñ  ×*Ò*Ü×$Ñ$Ð$Ø× Ñ  ×*Ò*Ü×$Ñ$Ð$ØˆrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r  rŠ   r¤  r„   rG   r#   rI   )rJ   s   "rK   rL   rK  ÷  s$   € ÷  ñ  Ð;Rð  Ðajð  Ðozñ  rM   c                	ó  € VP                   pVR 8X  d   \        P                  # VR9   dR   VR8X  d   \        P                  M\        P                  pT P                  V'       d   V^ ,          VR7      # RVR7      # \        P                  # )rª  rÊ  rd   r¿  )rÊ  rË  )r�   r#   ÚVOICEr¹  r»  r—  r  )r|   r  r¤  r„  r,  s   &&&  rK   r}  Ú.FeishuAdapter._resolve_normalized_message_type÷  s~   € Ø×5Ñ5ˆ	Ø˜Ôô ×$Ñ$Ð$ØÐ-Ô-Ø+4¸Ô+?”k×'Ò'Ä[×EYÑEYˆGØ×3Ñ3Çk°KÀµNÐcjÐ3ÓkÐkÐWYÐcjÐ3ÓkÐkÜ×ÑÐrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r‰  rb   r‚  rG   rI   )rJ   s   "rK   rL   rK    s"   € ÷ ñ ¸cð Èsð ÐWZñ rM   c              ƒ  	óÐ  "  € V'       d   VP                  R 4      '       g   R#  \        P                  P                  V4      \        8”  d   R# \        V4      P                  P                  4       pVR	9  d
   VR
9  d   R# \        V4      P                  RR7      pV P                  V4      pRV RV 2#   \        \        3 d    \        P                  RTRR7        R# i ; i5i)ztext/rd   ú	utf-8-sigrã  z[Content of z]:
z7[Feishu] Failed to inject text document content from %sTr©  >   ú.mdú.txt>   ú
text/plainútext/markdown)rû   rö  r  ÚgetsizeÚ_MAX_TEXT_INJECT_BYTESr   r  r±  Ú	read_textÚ_display_name_from_cached_pathrø  r0  r¬  r¶  )r|   r‰  r‚  rú  rO   r¸  s   &&&   rK   r  Ú*FeishuAdapter._maybe_extract_text_document  sÌ   é € ß *×"7Ñ"7¸×"@Ò"@Ùð	Ü�w‰w�‰˜{Ó+Ô.DÔDÙÜ�{Ó#×*Ñ*×0Ñ0Ó2ˆCØ˜/Ô)¨jÐ@_Ô._ÙÜ˜;Ó'×1Ñ1¸;Ð1ÓGˆGØ×>Ñ>¸{ÓKˆLØ! , ¨t°G°9Ð=Ð=øÜÔ+Ð,ô 	Ü�N‰NÐTÐVaÐlpˆNÔqÚð	üsE   ‚C&¢C&¥(B6 ÁC&Á1B6 Â C&Â3B6 Â5C&Â6)C#ÃC&Ã"C#Ã#C&c               ó(   € V ^8„  d   QhRRRRRRRR/# ©rC   r€  rb   rc   rg   rG   r
   rI   )rJ   s   "rK   rL   rK    s0   € ÷ Zñ Z¸3ð ZÈ#ð ZÐ^að ZÐfiñ ZrM   c             ƒ  óÌ   "  € V P                  WVR7      pV P                  V P                  P                  P                  P
                  P                  V4      G Rj  x€L
 #  L5i)zZGET im/v1/messages/{id}/resources/{key}; returns the SDK response (caller checks success).©r€  rc   rg   N)Ú_build_message_resource_requestr  rT  rŠ  r‹  Úmessage_resourcerñ   )r|   r€  rc   rg   rD   s   &$$$ rK   Ú_fetch_message_resourceÚ%FeishuAdapter._fetch_message_resource  sU   é € à×6Ñ6Ø!ÀMð 7ó 
ˆð ×'Ñ'¨¯©¯©×(:Ñ(:×(KÑ(K×(OÑ(OÐQXÓY×YÐYÑYùs   ‚AA$ÁA"ÁA$c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r€  rb   r—  rG   r[  rI   )rJ   s   "rK   rL   rK    s"   € ÷ ñ ¸#ð È#ð ÐRañ rM   c          
   ƒ  	óž  "  € V P                   '       d	   V'       g   R#  V P                  WRR7      G Rj  x€L
 pV'       d   VP                  4       '       g1   \        P	                  RV\        VRR4      \        VRR4      4       R# V P                  V4      pV'       g   R# V P                  VR	4      p\        VR
R4      ;'       g    V R2pV P                  WeR\        R7      p\        WGR7      G Rj  x€L
 pW€P                  WPP                  V4      R7      3#  Lç L(  \         d    \        P	                  RTRR7       Ru # i ; i5i)rd   r©  r¬  Nz+[Feishu] Failed to download image %s: %s %sr  ri  rn  úrequest failedrù  re   rê  ©Úallowedrë  r¿  z*[Feishu] Failed to cache image resource %sTr©  r_  )rT  r¯  rd  r¬  r¶  rÎ   Ú_read_binary_responseÚ_get_response_headerÚ_guess_extensionr  r!   Ú_normalize_media_typeÚ_default_image_media_typer«  )	r|   r€  r—  r{  Ú	raw_bytesrú  r   rú  r‰  s	   &$$      rK   r�  Ú$FeishuAdapter._download_feishu_image  s7  é € Ø�|�|ˆ|§:ØˆMð	Ø!×9Ñ9ÀZÐszÐ9Ó{×{ˆHß 8×#3Ñ#3×#5Ò#5Ü—‘ØAØœw x°¸ÓCÄWÈXÐW\Ð^nÓEoôð �Ø×2Ñ2°8Ó<ˆIßØ�Ø×4Ñ4°X¸~ÓNˆLÜ˜x¨°dÓ;×QÐQÀ)ÀÈDÐ?QˆHØ×'Ñ'¨ÀÔPaÐ'ÓbˆCÜ <¸YÔ P×PˆKØ× :Ñ :¸<×QoÑQoÐpsÓQtÐ :Ó uÐuÐuñ |ñ Qøäô 	Ü�N‰NÐGÈÐ]aˆNÔbØŠMð	üs   ‚E�E D" ¶D·D" ÁD" Á/D" ÂEÂ	D" Â"D" Â#EÂ$%D" Ã
-D" Ã7D Ã8%D" ÄEÄD" Ä D" Ä"%E
ÅEÅ	E
Å
Ec          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )rC   r€  rb   rc   rg   rŽ  rG   r[  rI   )rJ   s   "rK   rL   rK  5  s4   € ÷ 1ñ 1Ø ð1Ø,/ð1Ø@Cð1ØX[ð1à	ñ1rM   c             ƒ  	ó  "  € V P                   '       d	   V'       g   R# V.VR 9   d   R.M. ,           pV EFŒ  p V P                  WVR7      G Rj  x€L
 pV'       d   VP                  4       '       g2   \        P	                  RWV\        VRR4      \        VRR	4      4       Ko  V P                  V4      pV'       g   KŠ  V P                  VR
4      p	\        VRR4      ;'       g    R ;'       g    T;'       g    V RV 2p
V P                  W�P                  V
4      R7      pVP                  R4      '       dK   V P                  W©R\        R7      pR\        WŒR7      G Rj  x€L
 ríT;'       g    V P                  V4      pEM&VR8X  g   VP                  R4      '       dW   V P                  W©R\        R7      pR\!        WŒR7      G Rj  x€L
 ríT;'       g    RVP#                  R4      ;'       g    R 2pM²VP                  R4      '       d6   \%        V
4      P&                  '       g   V
 R2p
R\)        WŠ4      G Rj  x€L
 ríMf\%        V
4      P&                  '       g   V\*        9   d   V
 \*        V,           2p
R\)        WŠ4      G Rj  x€L
 ríT;'       g    V P-                  V
4      p\        P/                  RWÞ4       Wë3u # 	  R#  ELx ELj EL L“ LI  \0         d    \        P3                  RYRR7        EKÇ  i ; i5i)!rd   rª  rf   r¬  Nz>[Feishu] Resource download failed for %s/%s via type=%s: %s %sr  ri  rn  r³  rù  re   rÆ  r¿  r”  rê  r´  r©  rë  r•  r/   r  Úoggr–  ú.mp4r¬  rË  z)[Feishu] Cached message %s resource at %sz/[Feishu] Failed to cache message resource %s/%sTr©  r_  >   rª  r«  )rT  r¯  rd  r¬  r®  rÎ   r¶  r·  r¹  Ú_guess_media_type_from_filenamerû   r¸  r  r!   rº  r  r    rn  r   r  r   Ú_DOCUMENT_MIME_TO_EXTÚ_guess_document_media_typer$  r«  r¶  )r|   r€  rc   rg   rŽ  Úrequest_typesÚrequest_typer{  r»  rú  r   r‚  rú  Úkindr‰  s   &$$$$          rK   r�  Ú/FeishuAdapter._download_feishu_message_resource5  sÝ  é € ð �|�|ˆ|§:ØˆMà&˜°}ÐHZÔ7Z¨F©8Ð`bÕcˆÜ)ˆLð(wØ!%×!=Ñ!=Ø)ÈLð ">ó "÷ �÷   x×'7Ñ'7×'9Ò'9Ü—L‘LØXØ"¨lÜ ¨&°)Ó<¼gÀhÐPUÐWgÓ>hôñ
 Ø ×6Ñ6°xÓ@�	ß ÙØ#×8Ñ8¸À>ÓR�Ü# H¨k¸4Ó@×|ÐFÀB×|Ð|ÐK\×|Ð|ÐcoÐbpÐpqÐrzÐq{Ð`|�Ø!×7Ñ7Ø ×*NÑ*NÈxÓ*Xð 8ó �
ð ×(Ñ(¨×2Ò2Ø×/Ñ/°ÈÔXiÐ/Ój�CØ(/Ô7SÐT]Ô7g×1g˜+Ø!+×!RÐ!R¨t×/MÑ/MÈcÓ/R’JØ! WÔ,°
×0EÑ0EÀh×0OÒ0OØ×/Ñ/°ÈÔXiÐ/Ój�CØ(/Ô7SÐT]Ô7g×1g˜+Ø!+×!RÐ!R°¸¿
¹
À3»×8PÐ8PÈ5Ð7QÐ/R‘JØ×*Ñ*¨8×4Ò4Ü ›>×0×0Ð0Ø&. Z¨tÐ#4˜Ø(/Ô7VÐW`Ó7k×1k™+ä ›>×0×0Ð0°ZÔCXÔ5XØ&. ZÔ0EÀjÕ0QÐ/RÐ#S˜Ø(2Ô:YÐZcÓ:n×4n˜+Ø!+×!XÐ!X¨t×/NÑ/NÈxÓ/X�JÜ—‘ÐGÈÔ[Ø"Ð.Ò.ñO *ðT ˆòQò* 2hò 2hñ
 2lñ 5oøô ô wÜ—‘ÐPÐR\Ðqu�×vÐvðwüsÑ   ‚L �L ºKÁKÁKÁKÁ3/KÂ"L Â$KÂ=L Â?KÃ%	KÃ/	KÃ9A(KÅ!KÅ">KÆ!(KÇ	KÇ
&KÇ1KÈ/KÈ=KÈ>AKÊ	KÊ
7KËL ËKËKËKËKËKË#K=Ë8L Ë<K=Ë=L c               ó    € V ^8„  d   QhRRRR/# )rC   r{  r
   rG   rH   rI   )rJ   s   "rK   rL   rK  j  s   € ÷ &ñ &¨ð &°ñ &rM   c                	ó°   € \        V R R4      pVf   R# \        VR4      '       d   \        VP                  4       4      # \        VP	                  4       4      # )rf   NrM   Úgetvalue)rÎ   rC  rH   rÊ  Úread)r{  Úfile_objs   & rK   r¶  Ú#FeishuAdapter._read_binary_responsei  sK   € ä˜8 V¨TÓ2ˆØÒÙÜ�8˜Z×(Ò(Ü˜×*Ñ*Ó,Ó-Ð-Ü�X—]‘]“_Ó%Ð%rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r{  r
   rp   rb   rG   rI   )rJ   s   "rK   rL   rK  s  s&   € ÷ lñ l sð l°#ð l¸#ñ lrM   c           	     	ó4  € \        V R R4      p\        VR/ 4      ;'       g    / p\        VP                  WP                  VP                  4       R4      4      ;'       g    R4      P	                  R^4      ^ ,          P                  4       P                  4       # )rß  Nrø  rd   r  )rÎ   rb   rñ   r±  rQ  r  )r{  rp   rß  rø  s   &&  rK   r·  Ú"FeishuAdapter._get_response_headerr  sz   € ä�h  tÓ,ˆÜ˜#˜y¨"Ó-×3Ð3°ˆÜ�7—;‘;˜t§[¡[°·±³¸rÓ%BÓC×IÐIÀrÓJ×PÑPÐQTÐVWÓXÐYZÕ[×aÑaÓc×iÑiÓkÐkrM   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )rC   r   rb   rú  r,  rµ  r½   rG   rI   )rJ   s   "rK   rL   rK  y  s1   € ÷ :ñ : 3ð :°cð :ÀCð :ÐU]ð :Ðbeñ :rM   c               	ó:  € \        T ;'       g    R 4      P                  P                  4       pWC9   d   V# \        P                  ! T;'       g    R P                  R^4      ^ ,          P                  4       P                  4       ;'       g    R 4      pWS9   d   V# T# ©rd   r  )r   r  r±  r  r  rQ  r  )r   rú  r,  rµ  rú  r  s   &&&$  rK   r¸  ÚFeishuAdapter._guess_extensionx  s€   € ä�8—>�>˜rÓ"×)Ñ)×/Ñ/Ó1ˆØŒ>ØˆJÜ×+Ò+¨\×-?Ð-?¸R×,FÑ,FÀsÈAÓ,NÈqÕ,Q×,WÑ,WÓ,Y×,_Ñ,_Ó,a×,gÐ,gÐegÓhˆØ!Ô,ˆwÐ9°'Ð9rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rú  rb   r,  rG   rI   )rJ   s   "rK   rL   rK  �  s!   € ÷ %ñ %¨Cð %¸Sð %ÀSñ %rM   c               	ó˜   € T ;'       g    R P                  R^4      ^ ,          P                  4       P                  4       pT;'       g    T# rÓ  )rQ  r  r±  )rú  r,  r  s   &$ rK   r¹  Ú#FeishuAdapter._normalize_media_type€  sA   € à"×(Ð( b×/Ñ/°°QÓ7¸Õ:×@Ñ@ÓB×HÑHÓJˆ
Ø×$Ð$˜WÐ$rM   c               ó    € V ^8„  d   QhRRRR/# ©rC   r   rb   rG   rI   )rJ   s   "rK   rL   rK  †  s   € ÷ xñ x¨Sð x°Sñ xrM   c                	óè   € \        T ;'       g    R 4      P                  P                  4       p\        P                  ! T\
        P                  ! T ;'       g    R 4      ^ ,          ;'       g    R4      # )rd   zapplication/octet-stream)r   r  r±  r   rñ   r  Ú
guess_type)r   rú  s   & rK   rÃ  Ú(FeishuAdapter._guess_document_media_type…  sU   € ä�8—>�>˜rÓ"×)Ñ)×/Ñ/Ó1ˆÜ'×+Ò+¨C´×1EÒ1EÀhÇnÀnÐRTÓ1UÐVWÕ1X×1vÐ1vÐ\vÓwÐwrM   c               ó    € V ^8„  d   QhRRRR/# )rC   r  rb   rG   rI   )rJ   s   "rK   rL   rK  ‹  s   € ÷ 7ñ 7¨Sð 7°Sñ 7rM   c                	óÊ   € \         P                  P                  V 4      pVP                  R ^4      p\	        V4      ^8¼  d
   V^,          MTp\
        P                  ! RR V4      # )rÆ  z	[^\w.\- ])rö  r  r  rQ  rT   rù   rå   )r  r  rl  r¸  s   &   rK   r§  Ú,FeishuAdapter._display_name_from_cached_pathŠ  sN   € ä—7‘7×#Ñ# DÓ)ˆØ—‘˜s AÓ&ˆÜ#& u£:°¤?�u˜Q–x¸ˆÜ�vŠv�l C¨Ó6Ð6rM   c               ó    € V ^8„  d   QhRRRR/# rÙ  rI   )rJ   s   "rK   rL   rK  ’  s   € ÷ ñ °#ð ¸#ñ rM   c                	ó®  € \         P                  ! T ;'       g    R 4      ^ ,          ;'       g    R P                  4       pV'       d   V# \        T ;'       g    R 4      P                  P                  4       pV\
        9   d   RVP                  R4       2# V\        9   d   RVP                  R4       2# V\        9   d   \        P                  V4      # R # )rd   r–  r  r•  )r  rÛ  r±  r   r  r  rn  r  r  rE  rº  )r   r  rú  s   &  rK   rÁ  Ú-FeishuAdapter._guess_media_type_from_filename‘  s°   € ä×'Ò'¨¯¨°BÓ7¸Õ:×@Ð@¸b×GÑGÓIˆßØˆNÜ�8—>�>˜rÓ"×)Ñ)×/Ñ/Ó1ˆØÔ#Ô#Ø˜CŸJ™J s›OÐ,Ð-Ð-ØÔ#Ô#Ø˜CŸJ™J s›OÐ,Ð-Ð-ØÔ#Ô#Ü ×:Ñ:¸3Ó?Ð?ÙrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rH  rb   rG   rI   )rJ   s   "rK   rL   rK     s   € ÷ :ñ : cð :¨cñ :rM   c                	ó   a€ T ;'       g    R P                  4       P                  4       oSR8X  d   R# \        ;QJ d    V3R lR 4       F  '       g   K   RM	  RM! V3R lR 4       4      '       d   R# SR8X  d   R# R# )	rd   r{  r>  c              3  ó,   <"  € T F	  qS9   x € K  	  R # 5ir{   rI   )rÕ   Úmarkerr  s   & €rK   r×   Ú/FeishuAdapter._map_chat_type.<locals>.<genexpr>¤  s   øé € ÐOÑ2N¨˜Ö#Ó2Nùs   ƒÚforumTFr"  )ÚtopicÚthreadrè  )r  r±  r´  )rH  r  s   &@rK   rF  ÚFeishuAdapter._map_chat_typeŸ  se   ø€ à#×)Ð) r×0Ñ0Ó2×8Ñ8Ó:ˆ
Ø˜ÔÙß‹3ÔOÑ2NÓO�3�3Š3ÔOÑ2NÓO×OÒOÙØ$¨Ô/ˆwÐ9°TÐ9rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r0  r’   r  rb   rG   rI   )rJ   s   "rK   rL   rK  ©  s#   € ÷ =ñ =°ð =ÐQTð =ÐY\ñ =rM   c                	óª   € \        V P                  R 4      ;'       g    R4      P                  4       P                  4       pVR9   d   V# VR8X  d   R# R# )r   rd   r"  r{  r>  >   rè  r"  )rb   rñ   r  r±  )r0  r  rk  s   $$ rK   r8  Ú'FeishuAdapter._resolve_source_chat_type¨  sO   € ä�y—}‘} VÓ,×2Ð2°Ó3×9Ñ9Ó;×AÑAÓCˆØÐ)Ô)ØˆOØ&¨%Ô/ˆtÐ<°WÐ<rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rÒ   r
   r|  rr   rG   zdict[str, Optional[str]]rI   )rJ   s   "rK   rL   rK  ¯  s'   € ÷ 	[ñ 	[°sð 	[Àtð 	[ÐXpñ 	[rM   c             ƒ  ó   "  € \        VRR4      ;'       g    Rp\        VRR4      ;'       g    Rp\        VRR4      ;'       g    RpT;'       g    TpV'       d   TMT;'       g    TpV P                  WrR7      G Rj  x€L
 pRVRVRV/#  L5i)u´   Map Feishu's ID tiers onto SessionSource: user_id (tenant) > open_id (app) as primary,
union_id (developer-scoped, cross-app stable) as user_id_alt â€” session keys prefer the alt.rq   Nrw   rß   r¢  r•  r1  )rÎ   Ú_resolve_sender_name_from_api)	r|   rÒ   r|  rq   rw   rß   Ú
primary_idÚname_lookup_idr¸  s	   &&$      rK   r6  Ú%FeishuAdapter._resolve_sender_profile¯  s—   é € ô ˜) Y°Ó5×=Ð=¸ˆÜ˜) Y°Ó5×=Ð=¸ˆÜ˜9 j°$Ó7×?Ð?¸4ˆØ×'Ð' ˆ
ß$*™°×1GÐ1G¸xˆØ!×?Ñ?ÀÐ?Ó^×^ˆØ˜: {°LÀ-ÐQYÐZÐZñ _ùs.   ‚+B®BÁBÁ
BÁ
BÁ'BÁ?BÂ Bc               ó    € V ^8„  d   QhRRRR/# )rC   rÒ   r_  rG   rI   )rJ   s   "rK   rL   rK  º  s   € ÷ 	ñ 	°ð 	À=ñ 	rM   c                óÔ   € V'       d   V P                   P                  V4      MRpVf   R# Vw  r4\        P                  ! 4       V8  d   V# V P                   P                  VR4       R# )z>Return a cached sender name only while its TTL is still valid.N)rf  rñ   rp  r]  )r|   rÒ   rG  rp   Ú	expire_ats   &&   rK   rë  Ú%FeishuAdapter._get_cached_sender_nameº  sW   € ç;D�×(Ñ(×,Ñ,¨YÔ7È$ˆØŠ>ÙØ ‰ˆÜ�9Š9‹;˜Ô"ØˆKØ×Ñ×#Ñ# I¨tÔ4ÙrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rÒ   r_  r|  rr   rG   rI   )rJ   s   "rK   rL   rK  Å  s#   € ÷ !ñ !¸]ð !ÐW[ð !Ðhuñ !rM   c             ƒ  ód  a"  € V'       d#   V P                   '       d   VP                  4       MRpV'       g   R# \        P                  ! 4       pV P                  V4      pVe   T;'       g    R# V'       d�   V P	                  V.4      G Rj  x€L
 pVf   R# VP                  4        F   w  rxW„\        ,           3V P                  V&   K"  	  V P                  P                  V4      p	V	'       d   V	^ ,          ;'       g    R# R#  ^ RI	H
p
 VP                  R4      '       d   RMVP                  R4      '       d   RMRpV
P                  4       P                  V4      P                  V4      P                  4       pV P!                  V P                   P"                  P$                  P&                  P                  V4      G Rj  x€L
 pV'       d   VP)                  4       '       g   R# \+        \+        VR	R4      R
R4      oV3R lR 4       p\-        R V 4       R4      pV'       dZ   \/        V\0        4      '       dD   VP                  4       '       d.   VP                  4       pW„\        ,           3V P                  V&   V# R#  ELô LÁ  \2         d    \4        P7                  RTRR7        R# i ; i5i)um   Bots go via bot/basic_batch (contact API has no bot names). Failures are silent â€” never block the pipeline.rd   N)ÚGetUserRequestÚou_rq   Úon_rß   rw   rB  r”  c              3  ó>   <"  € T F  p\        SVR 4      x € K  	  R # 5ir{   rÍ   )rÕ   rÛ   r”  s   & €rK   r×   Ú>FeishuAdapter._resolve_sender_name_from_api.<locals>.<genexpr>Þ  s   øé € ÐjÑ:i°Qœ' $¨¨4×0Ð0Ó:iùrÝ   c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir{   rI   )rÕ   rè   s   & rK   r×   rÿ  ß  s   é € Ð@©J 5»%Ÿš«JùrÙ   z-[Feishu] Failed to resolve sender name for %sTr©  )rp   r¸  ÚnicknameÚen_name)rT  r  rp  rë  Ú_fetch_bot_namesr  Ú_FEISHU_SENDER_NAME_TTL_SECONDSrf  rñ   Úlark_oapi.api.contact.v3rû  rû   r  rw   Úuser_id_typer"  r  ÚcontactÚv3r”  rd  rÎ   r³  r  rb   r«  r¬  r®  )r|   rÒ   r|  Útrimmedr   Úcached_namer¹  Úoidrp   Úhitrû  r^  rD   r{  r  r”  s   &&$            @rK   rñ  Ú+FeishuAdapter._resolve_sender_name_from_apiÅ  s"  øé € ç'0°T·\·\°\�)—/‘/Ô#ÀrˆßÙÜ�iŠi‹kˆØ×2Ñ2°7Ó;ˆØÒ"Ø×&Ð& $Ð&ßØ×/Ñ/°°	Ó:×:ˆEØŠ}ÙØ"Ÿ[™[ž]‘	�Ø04Ô<[Õ6[Ð/\�×'Ñ'¨Ó,ñ +à×)Ñ)×-Ñ-¨gÓ6ˆCß'*�C˜•F—N�N˜dÐ4°Ð4ð	dÝ?Ø#*×#5Ñ#5°e×#<Ò#<‘iÐPW×PbÑPbÐch×PiÒPiÁ*ÐoxˆGØ$×,Ñ,Ó.×6Ñ6°wÓ?×LÑLÈWÓU×[Ñ[Ó]ˆGØ!×/Ñ/°·±×0DÑ0D×0GÑ0G×0LÑ0L×0PÑ0PÐRYÓZ×ZˆHß 8×#3Ñ#3×#5Ò#5ÙÜœ7 8¨V°TÓ:¸FÀDÓIˆDÜjÑ:iÓjˆJÜÑ@©JÓ@À$ÓGˆDßœ
 4¬×-Ò-°$·*±*·,²,Ø—z‘z“|�Ø48Ô@_Õ:_Ð3`�×'Ñ'¨Ñ0Ø�ñ ò/ ;ñ [øô ô 	dÜ�L‰LÐHÈ)Ð^bˆLÕcÙð	düs�   ƒJ0žJ0¸4J0Á-
J0Á8J0ÂJÂA J0Ã/J0Ã?J0ÄJ Ä"J Ä;BJ ÇJÇJ ÇJ Ç%J0Ç'A*J É,J É>J0ÊJ Ê#J-Ê)J0Ê,J-Ê-J0r  c               ó$   € V ^8„  d   QhRRRRRR/# r  rI   )rJ   s   "rK   rL   rK  è  s(   € ÷ Dñ D¨ð DÐ:Yð DÐehñ DrM   c             ƒ  ó®   "  € V P                  V P                  P                  \        WR7      4      G Rj  x€L
 p\	        \	        VRR4      RR4      #  L5i)zWGET ``uri`` with the tenant token via the raw client; returns the raw response content.©r  Nrß  rO   )r  rT  rD   r#  rÎ   )r|   r  r  Úresps   &&$ rK   Ú_tenant_get_rawÚFeishuAdapter._tenant_get_rawè  sI   é € à×'Ñ'¨¯©×(<Ñ(<Ô>QÐRUÔ>gÓh×hˆÜ”w˜t U¨DÓ1°9¸dÓCÐCñ iùs   ‚4A¶A·Ac               ó    € V ^8„  d   QhRRRR/# )rC   Úbot_idsr„   rG   r   rI   )rJ   s   "rK   rL   rK  í  s   € ÷ ñ ¨ið Ð<Tñ rM   c           
   ƒ  	ó¢  "  € V P                   '       d	   V'       g   R #  T P                  RV Uu. uF  pRV3NK	  	  upR7      G R j  x€L
 pV'       g   R # \        P                  ! V4      pVP	                  R4      ^ 8w  d   R # VP	                  R4      ;'       g    / P	                  R4      ;'       g    / pVP                  4        UUu/ uFB  w  r&V'       g   K  T\        VP	                  R4      ;'       g    R4      P                  4       bKD  	  upp# u upi  LÔu uppi   \         d    \        P                  R	TR
R7        R # i ; i5i)Nz"/open-apis/bot/v3/bots/basic_batchr  r  r  rB  Úbotsrp   rd   z)[Feishu] Failed to fetch bot names for %sTr©  )rT  r  r?  rá  rñ   r  rb   r  r«  r¬  r®  )r|   r  r  rO   r\  r  r$  s   &&     rK   r  ÚFeishuAdapter._fetch_bot_namesí  s  é € Ø�|�|ˆ|§7Ùð	Ø ×0Ñ0Ø4Ñ[bÓ>cÑ[bÐTWÀ	È3Ó?OÑ[bÑ>cð 1ó ÷ ˆG÷ ÙÜ—j’j Ó)ˆGØ�{‰{˜6Ó" aÔ'ÙØ—K‘K Ó'×-Ð-¨2×2Ñ2°6Ó:×@Ð@¸bˆDØNRÏjÉjÌlÔbÉlÁÀÔ^aÔ<�Cœ˜TŸX™X fÓ-×3Ð3°Ó4×:Ñ:Ó<Ò<ÉlÒbÐbùò ?dñùó cøÜô 	Ü�L‰LÐDÀgÐX\ˆLÔ]Úð	üs‹   ‚E�E D% °D
½D% ÁDÁ	D% ÁEÁ,D% ÂEÂD% ÂD% Â6D% ÃDÃDÃ;DÄD% ÄEÄD% ÄD% Ä%#EÅEÅEÅEc               ó    € V ^8„  d   QhRRRR/# )rC   r€  rb   rG   r_  rI   )rJ   s   "rK   rL   rK  ÿ  s   € ÷ ñ °Cð ¸Mñ rM   c              ƒ  	óD  "  € V P                   '       d	   V'       g   R # WP                  9   d/   V P                  P                  V4       V P                  V,          #  V P                  V4      pV P	                  V P                   P
                  P                  P                  P                  V4      G R j  x€L
 pV'       d   \        VRR 4      ! 4       RJ d4   \        VRR4      p\        VRR4      p\        P                  RWV4       R # \        \        VR	R 4      R
R 4      ;'       g    . pV'       d
   V^ ,          MR p\        VRR 4      p\        VRR4      ;'       g    Rp	\        VRR4      ;'       g    Rp
V'       d   \        VRR 4      MR pV P                  WšVR7      pWÀP                  V&   \        V P                  4      \        8”  d   V P                  P                  RR7       K<  V#  EL=  \          d    \        P                  RTRR7        R # i ; i5i)Nrd  c                 ó   € R # rð   rI   rI   rM   rK   r$  Ú3FeishuAdapter._fetch_message_text.<locals>.<lambda>  rA  rM   Fr  ri  rn  zmessage lookup failedz3[Feishu] Failed to fetch parent message %s: [%s] %srB  r  rV   r  rd   rO   r�   )r  rÇ  r�   ry  z*[Feishu] Failed to fetch parent message %sTr©  )rT  rq  rE  r  r  rŠ  r‹  r1   rñ   rÎ   r¬  r¶  Ú_extract_text_from_raw_contentrT   Ú_FEISHU_MESSAGE_TEXT_CACHE_SIZEr}  r«  )r|   r€  rD   r{  r  rn  r  ÚparentrV   r  rÇ  Úparent_mentionsrŒ   s   &&           rK   r©  Ú!FeishuAdapter._fetch_message_textÿ  sÒ  é € Ø�|�|ˆ|§:ÙØ×1Ñ1Ô1Ø×$Ñ$×0Ñ0°Ô<Ø×+Ñ+¨JÕ7Ð7ð	Ø×5Ñ5°jÓAˆGØ!×/Ñ/°·±·±×0BÑ0B×0JÑ0J×0NÑ0NÐPWÓX×XˆHßœw x°¹MÔJÓLÐPUÓUÜ˜x¨°Ó;�Ü˜h¨Ð/FÓG�Ü—‘ÐTÐV`ÐhkÔlÙÜœG H¨f°dÓ;¸WÀdÓK×QÐQÈrˆEß!&�U˜1–X¨DˆFÜ˜6 6¨4Ó0ˆDÜ˜v z°2Ó6×<Ð<¸"ˆHÜ! $¨	°2Ó6×<Ð<¸"ˆKßCIœg f¨j¸$Ô?ÈtˆOØ×6Ñ6Ø!À_ð 7ó ˆDð 48×$Ñ$ ZÑ0Ü�d×.Ñ.Ó/Ô2QÔQØ×(Ñ(×0Ñ0°eÐ0Ö<ØˆKò% Yøô& ô 	Ü�N‰NÐGÈÐ^bˆNÔcÚð	üst   ‚H �A H ÁAG6 Â6G3Â7G6 ÃAG6 ÄH ÄG6 Ä,
G6 Ä7+G6 Å#G6 Å:
G6 ÆA-G6 Ç2H Ç3G6 Ç6#HÈH ÈHÈH r�   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   r  rb   rÇ  r�   rÈ  rG   r_  rI   )rJ   s   "rK   rL   rK    s,   € ÷ 0ñ 0Øð0Ø-0ð0Ø<Sð0à	ñ0rM   c               	ó"  € V P                  WV4      pVP                  '       d   VP                  # \        VP                  \        4      '       d   VP                  P                  R 4      MRp\        V4      P                  4       ;'       g    R# )rÌ  N)rx  r�   r  r“   r”   rñ   rb   r  )r|   r  rÇ  r�   r  rp  s   &$$$  rK   r  Ú,FeishuAdapter._extract_text_from_raw_content  sv   € ð —_‘_ X¸HÓEˆ
Ø×"×"Ð"Ø×*Ñ*Ð*ÜEOÐPZ×PcÑPcÔei×EjÒEj�j×)Ñ)×-Ñ-Ð.@ÔAÐptˆÜ�;Ó×%Ñ%Ó'×/Ð/¨4Ð/rM   c               ó    € V ^8„  d   QhRRRR/# )rC   rú  rb   rG   rI   )rJ   s   "rK   rL   rK  (  s   € ÷ ?ñ ? sð ?¨sñ ?rM   c                	ó„   € T ;'       g    R P                  4       pVR9   d   R# RVP                  R4      ;'       g    R 2# )rd   z
image/jpegr”  r  Újpeg>   rê  ú.jpeg)r±  rn  )rú  Únormalized_exts   & rK   rº  Ú'FeishuAdapter._default_image_media_type'  sC   € àŸ)˜) ×*Ñ*Ó,ˆØÐ.Ô.ÙØ˜×-Ñ-¨cÓ2×<Ð<°fÐ=Ð>Ð>rM   c               ó    € V ^8„  d   QhRRRR/# )rC   rK  r
   rG   rI  rI   )rJ   s   "rK   rL   rK  /  s   € ÷ Nñ N¨ð N°ñ NrM   c                	óv   €  V P                  4        R#   \         d    \        P                  R 4        R# i ; i)z-[Feishu] Background inbound processing failedN)re  r«  r¬  r­  )rK  s   &rK   rÔ  Ú%FeishuAdapter._log_background_failure.  s1   € ð	NØ�M‰MŽOøÜô 	NÜ×ÑÐL×Mð	Nús   ‚ ” 8·8c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rÈ   r
   r1   rG   zOptional[RejectReason]rI   )rJ   s   "rK   rL   rK  6  s"   € ÷ !ñ !˜Sð !¨3ð !Ð3Iñ !rM   c                	ó  € \        V4      p\        R  V P                  V P                  3 4       4      p\	        V4      p\        VRR4      R8g  p\        VRR4      ;'       g    RpT;'       d    V P                  V4      pV'       d   W4,          '       d   R# V'       dP   V P                  p	V	R9  d   R# V'       d	   V'       g   R# V	R8X  d"   V'       g   V P                  V4      '       g   R	# V'       gC   V P                  '       g   V P                  '       g   R
# W0P                  ,          '       d   R
# R# V P                  \        VRR
4      WuR7      '       g   R# V'       d   V P                  V4      '       g   R# R
# )c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir{   rI   rÔ   s   & rK   r×   Ú'FeishuAdapter._admit.<locals>.<genexpr>8  s   é € ÐTÑ(N 1ÓRSŸQšQÓ(NùrÙ   rC  r{  rö  rd   Ú	self_echor�   Úbots_disabledÚself_ids_unknownÚbot_not_mentionedNÚdm_policy_rejectedrÒ   r¢  rz  )r�   r³  )rà   r¹   r§  Ú_bot_user_idrÏ   rÎ   Ú_require_mention_forÚ_allow_botsÚ_mentions_selfÚ_allow_all_dmrÉ  Ú_allow_group_message)
r|   rÈ   r1   Ú
sender_idsÚself_idsr|  Úis_grouprö  r¶   Úmodes
   &&&       rK   r~  ÚFeishuAdapter._admit6  s<  € Ü% fÓ-ˆ
ÜÑT¨×):Ñ):¸D×<MÑ<MÑ(NÓTÓTˆÜ Ó'ˆÜ˜7 K°Ó7¸5Ñ@ˆÜ˜' 9¨bÓ1×7Ð7°RˆØ"×IÐI t×'@Ñ'@ÀÓ'Iˆ÷ ˜
×-Ô-ÙßØ×#Ñ#ˆDØÐ.Ô.Ù&ß§:Ù)à�zÔ!¯/À$×BUÑBUÐV]×B^ÒB^Ù*ßð ×!×!Ð!¨×)B×)BÐ)BÙØ%×(AÑ(A×AÔA�4Ð[ÐG[Ð[Ø×(Ñ(¬°¸ÀdÓ)KÈWÐ(×dÒdÙ*ß 4×#6Ñ#6°w×#?Ò#?Ù*ÙrM   c               ó    € V ^8„  d   QhRRRR/# r'  rI   )rJ   s   "rK   rL   rK  \  s   € ÷ !ñ !°sð !¸tñ !rM   c                óØ   € V P                   '       d   R# ^ RIHp V! WP                  V P                  V P
                  R7      pV'       d   RV n         \        P                  V4       R# R# )uô   One WARNING when group traffic dies on the untouched allowlist default (#111420).

The policy read is scoped per profile on purpose â€” never inherit another profile's
FEISHU_GROUP_POLICY here; only make the resulting deny visible above DEBUG.
N)Úempty_allowlist_drop_warning)rö  r³   r²   rž   T)Ú_warned_empty_allowlist_denyÚ5plugins.platforms.feishu.feishu_admission_diagnosticsrD  Ú_group_rulesrË  rÉ  r¬  r¶  )r|   rö  rD  rŒ   s   &&  rK   r  Ú-FeishuAdapter._warn_once_empty_allowlist_deny\  sY   € ð ×,×,Ð,ÙÝfÙ+Ø×):Ñ):Ø!%×!;Ñ!;ÐQU×QjÑQjô
ˆ÷ Ø04ˆDÔ-Ü�N‰N˜4Ö ñ rM   c               ó    € V ^8„  d   QhRRRR/# )rC   rö  rb   rG   rr   rI   )rJ   s   "rK   rL   rK  m  s   € ÷ %ñ %¨Cð %°Dñ %rM   c                	ó¨   € V'       d   V P                   P                  V4      MR pV'       d   VP                  e   VP                  # V P                  # r{   )rG  rñ   r¶   Ú_require_mention)r|   rö  Úrules   && rK   r8  Ú"FeishuAdapter._require_mention_form  sB   € ß18ˆt× Ñ ×$Ñ$ WÔ-¸dˆß�D×(Ñ(Ò4Ø×'Ñ'Ð'Ø×$Ñ$Ð$rM   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   rÒ   r
   rö  rb   r|  rr   rG   rI   )rJ   s   "rK   rL   rK  s  s0   € ÷ Mñ M¨cð M¸Cð MÐQUð MÐbfñ MrM   c               óÊ  € \        VRR4      \        VRR4      0R0,
          pV'       d-   V P                  '       d   W@P                  ,          '       d   R# V'       d   V P                  P                  V4      MRpV'       d%   VP                  VP
                  VP                  r‡pM5V P                  ;'       g    V P                  V P                  \        4       r‡pVR	9   d   R# VR8X  g	   V'       d   R# VR8X  d   \        T;'       d	    WG,          4      # VR8X  d!   \        T;'       d    WH,          '       * 4      # \        T;'       d    W@P                  ,          4      # )
z)Per-group policy gate for non-DM traffic.rq   Nrw   TFr–  r¾   r¿   )ÚdisabledÚ
admin_only)rÎ   rÊ  rG  rñ   r¼   r¾   r¿   rË  Ú_group_policyrÉ  rÀ   rr   )	r|   rÒ   rö  r|  r=  rL  r¼   r¾   r¿   s	   &&&$     rK   r<  Ú"FeishuAdapter._allow_group_messages  s  € ä˜i¨°DÓ9¼7À9ÈiÐY]Ó;^Ð_ÐcgÐbhÕhˆ
ß˜$Ÿ,Ÿ,˜,¨J¿¹×,EÔ,EÙß18ˆt× Ñ ×$Ñ$ WÔ-¸dˆßØ+/¯;©;¸¿¹ÈÏÉ˜yˆF˜yà+/×+EÑ+E×+[Ð+[È×I[ÑI[Ð]a×]vÑ]vÔx{Óx}˜yˆFð Ð/Ô/ÙØ�VÔŸvÙØ�[Ô Ü˜
×?Ð?¨
Õ(>Ó@Ð@Ø�[Ô Ü˜
×CÐC¨JÕ,BÔ'CÓDÐDÜ�J×KÐK J×1JÑ1JÕ$JÓLÐLrM   c               ó    € V ^8„  d   QhRRRR/# )rC   r1   r
   rG   rr   rI   )rJ   s   "rK   rL   rK  ‰  s   € ÷ 	<ñ 	< cð 	<¨dñ 	<rM   c           	     	óN  € \        VR R4      ;'       g    RpRV9   d   R# \        VRR4      ;'       g    . pV'       d   V P                  V4      '       d   R# T P                  \        VRR4      ;'       g    RV\        VRR4      4      pV P                  VP                  4      # )rO   rd   r‘  Tr�   NrÆ  )rÎ   Ú_message_mentions_botrx  Ú_post_mentions_botr�   )r|   r1   rÇ  r�   r  s   &&   rK   r:  ÚFeishuAdapter._mentions_self‰  sž   € ä˜g y°"Ó5×;Ð;¸ˆØ�kÔ!ÙÜ˜7 J°Ó5×;Ð;¸ˆß˜×2Ñ2°8×<Ò<ÙØ—_‘_¤W¨W°nÀbÓ%I×%OÐ%OÈRÐQ\Ô^eÐfmÐoyÐ{ó  _Aó  Bˆ
Ø×&Ñ& z×':Ñ':Ó;Ð;rM   c               ó    € V ^8„  d   QhRRRR/# )rC   r�   rf  rG   rr   rI   )rJ   s   "rK   rL   rK  ”  s   € ÷ ñ ¨ið ¸Dñ rM   c           
     	ó^  € V P                  4       pV F–  p\        VR R4      pTP                  \        VRR4      ;'       g    RP                  4       \        VRR4      ;'       g    RP                  4       \        VRR4      ;'       g    RP                  4       R7      '       g   K•   R# 	  R# )	r]  Nrq   rd   rw   rp   rd  TF)rw  rÎ   r}   r  )r|   r�   rÌ   rZ  r`  s   &&   rK   rV  Ú#FeishuAdapter._message_mentions_bot”  s¡   € ð × Ñ Ó"ˆÛˆGÜ  ¨$°Ó5ˆJØ�{‰{Ü  ¨Y¸Ó=×CÐCÀ×JÑJÓLÜ  ¨Y¸Ó=×CÐCÀ×JÑJÓLÜ˜g v¨tÓ4×:Ð:¸×AÑAÓCð ÷ ô ò
 ñ  ñ rM   c               ó    € V ^8„  d   QhRRRR/# )rC   r�   rŽ   rG   rr   rI   )rJ   s   "rK   rL   rK  ¢  s   € ÷ 0ñ 0Ð+Að 0Àdñ 0rM   c                	ój   € \         ;QJ d    R  V 4       F  '       g   K   R# 	  R# ! R  V 4       4      # )c              3  ó8   "  € T F  qP                   x € K  	  R # 5ir{   )rt   )rÕ   r#  s   & rK   r×   Ú3FeishuAdapter._post_mentions_bot.<locals>.<genexpr>£  s   é € Ð/¡h —9–9£hùs   ‚TF)r´  )r|   r�   s   &&rK   rW  Ú FeishuAdapter._post_mentions_bot¢  s+   € ß‹sÑ/¡hÓ/�sŒsÐ/ŠsÐ/ˆsÑ/¡hÓ/Ó/Ð/rM   c               ó   € V ^8„  d   QhRR/# )rC   rG   rv   rI   )rJ   s   "rK   rL   rK  ¥  s   € ÷ mñ mÐ1ñ mrM   c                	óZ   € \        V P                  V P                  V P                  R 7      # )rd  )rv   r§  r7  Ú	_bot_namerˆ  s   &rK   rw  ÚFeishuAdapter._bot_identity¥  s$   € Ü!¨$×*;Ñ*;ÀT×EVÑEVÐ]a×]kÑ]kÔlÐlrM   c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  ¨  s   € ÷ 3eñ 3e¨Tñ 3erM   c              ƒ  óŒ  "  € V P                   '       g   R#  V P                  R4      G Rj  x€L
 pV'       Ed
   \        P                  ! V4      p\	        V4      ;'       g    / pVP                  R4      ;'       g    RP                  4       pVP                  R4      ;'       g    RP                  4       pV'       d?   V P                  '       d'   V P                  V8w  d   \        P                  R4       W@n        V'       d?   V P                  '       d'   V P                  V8w  d   \        P                  R4       WPn
        T P                  '       d   R#  T P                  T P                  RR7      pT P!                  T P                   P"                  P$                  P"                  P
                  T4      G Rj  x€L
 pT'       d   TP'                  4       '       g,   \)        TRR4      pTR8X  d   \        P                  R4       R# \)        \)        TRR4      RR4      p	\)        T	RR4      ;'       g    RP                  4       p
T
'       d   T P                  '       g	   Y n
        R# R# R#  ELA  \         d    \        P                  RR	R
7        ELRi ; i LÜ  \         d    \        P                  RR	R
7        R# i ; i5i)a8  Best-effort bot identity discovery for mention gating and self-event filtering.

/bot/v3/info (tenant token, no extra scopes) always wins over env values so stale
FEISHU_BOT_* from app migrations can't break gating; the application-info endpoint is
a name-only fallback. On failure env-provided values are kept.
Nú/open-apis/bot/v3/inforŸ   rd   r¡   z[[Feishu] FEISHU_BOT_OPEN_ID is stale; using /bot/v3/info open_id for group @mention gating.zf[Feishu] FEISHU_BOT_NAME differs from /bot/v3/info; using hydrated bot name for group @mention gating.z3[Feishu] /bot/v3/info probe failed during hydrationTr©  Úen_us©r—   r  r  ixÀõz¼[Feishu] Unable to hydrate bot name from application info. Grant admin:app.info:readonly or application:application:self_manage so group @mention gating can resolve the bot name precisely.rB  rË   Úapp_namez9[Feishu] Failed to hydrate bot name from application info)rT  r  r?  rá  Ú_parse_bot_responserñ   r  r§  r¬  r¶  rc  r$  r«  r®  Ú_build_get_application_requestr  r  ÚapplicationÚv6rd  rÎ   )r|   rO   r\  r1  rq   r¡   rD   r{  r  rË   rj  s   &          rK   Ú_hydrate_bot_identityÚ#FeishuAdapter._hydrate_bot_identity¨  s4  é € ð �|�|ˆ|Ùð	_Ø ×0Ñ0Ð1IÓJ×JˆGßˆwÜŸ*š* WÓ-�Ü,¨WÓ5×;Ð;¸�Ø!Ÿ:™: mÓ4×:Ð:¸×AÑAÓC�Ø"ŸJ™J zÓ2×8Ð8°b×?Ñ?ÓA�ßØ×(×(Ð(¨T×->Ñ->À'Ô-IÜŸ™Øyôð )0Ô%ßØ—~—~�~¨$¯.©.¸HÔ*DÜŸ™ð Eôð &.”Nð �>�>ˆ>Ùð	eØ×9Ñ9ÀÇÁÐT[Ð9Ó\ˆGØ!×/Ñ/°·±×0HÑ0H×0KÑ0K×0WÑ0W×0[Ñ0[Ð]dÓe×eˆHß 8×#3Ñ#3×#5Ò#5Ü˜x¨°Ó6�Ø˜8Ô#Ü—N‘NðWôñ
 Üœ' (¨F°DÓ9¸5À$ÓGˆCÜ  Z°Ó6×<Ð<¸"×CÑCÓEˆHß §§ Ø!)–ñ !/‰xòM Køô$ ô 	_Ü�L‰LÐNÐY]ˆL×^ð	_úñ føô ô 	eÜ�L‰LÐTÐ_cˆL×dð	eüsÉ   ‚K˜I0 ¬I-­I0 º'I0 Á"I0 Á=(I0 Â&I0 Â?I0 Ã3I0 ÄI0 Ä,I0 ÅKÅKÅA$J Æ<JÆ=J Ç	J Ç)J ÈKÈ
AJ ÉJ É!J É'KÉ-I0 É0"JÊKÊJÊKÊJ Ê"KÊ=KË KËKc               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  Þ  s   € ÷ Cñ C¨ñ CrM   c                	óö  a€  \         P                  ! V P                  P                  R R7      4      p\        T\        4      '       d   TP                  R/ 4      M/ p\        P                  ! 4       p\        p\        T\        4      '       dL   T Uu/ uF>  p\        T4      P!                  4       '       g   K$  \        T4      P!                  4       RbK@  	  ppM•\        T\        4      '       d~   / pTP#                  4        Ff  w  rx\        T\        4      '       g   K  TP!                  4       '       g   K5  \        T\$        \&        \        34      '       g   KX   \'        T4      Yg&   Kh  	  MR# TP#                  4        U	U
u/ uF$  w  ršT
R8X  g   T^ 8:  g   Y:,
          T8  g   K"  YšbK&  	  up
p	o\+        ST3R lRR	7      RT P,                   p\        \/        T4      4      T n        T Uu/ uF  qÌST,          bK  	  upT n        R#   \         d     R# \
        \         P                  3 d'    \        P                  RT P                  RR7        R# i ; iu upi   \(         d     EKk  i ; iu up
p	i u upi )
rŸ  rã  Nz5[Feishu] Failed to load persisted dedup state from %sTr©  Úmessage_idsrd  c                ó   <€ SV ,          # r{   rI   )rÛ   Úvalids   &€rK   r$  Ú6FeishuAdapter._load_seen_message_ids.<locals>.<lambda>ø  s	   ø€ °°q¶rM   )rî   Úreverse)r?  rá  rc  r¦  ÚFileNotFoundErrorrø  râ  r¬  r¶  r  r”   rñ   rp  Ú_FEISHU_DEDUP_TTL_SECONDSrˆ   rb   r  r  rF   r£   rU   ÚsortedÚ_dedup_cache_sizeÚreversedrb  ra  )r|   r\  Ú	seen_datar   Úttlrc  rñ  rî   rè   r#  r!  Ú
sorted_idsrÛ   ru  s   &            @rK   r€  Ú$FeishuAdapter._load_seen_message_idsÞ  sú  ø€ ð	Ü—j’j ×!7Ñ!7×!AÑ!AÈ;Ð!AÓ!WÓXˆGô 7AÀÌ$×6OÒ6O�G—K‘K ¨rÔ2ÐUWˆ	Ü�iŠi‹kˆÜ'ˆÜ�i¤×&Ò&ÙLUÓ(kÉIÀDÔY\Ð]aÓYb×YhÑYh×YjÔ)?¬¨T«¯©Ó):¸CÒ)?ÉIˆGÐ(kˆGÜ˜	¤4×(Ò(ØˆGØ'Ÿo™oÖ/‘
�Ü˜c¤3×'Ô'¨C¯I©I¯K¬K¼JÀuÌsÔTYÔ[^ÐN_×<`Ô<`ðÜ',¨U£|˜›ò 0ñ à6=·m±m´oÔ"q±o©U¨QÈÈsÌÐVYÐ]^ÔV^ÐbeÕbjÐmpÑbp¤5 1¢5±oÒ"qˆä˜EÔ'9À4ÔHÐI`È$×J`ÑJ`Ðaˆ
Ü#'¬°Ó(<Ó#=ˆÔ Ù7AÓ!B±z°! U¨1¥X¢+±zÑ!BˆÖøô3 !ô 	ÚÜœ×-Ñ-Ð.ô 	Ü�N‰NÐRÐTX×TjÑTjÐuyˆNÔzÚð	üò )løô &ô Ûðüó
 #rùò "CsM   ƒ0H Â!IÂ8IÅIÆI0Æ%I0Ç+I6ÈIÈIÈ.#IÉIÉI-É,I-c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  ü  s   € ÷ 
rñ 
r¨4ñ 
rrM   c           	     	óð  €  ^ RI Hp V! V P                  P                  4       V P                  ;_uu_ 4        V P
                  V P                  ) R pRV Uu/ uF(  q3V P                  9   g   K  W0P                  V,          bK*  	  up/pRRR4       \        V P                  XRR7       R# u upi   + '       g   i     L/; i  \         d'    \        P                  RT P                  RR7        R# i ; i)rõ   )Úmkdir_under_hermes_homeNrs  )Úindentz,[Feishu] Failed to persist dedup state to %sTr©  )Úhermes_constantsrƒ  rc  r  rd  rb  r{  ra  r(   rø  r¬  r¶  )r|   rƒ  ÚrecentrÛ   r\  s   &    rK   r3  Ú'FeishuAdapter._persist_seen_message_idsü  sÔ   € ð		rÝ@Ù# D×$:Ñ$:×$AÑ$AÔBØ×!×!Ó!Ø×1Ñ1°4×3IÑ3IÐ2IÐ2JÐK�à(ÑQWÓ*wÑQWÈAÐ`d×`vÑ`vÑ[vÔ+G¨1×.DÑ.DÀQÕ.GÒ+GÑQWÑ*wÐx�÷ "ô ˜d×4Ñ4°gÀd×Kùò +x÷ "×!ûô
 ô 	rÜ�N‰NÐIÈ4×KaÑKaÐlpˆN×qð	rús@   ‚6C ¸ B1ÁB,
Á/B,
ÂB1Â
 C Â,B1Â1C	Â<C Ã-C5Ã4C5c               ó    € V ^8„  d   QhRRRR/# )rC   r€  rb   rG   rr   rI   )rJ   s   "rK   rL   rK    s   € ÷ ñ ¨cð °dñ rM   c              ƒ  	ó  "  € \         P                   ! 4       \        r2V P                  ;_uu_ 4        V P                  P	                  V4      pVe    V^ 8:  g   W$,
          V8  d    R R R 4       R# W P                  V&   V P
                  P                  V4       \        V P
                  4      V P                  8”  d8   V P                  P                  V P
                  P                  ^ 4      R 4       K[   R R R 4       V P                  4       ;_uu_4       GR j  x€L
  V P                  V P                  4      G R j  x€L
  R R R 4      GR j  x€L
  R#   + '       g   i     Lf; i LL L+ L  + GR j  x€L 
 '       g   i     R# ; i5i)NTF)rp  ry  rd  ra  rñ   rb  rM  rT   r{  r]  Ú_dedup_persist_lock_or_creater  r3  )r|   r€  r   r~  Úseen_ats   &&   rK   r}  ÚFeishuAdapter._is_duplicate  s  é € Ü—9’9“;Ô 9ˆSØ××ÓØ×,Ñ,×0Ñ0°Ó<ˆGØÒ"¨¨q¬°CµMÀCÔ4GØ÷ Ñð 25×"Ñ" :Ñ.Ø×$Ñ$×+Ñ+¨JÔ7Ü�d×.Ñ.Ó/°$×2HÑ2HÔHØ×&Ñ&×*Ñ*¨4×+CÑ+C×+GÑ+GÈÓ+JÈDÖQð I÷ ð ×5Ñ5×7×7Õ7Ø×$Ñ$ T×%CÑ%CÓD×DÐD÷ 8×7á÷ ×úñ 8ÙD÷ 8×7×7Ñ7áüsƒ   ‚/F	±5EÁ&
F	Á0BEÃ5$F	ÄE&ÄF	ÄE,Ä<E(Ä=E,ÅF	ÅE*ÅF	ÅE#	Å	F	Å(E,Å*F	Å,F	Å2E5Å3
F	Å>F	Æ 	F	c               ó   € V ^8„  d   QhRR/# )rC   rG   r?  rI   )rJ   s   "rK   rL   rK    s   € ÷ ñ ¨|ñ rM   c                	ó^   € \        V R R4      pVf   \        P                  ! 4       ;qn        V# )re  N)rÎ   rQ   rV  re  )r|   rü  s   & rK   rŠ  Ú+FeishuAdapter._dedup_persist_lock_or_create  s.   € ô �tÐ2°DÓ9ˆØŠ<Ü.5¯lªl«nÐ<ˆDÔ+ØˆrM   rm  c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rO   rb   rm  rr   rG   r[  rI   )rJ   s   "rK   rL   rK  $  s'   € ÷ Iñ I¨sð IÀDð IÐUdñ IrM   c               	óš   € V'       g   \         P                  V4      '       d   R \        V4      3# R\        P                  ! RV/RR7      3# )ru  rŒ   Fr<  )rr  rs  rB  r?  r@  )r|   rO   rm  s   &&$rK   rt  Ú%FeishuAdapter._build_outbound_payload$  sD   € ÷ Ô+×2Ñ2°7×;Ò;ØÔ7¸Ó@Ð@Ð@Ø”t—z’z 6¨7Ð"3À%ÔHÐHÐHrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rñ  rb   rG   rF   rI   )rJ   s   "rK   rL   rK  2  s   € ÷ ñ ¨#ð °#ñ rM   c                ó   € ^ RI p \        V R4      ;_uu_ 4       pVP                  4       pRRR4       ^ ;rEV\        X4      ^,
          8  d¼   VP	                  RV4      pVR8X  g   V^,           \        V4      8”  d   MŠVP                  RW4^,           4      ^ ,          pW4^,           ,          pV^ 8”  d   TMTpV^,           V,           \        V4      8”  d   M1WG\        W4^,           V^,           V,            4      ,           ,          pKÒ  V^ 8”  d   \        VR,          R,          4      # ^ #   + '       g   i     EL; i  \         d     ^ # i ; i)z_OGG/Opus duration in ms (pure Python): last granule position / 48000 Hz; 0 on non-OGG or error.NÚrbs   OggSz<qi€»  rH  éÿÿÿÿ)	Ústructr–  rË  rT   ÚfindÚunpack_fromÚsumrF   r«  )rñ  r—  ÚfrB  ÚposÚlast_granuleÚgranuleÚnum_segmentss   &       rK   Ú_get_audio_duration_msÚ$FeishuAdapter._get_audio_duration_ms1  s  € ó 	ð	Ü�i ×&Ô&¨!Ø—v‘v“x�÷ 'à!"Ð"ˆCØœ˜D›	 B�Ô&Ø—i‘i ¨Ó-�Ø˜"”9  b¥¬3¨t«9Ô 4ØØ ×,Ñ,¨T°4¸q½ÓAÀ!ÕD�Ø#¨"¥H�~�Ø*1°A¬+™w¸<�Ø˜•8˜lÕ*¬S°«YÔ6ØØ¤c¨$°R­x¸#À½(À\Õ:QÐ*RÓ&SÕSÕS’Ø7CÀaÔ7G”3�| eÕ+¨dÕ2Ó3ÐNÈQÐN÷ '×&Ð&ûô ô 	Úð	ús.   †D> šD*«C<D> Ä(D> Ä*D;	Ä5	D> Ä>EÅErí  re   rò  rf   c               ó8   € V ^8„  d   QhRRRRRRRRRRR	RR
RRR/# )rC   rö  rb   rñ  r^  r_  r“   r`  rí  re   rò  rG   r   rI   )rJ   s   "rK   rL   rK  G  sN   € ÷ :=ñ :=Øð:=Ø*-ð:=Ø9Fð:=ØRjð:=àð:=à2?ð:=à_bð:=ð 
ñ:=rM   c             ƒ  	ó¸  "  € V P                   '       g   \        R RR7      # \        P                  P	                  V4      '       g   \        R RV 2R7      # T;'       g     \        P                  P                  V4      pV P                  W‡R7      w  rš V	R8X  d   V P                  V4      M^ p\        VR4      ;_uu_ 4       pV P                  W˜WËR7      pV P                  V4      pV P                  V P                   P                  P                  P                  P                  V4      G Rj  x€L
 pRRR4       V P!                  XR	4      pV'       g   V P#                  VR
RR7      # R	V/pV P%                  WWEV
VRRR	VRV/R7      G Rj  x€L
 pV'       EgG   V P'                  V4      '       Eg/   \)        VRR4      R8X  Ed   V
R8X  Ed   T;'       g    / P+                  R4      '       dó   \,        P.                  ! VR R7      pT;'       g    / P+                  R4      pV'       g3   T P1                  T;'       g    / P+                  R4      4      G Rj  x€L
 pV'       d4   \2        P5                  R4       V P7                  VRVVVR7      G Rj  x€L
 pV P'                  V4      '       g4   \2        P9                  R4       V P7                  VRVRRR7      G Rj  x€L
 pV P;                  VR4      #  ELÄ  + '       g   i     ELË; i EL} Lµ L| L4  \<         d:   p\2        P?                  RTTRR7       \        R \A        T4      R7      u Rp?# Rp?ii ; i5i)Frb  rc  zFile not found: )rñ  Úrequested_message_typeÚopusr•  ©Ú	file_typere   rf   ÚdurationNrc   zfile upload failedz#Feishu file upload missing file_keyr  rE  r«  re   r  r  iRÃõrª  r2  r<  r¦  z0[Feishu] Audio: retrying via reply API in threadri  z;[Feishu] Audio send failed in thread, retrying with chat_idzfile send failedz#[Feishu] Failed to send file %s: %sTr©  )!rT  r   rö  r  r  r  Ú_resolve_outbound_file_routingr   r–  Ú_build_file_upload_bodyÚ_build_file_upload_requestr  rŠ  r‹  rf   r  r  r  r  rv  rÎ   rñ   r?  r@  Ú_fetch_last_message_in_threadr¬  r$  rj  r¶  rw  r«  r  rb   )r|   rö  rñ  r^  r“   rí  re   rò  r¸  Úupload_file_typeÚresolved_message_typeÚduration_msrÌ  rV   rD   r"  rc   r  r#  r\  Úthread_msg_idrW   s   &$$$$$$$              rK   rõ  Ú)FeishuAdapter._send_uploaded_file_messageG  s  é € ð �|�|ˆ|Ü e°?ÔCÐCÜ�w‰w�~‰~˜i×(Ò(Ü eÐ5EÀiÀ[Ð3QÔRÐRà ×?Ð?¤B§G¡G×$4Ñ$4°YÓ$?ˆØ26×2UÑ2UØ"ð 3Vó 3
Ñ/Ðð-	=ØDTÐX^ÔD^˜$×5Ñ5°iÔ@ÐdeˆKÜ�i ×&Ô&¨(Ø×3Ñ3Ø.ÈXð 4ó �ð ×9Ñ9¸$Ó?�Ø(,×(:Ñ(:¸4¿<¹<¿?¹?×;MÑ;M×;RÑ;R×;YÑ;YÐ[bÓ(c×"c�÷ 'ð ×3Ñ3°OÀZÓPˆHßØ×2Ñ2Ø#Ð5IØ#Hð 3ó ð ð
 & xÐ0ˆKØ%)×%<Ñ%<Ø¸XØ2ÀØ  '¨:°xÀÈlÐ[ð &=ó &÷  Ð÷ �GØ ×4Ñ4Ð5E×FÓFÜÐ 0°&¸$Ó?À8ÕKØ-°Õ8Ø!Ÿ˜ R×,Ñ,¨[×9Ò9ÜŸ*š* [¸uÔE�Ø!)§ ¨R× 4Ñ 4Ð5JÓ K�ß$Ø*.×*LÑ*LÈhÏnÈnÐZ\×MaÑMaÐbmÓMnÓ*o×$o�Mß Ü—K‘KÐ RÔSØ-1×-IÑ-IØ '°'À7ÐUbÐmuð .Jó .÷ (Ð$ð ×/Ñ/Ð0@×AÒAÜ—N‘NÐ#`ÔaØ-1×-IÑ-IØ '°'À7ÐUYÐdhð .Jó .÷ (Ð$ð ×-Ñ-Ð.>Ð@RÓSÐSòG #d÷ '×&Ð&úò ñ %pñ(ñ
(øô ô 	=Ü�L‰LÐ>À	È3ÐY]ˆLÔ^Ü e´3°s³8Ô<Õ<ûð	=üs÷   ‚AMÁMÁ 4MÂ.L ÃA,K6Ä/K3Ä0K6Ä4!L ÅL Å)MÅ*#L ÆL
ÆL ÆL Æ3#L ÇL Ç/ L ÈL È*L È>L ÉLÉL É$.L ÊLÊL Ê..L ËLËL Ë2MË3K6Ë6L	Ì
L ÌL ÌL ÌL ÌMÌ.MÍMÍMÍMÍMc               ó8   € V ^8„  d   QhRRRRRRRRRRR	R
RR
RR/# )rC   rö  rb   r^  r_  r“   r`  rí  r  r  r?   r  rG   r
   rI   )rJ   s   "rK   rL   rK  ƒ  sN   € ÷ 
ñ 
Øð
Ø)6ð
ØBZð
Øerð
àð
à(6ð
àCQð
ð 
ñ
rM   c             ƒ  ó´   "  € V'       d   RpV P                  WGR7      p	MTp\        P                  ! VRR7      p	V P                  WW’VR7      G Rj  x€L
 #  L5i)zRSend an uploaded image/file key: as a captioned ``post`` or as a bare key message.ru  )rí  r  Fr<  ri  N)Ú_build_media_post_payloadr?  r@  rj  )
r|   rö  r^  r“   rí  r  r  r  r  r\  s
   &$$$$$$$  rK   r  Ú FeishuAdapter._send_uploaded_keyƒ  sa   é € ÷
 ØˆHØ×4Ñ4¸WÐ4ÓZ‰Gà#ˆHÜ—j’j ¸5ÔAˆGØ×1Ñ1Ø¸Ð]eð 2ó 
÷ 
ð 	
ñ 
ùs   ‚AAÁAÁAc               ó    € V ^8„  d   QhRRRR/# )rC   r2  rb   rG   r_  rI   )rJ   s   "rK   rL   rK  ’  s   € ÷ ñ ¸Sð À]ñ rM   c              ƒ  óš  "  € V P                   '       d	   V'       g   R#  ^ RIHp VP                  4       P	                  R4      P                  V4      P                  ^4      P                  4       pV P                  V P                   P                  P                  P                  P                  V4      G Rj  x€L
 pV P                  V4      '       dE   \        \        VRR4      RR4      pV'       d%   \        V4      ^ 8”  d   \        V^ ,          RR4      # R#  La  \          d"   p\"        P%                  RY4        Rp?R# Rp?ii ; i5i)z>Fetch the last message_id in a thread for reply-based routing.N)ÚListMessageRequestrê  rB  r  r€  z6[Feishu] Failed to fetch last message in thread %s: %s)rT  re  r¸  r  Úcontainer_id_typeÚcontainer_idÚ	page_sizer"  r  rŠ  r‹  r1   rˆ   rv  rÎ   rT   r«  r¬  r®  )r|   r2  r¸  rD   r{  r  rW   s   &&     rK   r¬  Ú+FeishuAdapter._fetch_last_message_in_thread’  s  é € à�|�|ˆ|§9Ùð		cÝ>Ø(×0Ñ0Ó2×DÑDÀXÓN×[Ñ[Ð\eÓf×pÑpÐqrÓs×yÑyÓ{ˆGØ!×/Ñ/°·±·±×0BÑ0B×0JÑ0J×0OÑ0OÐQXÓY×YˆHØ×'Ñ'¨×1Ò1Ü¤¨°&¸$Ó ?ÀÈ$ÓO�ßœS ›Z¨!œ^Ü" 5¨¥8¨\¸4Ó@Ð@ñ ñ Zøô
 ô 	cÜ�L‰LÐQÐS\×bÐbÙûð	cüsM   ‚E�E BD Â8DÂ9D ÃAD ÄEÄD ÄEÄ'EÄ=EÅEÅEc               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# ©rC   rö  rb   r  r\  r^  r_  r“   r`  rG   r
   rI   )rJ   s   "rK   rL   rK  ¢  sD   € ÷ Tñ TØðTØ),ðTØ7:ðTØFSðTØ_wðTà	ñTrM   c          	   ƒ  	ó®  "  € T;'       g    / P                  R 4      pT;'       g&    V'       d   T;'       g    / P                  R4      MRpV'       d—   V P                  W2\        V4      \        \        P
                  ! 4       4      R7      pV P                  Wx4      p	V P                  V P                  P                  P                  P                  P                  V	4      G Rj  x€L
 # V'       d   TR rºMMVP                  R4      '       d   VP                  R^4      ^,          RrºMYP                  R4      '       d   RMR	rºV P                  W¢V\        \        P
                  ! 4       4      R
7      pV P!                  W¸4      p	V P                  V P                  P                  P                  P                  P"                  V	4      G Rj  x€L
 #  Lê L5i)r2  r¦  N©rO   r  Úreply_in_threadÚ
uuid_valuezfeishu_user_id:r¤  rw   rü  rq   rö  ©Ú
receive_idr  rO   rÂ  )rñ   Ú_build_reply_message_bodyrr   rb   r(  r)  Ú_build_reply_message_requestr  rT  rŠ  r‹  r1   Úreplyrû   rQ  Ú_build_create_message_bodyÚ_build_create_message_requestr  )r|   rö  r  r\  r^  r“   r2  Úeffective_reply_torV   rD   rÄ  Úreceive_id_types   &$$$$$      rK   Ú_send_raw_messageÚFeishuAdapter._send_raw_message¢  s  é € ð —^�^ ×(Ñ(¨Ó5ˆ	Ø%×mÐm×Yb¨8¯>¨>°r×*>Ñ*>Ð?TÔ*UÐhlÐßØ×1Ñ1ØÄDÈÃOÔ`cÔdh×dnÒdnÓdpÓ`qð 2ó ˆDð ×7Ñ7Ð8JÓQˆGØ×+Ñ+¨D¯L©L¯O©O×,>Ñ,>×,FÑ,F×,LÑ,LÈgÓV×VÐVßà*3°[™Ø×ÑÐ 1×2Ò2Ø*1¯-©-¸¸QÓ*?ÀÕ*BÀI™à*1×@RÑ@RÐSX×@YÒ@Y±9Ð_h˜Ø×.Ñ.Ø!¸gÔRUÔVZ×V`ÒV`ÓVbÓRcð /ó 
ˆð ×4Ñ4°_ÓKˆØ×'Ñ'¨¯©¯©×(:Ñ(:×(BÑ(B×(IÑ(IÈ7ÓS×SÐSñ Wñ TùsF   ‚$G§G°G¹GÁBGÃ&GÃ'GÃ3GÄB>GÇGÇGÇGc               ó    € V ^8„  d   QhRRRR/# )rC   r{  r
   rG   rr   rI   )rJ   s   "rK   rL   rK  »  s   € ÷ Pñ P cð P¨dñ PrM   c                	óN   € \        T ;'       d    \        V R R 4      ! 4       4      # )rd  c                 ó   € R # rð   rI   rI   rM   rK   r$  Ú3FeishuAdapter._response_succeeded.<locals>.<lambda>¼  s   € ÁerM   rÊ  )r{  s   &rK   rv  Ú!FeishuAdapter._response_succeededº  s!   € ä�H×NÐN¤¨°9¹mÔ!LÓ!NÓOÐOrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r{  r
   Ú
field_namerb   rG   rI   )rJ   s   "rK   rL   rK  ¿  s&   € ÷ Añ A¨#ð A¸3ð AÀ3ñ ArM   c                	ó‚   € \         P                  V 4      '       d   \        V R R4      MRpV'       d   \        W!R4      # R# )rB  N)rE  rv  rÎ   )r{  rÔ  rB  s   && rK   r  Ú%FeishuAdapter._extract_response_field¾  s8   € ä2?×2SÑ2SÐT\×2]Ò2]Œw�x ¨Ô.Ðcgˆß26Œw�t¨Ó.Ð@¸DÐ@rM   r  c               ó(   € V ^8„  d   QhRRRRRRRR/# )	rC   r{  r
   r  rb   r  r_  rG   r   rI   )rJ   s   "rK   rL   rK  Ã  s2   € ÷ Yñ YØðYØ14ðYØFSðYà	ñYrM   c               	óˆ   € V'       d   \        R W1R7      # \        VRR4      p\        VRV4      p\        R RV RV 2VR7      # )F)rd  r  Úraw_responser  ri  rn  r�  z] )r   rÎ   )r|   r{  r  r  r  rn  s   &&$$  rK   r  Ú$FeishuAdapter._response_error_resultÃ  sL   € ÷ Ü e°>ÔYÐYÜ�x ¨Ó3ˆÜ�h  Ó7ˆÜ %°°4°&¸¸3¸%Ð/@ÈxÔXÐXrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r{  r
   r  rb   rG   r   rI   )rJ   s   "rK   rL   rK  Ì  s!   € ÷ 
ñ 
¨cð 
ÀCð 
ÈJñ 
rM   c                	ó�   € V P                  V4      '       g   V P                  WR 7      # \        RV P                  VR4      VR7      # ))r  Tr€  )rd  r€  rÙ  )rv  r  r   r  )r|   r{  r  s   &&&rK   rw  Ú#FeishuAdapter._finalize_send_resultÌ  sI   € Ø×'Ñ'¨×1Ò1Ø×.Ñ.¨xÐ.ÓYÐYÜØ T×%AÑ%AÀ(ÈLÓ%YØ!ô
ð 	
rM   c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  Õ  s   € ÷ 2ñ 2¨4ñ 2rM   c           	   ƒ  	ó&  "  € \        \        4       FG  p V P                  R 8X  d   V P                  4       G Rj  x€L
  MV P	                  4       G Rj  x€L
   R# 	  R#  L$ L  \
         d¡   pRT n        T P                  4        RT n        T P                  4       G Rj  x€L 
  T\        ^,
          8¼  d   h ^T,          p\        P                  RT^,           \        Y24       \        P                  ! T4      G Rj  x€L 
   Rp?K÷  Rp?ii ; i5i)r   NFz:[Feishu] Connect attempt %d/%d failed; retrying in %ds: %s)ÚrangeÚ_FEISHU_CONNECT_ATTEMPTSr  Ú_connect_websocketÚ_connect_webhookr«  r¨  r0  r[  r1  r¬  r¶  rQ   rq  )r|   ÚattemptrW   Úwait_secondss   &   rK   r   Ú!FeishuAdapter._connect_with_retryÕ  sÛ   é € ÜÔ5Ö6ˆGð2Ø×(Ñ(¨KÔ7Ø×1Ñ1Ó3×3Ñ3à×/Ñ/Ó1×1Ð1Úó 7ñ 4á1øäô 2Ø %�”Ø×6Ñ6Ô8Ø"&�”Ø×/Ñ/Ó1×1Ñ1ØÔ6¸Õ:Ô:ØØ  G�|�Ü—‘ØPØ˜a•KÔ!9¸<ôô —m’m LÓ1×1×1ûð2üsi   ‚D–$A#ºA»A#ÁA!ÁA#ÁDÁA#Á!A#Á#DÁ.1D	ÂB"Â AD	Ã=D Ã>D	ÄDÄ	DÄDc               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  ë  s   € ÷ '1ñ '1°4ñ '1rM   c              ƒ  óè  "  € \        V P                  4      ;rRpV P                  '       dÕ   V P                  pVf   R#  \        P
                  ! V4      G Rj  x€L
  T P                  '       d   T P                  f   R# YCJd.   \        P                  RT4       TpT P                  RRRRR7       \        P                  ! T4      G Rj  x€L
  T P                  '       g   R#  T P                  4       G Rj  x€L
  TpKæ  R#  L©  \        P                   d    h \         d     LÉi ; i L_ L4  \         d6   p\        P                  RT4       \        T^,          R4      p Rp?EKO  Rp?ii ; i5i)	zûRestart the WS client thread if it dies while the adapter is up.

``lark_oapi.start()`` only returns on fatal errors; without this watcher a dead thread
left the profile silently deaf until a gateway restart. Rebuild with capped backoff.

See #73779.
NzI[Feishu] WebSocket client thread exited unexpectedly; restarting in %.0fsÚws_link_lostÚretryingz&Feishu websocket link lost; rebuilding©Úplatform_stateÚ
error_codeÚerror_messagez0[Feishu] WebSocket restart failed (retrying): %sg      N@)r£   r]  r¨  r[  rQ   rH  rI  r«  rZ  r¬  r  Ú_write_runtime_status_saferq  râ  r¶  Úmin)r|   ÚbackoffÚinitial_backoffÚ	last_deadrL  rW   s   &     rK   r"  Ú)FeishuAdapter._supervise_websocket_threadë  sB  é € ô %*¨$×*BÑ*BÓ$CÐCˆØ.2ˆ	Ø�m�mˆmØŸ™ˆIØÒ ÙðÜ—n’n YÓ/×/Ð/ð —=—=�= D§O¡OÒ$;ÙØÓ)Ü—‘ÐhÐjqÔrØ%�	à×/Ñ/Ø"°:È$Ø"Jð 0ô ô —-’- Ó(×(Ð(Ø—=—=�=Ùð1Ø×-Ñ-Ó/×/Ð/Ø)’ñ5 ñ
 0øÜ×)Ñ)ô ØÜô Ùðúñ )ñ 0øäô 1Ü—‘ÐQÐSVÔWÜ˜g¨�k¨4Ó0—ûð1üs›   ‚*E2­E2Á D ÁDÁD ÁE2Á0AE2ÃD+ÃE2Ã"E2Ã%D/ Ã8D-Ã9D/ Ã?E2ÄD ÄD(Ä$D(Ä%E2Ä'D(Ä(E2Ä-D/ Ä/E/Ä:)E*Å#E2Å*E/Å/E2c               ó    € V ^8„  d   QhRRRR/# ©rC   r¼  r
   rG   rI  rI   )rJ   s   "rK   rL   rK    s   € ÷ #ñ # Sð #¨Tñ #rM   c                ór   € V P                   '       d%   V P                  VJ d   V P                  4        R# R# R# )zfWS thread reports its link is up (SDK receive loop scheduled); re-stamp ``connected`` after a rebuild.N)r¨  rZ  r#  ©r|   r¼  s   &&rK   rØ  ÚFeishuAdapter._ws_link_up  s)   € à�=�=ˆ=˜TŸ_™_°	Ó9Ø× Ñ Ö"ñ :‰=rM   c               ó    € V ^8„  d   QhRRRR/# rö  rI   )rJ   s   "rK   rL   rK    s   € ÷ ñ ¨3ð °4ñ rM   c                ó|   € V P                   '       d*   V P                  VJ d   V P                  RRRRR7       R# R# R# )zbWS thread reports the SDK's own reconnect ladder started; ``_ws_link_up`` re-stamps ``connected``.ré  rê  Nz(Feishu websocket link lost; reconnectingrë  )r¨  rZ  rï  rø  s   &&rK   rÒ  ÚFeishuAdapter._ws_link_retrying  s:   € à�=�=ˆ=˜TŸ_™_°	Ó9Ø×+Ñ+Ø¨zÀdØHð ,ö ñ :‰=rM   c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  !  s   € ÷ }ñ }¨$ñ }rM   c           	   ƒ  	ó2  "  € \         '       g   \        R 4      hV P                  4       pV P                  pVe   VP	                  4       '       d   \        R4      hV P                  4       G Rj  x€L
  \        V P                  V P                  \        P                  P                  V P                  VR.R7      V n        VP                  V P                  4       \         P"                  ! 4       P$                  \&        V P                  V 4      V n        R#  L¦5i)z4websockets not installed; websocket mode unavailableNzadapter loop is not readyÚchannel)r—   r˜   r-  Úevent_handlerr,  Úextra_ua_tags)ÚFEISHU_WEBSOCKET_AVAILABLErÞ  Ú_prepare_clientrê  rÐ  ro  rû  r  r  r\   r.  ÚINFOr`  rZ  r  rþ  r  r  rý   rö  r[  )r|   r,  r†  s   &  rK   râ  Ú FeishuAdapter._connect_websocket!  sÝ   é € ß)Ó)ÜÐUÓVÐVØ×%Ñ%Ó'ˆØ�z‰zˆØŠ<˜4Ÿ>™>×+Ò+ÜÐ:Ó;Ð;Ø×(Ñ(Ó*×*Ð*Ü(Ø—<‘<Ø×'Ñ'Ü—m‘m×(Ñ(Ø×-Ñ-Øà$˜+ô
ˆŒð ×.Ñ.Ø×"Ñ"Ó$¤k×&>Ò&>Ó&@×&DÑ&DÔFdÐfj×fuÑfuÐw{ó}ˆŽñ! 	+ùs   ‚ADÁDÁ.DÁ/B'Dc               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  ;  s   € ÷ zñ z¨ñ zrM   c              ƒ  	ó¢  "  € \         '       g   \        R 4      hV P                  4        V P                  4       G Rj  x€L
  \        P
                  ! \        R7      pVP                  P                  V P                  V P                  4       ^ RIHp V! WV P                  V P                  V P                  4      G Rj  x€L
 V n        R#  L� L5i)z/aiohttp not installed; webhook mode unavailableN)Úclient_max_size)Úbind_listener)ÚFEISHU_WEBHOOK_AVAILABLErÞ  r	  ro  r   ÚApplicationr-  ÚrouterÚadd_postr,  r9  Ú gateway.platforms.shared_ingressr		  Ú_webhook_hostÚ_webhook_portr^  )r|   rË   r		  s   &  rK   rã  ÚFeishuAdapter._connect_webhook;  sž   é € ß'Ó'ÜÐPÓQÐQØ×ÑÔØ×(Ñ(Ó*×*Ð*ô �oŠoÔ.LÔMˆØ�
‰
×Ñ˜D×.Ñ.°×0LÑ0LÔMåBÙ%2°4¸d×>PÑ>PÐRV×RdÑRdÐfj×fxÑfxÓ%y×yˆÖñ 	+ñ  zùs"   ‚;C½C¾BCÂ?CÃ CÃCc               ó   € V ^8„  d   QhRR/# r„  rI   )rJ   s   "rK   rL   rK  H  s   € ÷ ñ  ñ rM   c                ó¸   € \        V P                  4      pV P                  V4      V n        V P	                  4       V n        V P
                  f   \        R4      hV# )z[Build the lark client + event dispatcher for this adapter's domain; returns the SDK domain.z$failed to build Feishu event handler)r(  r%  r0  rT  rñ  r`  rÞ  ©r|   r,  s   & rK   r	  ÚFeishuAdapter._prepare_clientH  sR   € ä˜T×.Ñ.Ó/ˆØ×.Ñ.¨vÓ6ˆŒØ"×7Ñ7Ó9ˆÔØ×ÑÒ&ÜÐEÓFÐFØˆrM   c               ó    € V ^8„  d   QhRRRR/# )rC   r,  r
   rG   rI   )rJ   s   "rK   rL   rK  Q  s   € ÷ Jñ J¨ð J°ñ JrM   c                	óD   € \        V P                  V P                  V4      # r{   )r0  r  r  r	  s   &&rK   r0  Ú FeishuAdapter._build_lark_clientQ  s   € Ü! $§,¡,°×0@Ñ0@À&ÓIÐIrM   c               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# r¾  rI   )rJ   s   "rK   rL   rK  T  s<   € ÷ -?ñ -?Øð-?Ø),ð-?Ø7:ð-?ØFSð-?Ø_wð-?à	ñ-?rM   c          
   ƒ  	ót  a aaaa"  € R pTpR VVVVV 3R llp\        \        4       FÌ  p	 V! V4      G R j  x€L
 p
V'       d¯   S P                  V
4      '       g˜   \        V
RR 4      pV\        9   d€   S;'       g    / P                  R4      '       d6   \        P                  RTS;'       g    / P                  R4      V4       V
u # \        P                  RW{S4       R pV! R 4      G R j  x€L
 p
V
u # 	  T;'       g    \        R	4      h LÕ L!  \         dš   pTpSR8X  d&   \        P                  \        T4      4      '       d   h T	\        ^,
          8¼  d   h ^T	,          p\        P                  RT	^,           \        SYÜ4       \        P                  ! T4      G R j  x€L 
   R p?EKˆ  R p?ii ; i5i)
Nc               ó    € V ^8„  d   QhRRRR/# )rC   Úreply_targetr_  rG   r
   rI   )rJ   s   "rK   rL   Ú;FeishuAdapter._feishu_send_with_retry.<locals>.__annotate__Z  s   € ÷ 	ñ 	 ]ð 	°sñ 	rM   c              “  óL   <"  € SP                  SSSV SR 7      G Rj  x€L
 #  L5i)ri  N)rÌ  )r	  rö  r“   r  r\  r|   s   &€€€€€rK   Ú_rawÚ3FeishuAdapter._feishu_send_with_retry.<locals>._rawZ  s4   øé € Ø×/Ñ/Ø¨(¸GÈlÐemð 0ó ÷ ð ñ ùs   ƒ$�"ž$r  r2  u‹   [Feishu] Reply to %s failed in thread %s (code %s â€” message withdrawn/missing); skipping top-level fallback to avoid creating a new topicuk   [Feishu] Reply to %s failed (code %s â€” message withdrawn/missing); falling back to new message in chat %sru  zC[Feishu] Send attempt %d/%d failed for chat %s; retrying in %ds: %szFeishu send failed)rà  Ú_FEISHU_SEND_ATTEMPTSrv  rÎ   Ú_FEISHU_REPLY_FALLBACK_CODESrñ   r¬  r¶  r«  ru  rs  rb   rQ   rq  rÞ  )r|   rö  r  r\  r^  r“   Ú
last_errorÚactive_reply_tor	  rä  r{  r  rW   rå  s   fddd$d        rK   rj  Ú%FeishuAdapter._feishu_send_with_retryT  s†  üé € ð +/ˆ
Ø"ˆ÷	ô 	ô
 Ô2Ö3ˆGð 2Ù!% oÓ!6×6�ç"¨4×+CÑ+CÀH×+MÒ+MÜ" 8¨V°TÓ:�DØÔ;Ô;Ø$ŸN˜N¨×/Ñ/°×<Ò<Ü"ŸN™Nð!\à /°(·.°.¸b×1EÑ1EÀkÓ1RÐTXôð
 $,šOÜŸ™ðEà+°7ôð
 +/˜Ù)-¨d«×#3˜Ø’ñ+ 4ðD ×>Ð>œLÐ)=Ó>Ð>ñA 7ñ$ $4øäô 2Ø �
Ø˜vÔ%Ô*B×*IÑ*IÌ#ÈcË(×*SÒ*SØØÔ3°aÕ7Ô7ØØ  G�|�Ü—‘ØYØ˜a•KÔ!6¸Àôô —m’m LÓ1×1×1Ð1ûð2üs�   ‡$F8¬D·D¸DÁDÁ DÁ<DÂDÂ.DÃF8Ã	$DÃ-DÃ.DÃ3F8ÄF8ÄDÄDÄF5ÄBF0Æ#F&Æ$F0Æ)F8Æ0F5Æ5F8c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rK  ƒ  s   € ÷ +ñ +¨ñ +rM   c              ƒ  	óò   "  € V P                   '       g   R #  \        \        V P                   4       R V n         R #   \         d#   p\        P                  RTRR7        R p?L1R p?ii ; i  R T n         i ; i5i)Nz'[Feishu] Failed to release app lock: %sTr©  )rr  r&   r  r«  r¬  r¶  )r|   rW   s   & rK   r'  ÚFeishuAdapter._release_app_lockƒ  si   é € Ø×&×&Ð&Ùð	+ÜÔ 6¸×8OÑ8OÔPð '+ˆDÖ#øô ô 	ZÜ�N‰NÐDÀcÐTXˆN×YÑYûð	Zûð '+ˆDÕ#üs7   ‚A7˜; ²	A7»A(ÁA#ÁA+ Á#A(Á(A+ Á+	A4Á4A7c               ó    € V ^8„  d   QhRRRR/# )rC   rö  rb   rG   r
   rI   )rJ   s   "rK   rL   rK  �  s   € ÷ ;ñ ;¨ð ;°ñ ;rM   c                	ó$   € \        \        V R 7      # )©rö  )rC  ÚGetChatRequestr+	  s   &rK   rD  Ú%FeishuAdapter._build_get_chat_requestŽ  s   € äœ.°'Ô:Ð:rM   c               ó    € V ^8„  d   QhRRRR/# ©rC   r€  rb   rG   r
   rI   )rJ   s   "rK   rL   rK  “  s   € ÷ Dñ D¨sð D°sñ DrM   c                	ó$   € \        \        V R 7      # ©©r€  )rC  ÚGetMessageRequestr2	  s   &rK   r  Ú(FeishuAdapter._build_get_message_request’  s   € äÔ+¸
ÔCÐCrM   c               ó(   € V ^8„  d   QhRRRRRRRR/# rª  rI   )rJ   s   "rK   rL   rK  —  s0   € ÷ sñ s°sð sÀcð sÐZ]ð sÐbeñ srM   c                	ó&   € \        \        WVR 7      # ))r€  rc   r   )rC  ÚGetMessageResourceRequestr¬  s   $$$rK   r­  Ú-FeishuAdapter._build_message_resource_request–  s   € äÔ3À
ÐdqÔrÐrrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r—   rb   r  rG   r
   rI   )rJ   s   "rK   rL   rK  ›  s&   € ÷ Kñ K°#ð K¸Sð KÀSñ KrM   c                	ó$   € \        \        WR 7      # )ri  )rC  ÚGetApplicationRequestri  s   $$rK   rl  Ú,FeishuAdapter._build_get_application_requestš  s   € äÔ/¸ÔJÐJrM   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	rC   rO   rb   r  rÁ  rr   rÂ  rG   r
   rI   )rJ   s   "rK   rL   rK  Ÿ  s2   € ÷ 
ñ 
¨cð 
¸Sð 
ÐSWð 
Ðehð 
Ðmpñ 
rM   c                	ó&   € \        \        WW#R 7      # ))rO   r  rÁ  r(  )rC  ÚReplyMessageRequestBodyrÀ  s   $$$$rK   rÅ  Ú'FeishuAdapter._build_reply_message_bodyž  s   € äÜ#ØÀô
ð 	
rM   c               ó$   € V ^8„  d   QhRRRRRR/# ©rC   r€  rb   r‡  r
   rG   rI   )rJ   s   "rK   rL   rK  ¦  s&   € ÷ añ a°ð aÀCð aÈCñ arM   c                	ó$   € \        \        WR 7      # ©r†  )rC  ÚReplyMessageRequestr†  s   &&rK   rÆ  Ú*FeishuAdapter._build_reply_message_request¥  s   € äÔ-¸*Ô`Ð`rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r  rb   rO   rG   r
   rI   )rJ   s   "rK   rL   rK  ª  s&   € ÷ Xñ X°ð X¸cð XÀcñ XrM   c                	ó$   € \        \        WR 7      # )r…  )rC  ÚUpdateMessageRequestBodyr…  s   $$rK   rˆ  Ú(FeishuAdapter._build_update_message_body©  s   € äÔ2¸XÔWÐWrM   c               ó$   € V ^8„  d   QhRRRRRR/# rB	  rI   )rJ   s   "rK   rL   rK  ®  s&   € ÷ bñ b°#ð bÀSð bÈSñ brM   c                	ó$   € \        \        WR 7      # rD	  )rC  ÚUpdateMessageRequestr†  s   &&rK   r‰  Ú+FeishuAdapter._build_update_message_request­  s   € äÔ.¸:ÔaÐarM   c               ó    € V ^8„  d   QhRRRR/# r/	  rI   )rJ   s   "rK   rL   rK  ²  s   € ÷ Gñ G°#ð G¸#ñ GrM   c                	ó$   € \        \        V R 7      # r1	  )rC  ÚDeleteMessageRequestr2	  s   &rK   r’  Ú+FeishuAdapter._build_delete_message_request±  s   € äÔ.¸:ÔFÐFrM   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )rC   rÄ  rb   r  rO   rÂ  rG   r
   rI   )rJ   s   "rK   rL   rK  ¶  s1   € ÷ 
ñ 
°#ð 
Àð 
Èsð 
Ð`cð 
Ðhkñ 
rM   c                	ó&   € \        \        WW#R 7      # ))rÄ  r  rO   r(  )rC  ÚCreateMessageRequestBodyrÃ  s   $$$$rK   rÈ  Ú(FeishuAdapter._build_create_message_bodyµ  s   € äÜ$°ÐX_ô
ð 	
rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rË  rb   r‡  r
   rG   rI   )rJ   s   "rK   rL   rK  ¼  s'   € ÷ lñ l°sð lÈ#ð lÐRUñ lrM   c                	ó$   € \        \        WR 7      # )©rË  r‡  )rC  ÚCreateMessageRequestrY	  s   &&rK   rÉ  Ú+FeishuAdapter._build_create_message_request»  s   € äÔ.ÀÔkÐkrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   r  rb   r©  r
   rG   rI   )rJ   s   "rK   rL   rK  À  s&   € ÷ Vñ V°ð V¸Cð VÀCñ VrM   c                	ó$   € \        \        WR 7      # )r
  )rC  ÚCreateImageRequestBodyr
  s   $$rK   r  Ú&FeishuAdapter._build_image_upload_body¿  s   € äÔ0¸ZÔUÐUrM   c               ó    € V ^8„  d   QhRRRR/# ©rC   r‡  r
   rG   rI   )rJ   s   "rK   rL   rK  Ä  s   € ÷ Iñ I°#ð I¸#ñ IrM   c                	ó$   € \        \        V R 7      # ©©r‡  )rC  ÚCreateImageRequestrd	  s   &rK   r  Ú)FeishuAdapter._build_image_upload_requestÃ  s   € äÔ,¸<ÔHÐHrM   r¨  c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	rC   r§  rb   re   rf   r
   r¨  rF   rG   rI   )rJ   s   "rK   rL   rK  È  s1   € ÷ ;ñ ;¨cð ;¸cð ;Èð ;ÐX[ð ;Ðdgñ ;rM   c                	ór   € \         f   \        WW#R7      # RV RVRV/pV^ 8”  d   W4R&   \        \         3/ VB # )Nr¦  r§  re   rf   r¨  )ÚCreateFileRequestBodyr	   rC  )r§  re   rf   r¨  rA  s   $$$$ rK   rª  Ú%FeishuAdapter._build_file_upload_bodyÇ  sJ   € ä Ò(Ü"¨YÐRVÔjÐjØ"-¨y¸+ÀyÐRXÐZ^Ð!_ˆØ�aŒ<Ø!)�:ÑÜÔ/Ñ:°6Ñ:Ð:rM   c               ó    € V ^8„  d   QhRRRR/# ra	  rI   )rJ   s   "rK   rL   rK  Ñ  s   € ÷ Hñ H°ð H¸ñ HrM   c                	ó$   € \        \        V R 7      # rc	  )rC  ÚCreateFileRequestrd	  s   &rK   r«  Ú(FeishuAdapter._build_file_upload_requestÐ  s   € äÔ+¸,ÔGÐGrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rí  rb   r  r?   rG   rI   )rJ   s   "rK   rL   rK  Ô  s"   € ÷ 7ñ 7°Cð 7ÀNð 7ÐWZñ 7rM   c               	óØ   € \         P                  ! \        V4      4      pVP                  R / 4      P                  R. 4      pVP	                  V.4       \         P
                  ! VRR7      # r:  )r?  rá  rB  rž  rM  r@  )r|   rí  r  r\  rO   s   &$$  rK   r´  Ú'FeishuAdapter._build_media_post_payloadÔ  sT   € Ü—*’*Ô9¸'ÓBÓCˆØ×$Ñ$ W¨bÓ1×<Ñ<¸YÈÓKˆØ�‰˜	�{Ô#Ü�zŠz˜'°Ô6Ð6rM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   rñ  rb   r¤  rG   r[  rI   )rJ   s   "rK   rL   rK  Û  s#   € ÷ 	0ñ 	0°Sð 	0ÐRUð 	0ÐZiñ 	0rM   c                	óÀ   € \        V 4      P                  P                  4       pV\        9   d   R# V\        9   d   R# V\
        9   d   \
        V,          R3# \        R3# )r¥  rf   )r¥  rª  )Úmp4r«  )r   r  r±  ró  Ú_FEISHU_MEDIA_UPLOAD_EXTENSIONSÚ_FEISHU_DOC_UPLOAD_TYPESÚ_FEISHU_FILE_UPLOAD_TYPE)rñ  r¤  rú  s   $$ rK   r©  Ú,FeishuAdapter._resolve_outbound_file_routingÚ  s^   € ô �9‹o×$Ñ$×*Ñ*Ó,ˆØÔ0Ô0Ø"Ð"ØÔ1Ô1Ø!Ð!ØÔ*Ô*Ü+¨CÕ0°&Ð8Ð8Ü'¨Ð/Ð/rM   )2rÊ  rÉ  rr  r|  rz  rc  r§  ri  rp  ro  rT  rd  re  rc  rË  r`  rê  rw  rq  rl  rj  rk  rm  ry  rx  r  rv  ru  rt  r¨  rX  rY  rW  ra  rb  rf  rR  rs  r~  r}  rE  rh  rg  r^  r_  rZ  r[  r]  r\  rè  )NN)rd   rd   N)NNN)NNNNr{   rÄ  )Èrh   ri   rj   rk   r¸   rF  rl   Úsupports_code_blocksÚsplits_long_messagesÚserial_receive_looprq  rI  Ú_SPLIT_THRESHOLDr�  ÚstaticmethodrP  rS  rñ  rþ  r  r  r£  r6  r2  r.  r/  r0  r1  r|  rŽ  r”  Ú
_EA_HEADERÚ_EA_CMD_BUDGETÚpropertyr™  r¡  r¥  r²  rµ  r³  rÍ  rÑ  rÚ  rÞ  ré  rû  r   r  r$  r)  r/  r8  rI  ro  rá  rT  rV  rX  rß  rŠ  rç  ré  rë  rí  rž  rï  rð  rÒ  rå  rS  rW  rÚ  rÁ  rî  rÂ  rÃ  r  rõ  rú  r»  r#  rÄ  r  rH  r:  rV  r\  rk  ru  r  r‡  r‘  r•  r9  r€  rª  r³  rÂ  rÊ  r´  rÎ  rÖ  rÛ  rÏ  r.  r7  rì  rþ  r  r  r9  r5  r4  r+  rÈ  r²  rW  rÕ  ro  rs  rx  r¨  r|  r—  r}  r  r¯  r�  r�  r¶  r·  r¸  r¹  rÃ  r§  rÁ  rF  r8  r6  rë  rñ  r  r  r©  r  rº  rÔ  r~  rE  r  r8  r<  r:  rV  rW  rw  ro  r€  r3  r}  rŠ  rt  r   rõ  r  r¬  rÌ  rv  r  r  rw  r   r"  rØ  rÒ  râ  rã  r	  r0  rj  r'  rD  r  r­  rl  rÅ  rÆ  rˆ  r‰  r’  rÈ  rÉ  r  r  rª  r«  r´  r©  rm   Ú__classcell__)r�  s   @rK   rE  rE    s^  ø‡ Ù"à"&Ð˜4Ó&àÐØÐØÐØÐØ"Ð˜Ó"ØÐ÷1&ð 1&ðf ôE
ó ðE
õN\õ
õ&ò&Sõ*ð 2°E÷ 2õh-õ:+dõZõ,õ
#õ&÷2=ð 2=ðh=Ðbg÷ =õ8ð( €JØ€Nð ôBó ðBð ôEó ðEð
 ôIó ðIð
  °	Ð;LÈhÐXhÐjpÐrxÐyÐõ=õ(ð$ ôuó ðu÷=ð =ð$ ômó ðmð ôwó ðwð ô(ó ð(÷ð ÷2
ð 
÷
ð 
÷=ð =÷@ð ÷
ó 
÷ 
ó 
õ,õ8õ
Jõõ,36õj
õ.mõ
1õ
9õ=õ@õ:õ0õxõhõ
Rõ&%ð, ôZó ðZõ
õ?ð ÷
ó ð
õ[õ,kõ,põ.ð* [ØOQð [Øbd÷ [ðDLØMOðLØ`b÷Lõ('
õR
õ
õ<@õ0õ-õoõõPõ	 õ
*õKõNõ:÷
Að Að:7Øjo÷:7õx6õJõQð ô~ó ð~õ.õ.cõ
ð
 ô(ó ð(õ6õ>õOð* ôFó ðFð ôó ðð ôó ð÷6ð 6õL;ð` 	 Ð!4Ø$Ð&>Ø%Ð'>Ø'Ð)DØÐ8Ø%Ð'@Ø#Ð%@ðÐõõ"ð6 ô
ó ð
õ&-õPað ô;ó ð;õ9õ6õ
õ
jõ2'ð( ôó ðõ õ õ Z÷÷.1ðh ö&ó ð&ð öló ðlð
 ö:ó ð:ð ö%ó ð%ð öxó ðxð ö7ó ð7ð öó ðð ö:ó ð:ð ö=ó ð=ð	[Èe÷ 	[ñ 	[÷	ð!Ð^c÷ !ñ !ñFDÐ\`÷ Dñ D÷
÷$ñ>0ØVZ÷0ñ 0ð ö?ó ð?ð öNó ðN÷!ðH $)Ð ÷!÷"%òMÐX]÷ Mò M÷,	<÷÷0÷m÷3e÷lC÷<
r÷÷&ñIÈ5÷ Iñ Ið öó ðñ*:=à!%ñ:=àBFñ:=áek÷:=ñ :=÷x
÷÷ Tð0 öPó ðPð öAó ðAñYØVZ÷Yñ Y÷
÷2÷,'1÷R#÷
÷}÷4z÷÷J÷-?÷^+ð ö;ó ð;ð öDó ðDð ösó ðsð öKó ðKð ö
ó ð
ð öaó ðað öXó ðXð öbó ðbð öGó ðGð ö
ó ð
ð
 öló ðlð öVó ðVð öIó ðIð ñ;Ð^_÷ ;ð ;ó ð;ð öHó ðH÷7ð ö	0ó ÷	0rM   rE  c               ó    € V ^8„  d   QhRRRR/# ©rC   r,  rb   rG   rI   )rJ   s   "rK   rL   rL   ê  s   € ÷ Pñ P˜sð P sñ PrM   c                óD   € \         P                  V \         R ,          4      # ©r[   )Ú_ONBOARD_ACCOUNTS_URLSrñ   ©r,  s   &rK   Ú_accounts_base_urlrˆ	  ê  s   € Ü!×%Ñ% fÔ.DÀXÕ.NÓOÐOrM   c               ó    € V ^8„  d   QhRRRR/# rƒ	  rI   )rJ   s   "rK   rL   rL   î  s   € ÷ Hñ H 3ð H¨3ñ HrM   c                óD   € \         P                  V \         R ,          4      # r…	  )Ú_ONBOARD_OPEN_URLSrñ   r‡	  s   &rK   Ú_onboard_open_base_urlrŒ	  î  s   € Ü×!Ñ! &Ô*<¸XÕ*FÓGÐGrM   c               ó$   € V ^8„  d   QhRRRRRR/# )rC   Úbase_urlrb   rV   r?   rG   r”   rI   )rJ   s   "rK   rL   rL   ò  s!   € ÷ ñ  ð ¨Nð ¸tñ rM   c                ó,  € \        V  \         2\        V4      P                  R4      RR/R7      p \	        V\
        R7      ;_uu_ 4       p\        P                  ! VP                  4       P                  R4      4      uuRRR4       #   + '       g   i     R# ; i  \         dl   pTP                  4       pT'       dN    \        P                  ! TP                  R4      4      u Rp?#   \        \        P                  3 d    TRhi ; ih Rp?ii ; i)z^POST form data to the registration endpoint; parse JSON even on 4xx (poll's pending is a 400).râ  rù  z!application/x-www-form-urlencoded©rB  rø  r;  N)r   Ú_REGISTRATION_PATHr   r3  r   Ú_ONBOARD_REQUEST_TIMEOUT_Sr?  rá  rË  r/  r   rU   râ  )rŽ	  rV   Úreqr  rW   r6  s   &&    rK   Ú_post_registrationr”	  ò  sÖ   € ä
Øˆ*Ô'Ð(Ð)´	¸$³×0FÑ0FÀwÓ0OØÐ!DÐEô€Cð
Ü�SÔ"<×=Õ=ÀÜ—:’:˜dŸi™i›k×0Ñ0°Ó9Ó:÷ >×=×=Ó=ûäô Ø—X‘X“Zˆ
ßð$Ü—z’z *×"3Ñ"3°GÓ"<Ó=Õ=øÜ¤× 4Ñ 4Ð5ô $Ø˜tÐ#ð$úàûðúsM   ²B Á3B	Á>
B Â	B	ÂB ÂB ÂDÂ(DÃ$C+Ã%DÃ+D
Ä
DÄDc               ó    € V ^8„  d   QhRRRR/# )rC   r,  rb   rG   rI  rI   )rJ   s   "rK   rL   rL     s   € ÷ 
ñ 
˜sð 
°$ñ 
rM   c                ó”   € \        \        V 4      RR/4      pVP                  R4      ;'       g    . pRV9  d   \        RV 24      hR# )zSRaise RuntimeError unless the registration environment supports client_secret auth.r:  ÚinitÚsupported_auth_methodsÚclient_secretzWFeishu / Lark registration environment does not support client_secret auth. Supported: N©r”	  rˆ	  rñ   rÞ  )r,  ÚresÚmethodss   &  rK   Ú_init_registrationr�	    sY   € ä
Ô/°Ó7¸(ÀFÐ9KÓ
L€CØ�g‰gÐ.Ó/×5Ð5°2€GØ˜gÔ%ÜðØ!˜ð$ó
ð 	
ñ &rM   c               ó    € V ^8„  d   QhRRRR/# )rC   r,  rb   rG   r”   rI   )rJ   s   "rK   rL   rL     s   € ÷ ñ  ð °4ñ rM   c                óv  € \        \        V 4      RRRRRRRR/4      pVP                  R	4      pV'       g   \        R
4      hVP                  RR4      pTRV9   d   RMRR,           ,          pR	TRTRVP                  RR4      RVP                  R4      ;'       g    ^RVP                  R4      ;'       g    R/# )zXStart the device-code flow. Returns device_code, qr_url, user_code, interval, expire_in.r:  ÚbeginÚ	archetypeÚPersonalAgentÚauth_methodr™	  Úrequest_user_inforq   Údevice_codez7Feishu / Lark registration did not return a device_codeÚverification_uri_completerd   r  Ú&zfrom=hermes&tp=hermesÚqr_urlÚ	user_codeÚintervalÚ	expire_inéX  rš	  )r,  r›	  r¥	  r¨	  s   &   rK   Ú_begin_registrationr­	    sÃ   € ä
Ô/°Ó7Ø�'˜;¨¸ÈÐYlÐnwð:ó €Cð —'‘'˜-Ó(€KßÜÐTÓUÐUØ�W‰WÐ0°"Ó5€FØ
�c˜V”m‰s¨Ð0GÕGÕG€Fà�{ H¨f°kÀ3Ç7Á7È;ÐXZÓC[Ø�C—G‘G˜JÓ'×,Ð,¨1¨k¸3¿7¹7À;Ó;O×;VÐ;VÐSVðð rM   r,  c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	rC   r¥	  rb   rª	  rF   r«	  r,  rG   úOptional[dict]rI   )rJ   s   "rK   rL   rL      s1   € ÷ -ñ - sð -°cð -Àcð -ÐSVð -Ðftñ -rM   c           
     óø  € \         P                  ! 4       V,           pTpRp^ p\         P                  ! 4       V8  EdX    RRRV RR/p\        \        V4      V4      p	T^,          pT^8X  d   \        RRR	R
7       MT^,          ^ 8X  d   \        RRR	R
7       T	P                  R4      ;'       g    / p
T
P                  R4      R8X  d   T'       g   RpR	pT	P                  R4      '       dP   T	P                  R4      '       d9   T^ 8”  d   \        4        RT	R,          RT	R,          RTRT
P                  R4      /# T	P                  RR4      pTR9   d*   T^ 8”  d   \        4        \        P                  RT4       R# \         P                  ! T4       EKr  V^ 8”  d   \        4        \        P                  RV4       R#   \        \
        \        P                  3 d    \         P                  ! T4        EKÕ  i ; i)uW   Poll until scan (â†’ {app_id, app_secret, domain, open_id}), or None on denial/timeout.Fr:  Úpollr¥	  ÚtpÚob_appz#  Fetching configuration results...rd   T©ÚendÚflushr  Ú	user_infoÚtenant_brandr\   Ú	client_idr™	  r—   r˜   r,  rq   r  z [Feishu onboard] Registration %sNz)[Feishu onboard] Poll timed out after %ds>   Úaccess_deniedÚexpired_token)rp  Ú	monotonicr”	  rˆ	  r   rø  r?  râ  rq  Úprintrñ   r¬  r¶  )r¥	  rª	  r«	  r,  ÚdeadlineÚcurrent_domainÚdomain_switchedÚ
poll_countrV   r›	  r·	  r  s   $$$$        rK   Ú_poll_registrationrÂ	     s±  € ä�~Š~Ó )Õ+€HØ€NØ€OØ€Jä
�.Š.Ó
˜XÕ
%ð	Ø˜f m°[À$ÈÐQˆDÜ$Ô%7¸Ó%GÈÓNˆCð
 	�a�ˆ
Ø˜Œ?ÜÐ7¸RÀtÖLØ˜!�^˜qÔ Ü�#˜2 TÕ*ð —G‘G˜KÓ(×.Ð.¨Bˆ	Ø�=‰=˜Ó(¨FÔ2¿?Ø#ˆNØ"ˆOØ�7‰7�;×Ò C§G¡G¨O×$<Ò$<Ø˜AŒ~Ü”à˜#˜kÕ*¨L¸#¸oÕ:NÐPXÐZhØ˜9Ÿ=™=¨Ó3ðð ð
 —‘˜ Ó$ˆØÐ6Ô6Ø˜AŒ~Ü”Ü�N‰NÐ=¸uÔEÙÜ�
Š
�8×à�A„~ÜŒÜ
‡N�NÐ>À	ÔJÙøôE œ'¤4×#7Ñ#7Ð8ô 	Ü�JŠJ�xÔ Ûð	ús   ¿F> Æ>6G9Ç8G9c               ó    € V ^8„  d   QhRRRR/# )rC   r  rb   rG   rr   rI   )rJ   s   "rK   rL   rL   V  s   € ÷ ñ �Cð ˜Dñ rM   c                óÔ   € \         f   R#  \         P                  ! 4       pVP                  V 4       VP                  RR7       VP	                  RR7       R#   \
         d     R# i ; i)zDTry to render a QR code in the terminal. Returns True if successful.FT)Úfit)Úinvert)Ú_qrcode_modÚQRCodeÚadd_dataÚmakeÚprint_asciir«  )r  Úqrs   & rK   Ú
_render_qrrÍ	  V  s[   € äÒÙðÜ×ÒÓ!ˆØ
�‰�CÔØ
�‰�DˆÔØ
�‰˜dˆÔ#ÙøÜô Úðús   ŒA
A ÁA'Á&A'c               ó(   € V ^8„  d   QhRRRRRRRR/# ©rC   r—   rb   r˜   r,  rG   r¯	  rI   )rJ   s   "rK   rL   rL   d  s(   € ÷ 7ñ 7�cð 7 sð 7°Cð 7¸Nñ 7rM   c                óR   € \        4       '       d   \        WV4      # \        WV4      # )uÇ   Probe /open-apis/bot/v3/info â†’ {"bot_name", "bot_open_id"} (app-scoped open_id, NOT app_id) or None.

Onboarding runs before connect(), so load the SDK here instead of always falling back to HTTP.
)r  Ú_probe_bot_sdkÚ_probe_bot_http©r—   r˜   r,  s   &&&rK   Ú	probe_botrÔ	  d  s'   € ô
 ×ÒÜ˜f°&Ó9Ð9Ü˜6¨vÓ6Ð6rM   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rC   r—   rb   r˜   r,  rG   r
   rI   )rJ   s   "rK   rL   rL   n  s.   € ÷ Gñ G #ð G°3ð GÀð GÈñ GrM   c                ó,   € \        W\        V4      4      # )zPBuild a lark Client for the given credentials and domain name ("feishu"/"lark").)r0  r(  rÓ	  s   &&&rK   Ú_build_onboard_clientr×	  n  s   € ä˜f´+¸fÓ2EÓFÐFrM   c               ó    € V ^8„  d   QhRRRR/# )rC   rB  r”   rG   r¯	  rI   )rJ   s   "rK   rL   rL   s  s   € ÷ ñ ˜dð  ~ñ rM   c                ó4  € V P                  R 4      ^ 8w  d   R# V P                  R4      ;'       g,    V P                  R/ 4      P                  R4      ;'       g    / pRVP                  R4      ;'       g    VP                  R4      RVP                  R4      /# )r  NrÌ   rB  r¡   rj  rŸ   rq   r|  )rB  rÌ   s   & rK   rk  rk  s  s€   € à‡x�x�Ó˜1ÔÙØ
�(‰(�5‹/×
BÐ
B˜TŸX™X f¨bÓ1×5Ñ5°eÓ<×
BÐ
BÀ€Cà�C—G‘G˜JÓ'×>Ð>¨3¯7©7°:Ó+>Ø�s—w‘w˜yÓ)ðð rM   c               ó(   € V ^8„  d   QhRRRRRRRR/# rÏ	  rI   )rJ   s   "rK   rL   rL   ~  s(   € ÷ ñ ˜3ð ¨Cð ¸ð Àñ rM   c                ó$  €  \        WV4      P                  \        R4      4      p\        \        VRR4      RR4      pVf   R# \	        \
        P                  ! V4      4      #   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)z#Probe bot info using lark_oapi SDK.rg  rß  NrO   z%[Feishu onboard] SDK probe failed: %s)
r×	  rD   r#  rÎ   rk  r?  rá  r«  r¬  r®  )r—   r˜   r,  r  rO   rW   s   &&&   rK   rÑ	  rÑ	  ~  s|   € ðÜ$ V¸Ó@×HÑHÔI\Ð]uÓIvÓwˆÜœ' $¨¨tÓ4°iÀÓFˆØ’ˆtÐTÔ,?ÄÇ
Â
È7Ó@SÓ,TÐTøÜô Ü�‰Ð<¸cÔBÝûðús   ‚AA# ÁA# Á#BÁ.B
Â
Bc               ó(   € V ^8„  d   QhRRRRRRRR/# rÏ	  rI   )rJ   s   "rK   rL   rL   ‰  s(   € ÷ ñ ˜Cð ¨Sð ¸#ð À.ñ rM   c           	     ó˜  a€ \        V4      oRRRR/R V3R lllp V! R\        P                  ! RV RV/4      P                  R	4      R
7      pVP	                  R4      pV'       g   R# V! RRRV 2/R7      p\        V4      #   \        \        \        \        P                  3 d"   p\        P                  RT4        Rp?R# Rp?ii ; i)z@Fallback probe using raw HTTP (when lark_oapi is not installed).rB  NÚextra_headersc               ó(   € V ^8„  d   QhRRRRRRRR/# )	rC   r  rb   rB  zOptional[bytes]rÞ	  r   rG   r”   rI   )rJ   s   "rK   rL   Ú%_probe_bot_http.<locals>.__annotate__�  s*   € ÷ ;ñ ;˜ð ; oð ;ÐMeð ;Ðquñ ;rM   c               ó  <€ / T;'       g    / CR R/Cp\        \        S V  2WR7      \        R7      ;_uu_ 4       p\        P                  ! VP                  4       P                  R4      4      uuRRR4       #   + '       g   i     R# ; i)rù  r!  r�	  r;  râ  N)r   r   r’	  r?  rá  rË  r/  )r  rB  rÞ	  rø  r  rŽ	  s   &$$  €rK   Ú	_get_jsonÚ"_probe_bot_http.<locals>._get_json�  sk   ø€ ØO�m×)Ð) rÐO¨NÐ<NÑOˆÜ”W ˜z¨$¨Ð0°tÔMÔWq×rÕrÐvzÜ—:’:˜dŸi™i›k×0Ñ0°Ó9Ó:÷ s×r×rÓrús   ¼3A:Á:B	z//open-apis/auth/v3/tenant_access_token/internalr—   r˜   râ  )rB  Útenant_access_tokenrg  ÚAuthorizationzBearer )rÞ	  z&[Feishu onboard] HTTP probe failed: %s)rŒ	  r?  r@  r3  rñ   rk  r   rø  ÚKeyErrorrâ  r¬  r®  )	r—   r˜   r,  râ	  Ú	token_resÚaccess_tokenÚbot_resrW   rŽ	  s	   &&&     @rK   rÒ	  rÒ	  ‰  sÈ   ø€ ä% fÓ-€Hð;¸ð ;Ðhl÷ ;ò ;ð
ÙØ=Ü—’˜X v¨|¸ZÐHÓI×PÑPÐQXÓYô
ˆ	ð !—}‘}Ð%:Ó;ˆßÙÙÐ4À_ÐX_Ð`lÐ_mÐVnÐDoÔpˆÜ" 7Ó+Ð+øÜ”gœx¬×)=Ñ)=Ð>ô Ü�‰Ð=¸sÔCÝûðús   �A	B Á)B Â%C	Â(CÃC	Úinitial_domainÚtimeout_secondsr¬	  c               ó$   € V ^8„  d   QhRRRRRR/# ©rC   rê	  rb   rë	  rF   rG   r¯	  rI   )rJ   s   "rK   rL   rL   ¡  s"   € ÷ 	ñ 	 3ð 	ÀCð 	ÐR`ñ 	rM   c                ó®   €  \        WR7      #   \        \        \        \        P
                  3 d"   p\        P                  RT4        Rp?R# Rp?ii ; i)uª   Scan-to-create flow â†’ {app_id, app_secret, domain, open_id, bot_name, bot_open_id}.

None on expected failures (network, denied, timeout); unexpected errors propagate.
)rê	  rë	  z([Feishu onboard] Registration failed: %sN)Ú_qr_register_innerrÞ  r   rø  r?  râ  r¬  r¶  )rê	  rë	  rW   s   $$ rK   Úqr_registerrð	  ¡  sC   € ð
Ü!°ÔaÐaøÜœ(¤G¬T×-AÑ-AÐBô Ü�‰ÐAÀ3ÔGÝûðús   ‚ Ž%A³AÁAc               ó$   € V ^8„  d   QhRRRRRR/# rí	  rI   )rJ   s   "rK   rL   rL   ­  s!   € ÷ ñ ¨#ð Àð Èñ rM   c                óD  € \        RRRR7       \        V 4       \        V 4      p\        R4       \        4        VR,          p\        V4      '       d   \        RV 24       M'\        RV R	24       \        R
\	        R4       R24       \        4        \        VR,          VR,          \        VR,          V4      V R7      pV'       g   R# \        VR,          VR,          VR,          4      ;'       g    / pVP                  R4      VR&   VP                  R4      VR&   V# )uI   Run init â†’ begin â†’ poll â†’ probe. Raises on network/protocol errors.z   Connecting to Feishu / Lark...rd   Tr´	  z done.r¨	  z8
  Scan the QR code above, or open this URL directly:
  z3  Open this URL in Feishu / Lark on your phone:

  r  z)  Tip: from the Hermes environment, run: Ú	messagingz. to display a scannable QR code here next timer¥	  rª	  r«	  )r¥	  rª	  r«	  r,  Nr—   r˜   r,  r¡   rŸ   )	r½	  r�	  r­	  rÍ	  r   rÂ	  rð  rÔ	  rñ   )rê	  rë	  r 	  r¨	  re  Úbot_infos   $$    rK   rï	  rï	  ­  s  € ä	Ð
,°"¸DÕAÜ�~Ô&Ü Ó/€EÜ	ˆ(„OÜ	„GØ�8�_€FÜ�&×ÒÜÐJÈ6È(ÐSÕTäÐEÀfÀXÈRÐPÔQÜÐ9Ü˜kÓ*Ð+ð ,>ð>ô 	?ô 
„GÜØ˜-Õ(°5¸Õ3DÜ�e˜KÕ(¨/Ó:À>ô€F÷ ÙÜ˜ Õ)¨6°,Õ+?ÀÈÕAQÓR×XÐXÐVX€HØ!Ÿ™ jÓ1€Fˆ:ÑØ$ŸL™L¨Ó7€Fˆ=ÑØ€MrM   r2  Úmedia_filesÚforce_documentc          	   ƒ  óv  "  € \         P                  ! \        4      G Rj  x€L
 '       g   \        R4      #  \	        V 4      pVP                  \        \        VRR4      4      4      Vn        V'       d   RV/MRpRpVP                  4       '       dF   VP                  WVR7      G Rj  x€L
 pVP                  '       g   \        RVP                   24      # T;'       g    .  EF   w  rš\        P                  P                  V	4      '       g   \        RV	 24      u # \        P                  P!                  V	4      ^,          P#                  4       pV\$        9   d   VP&                  pM<V\(        9   d   VP*                  pM$V\,        9   d   VP.                  pMVP0                  pV! WVR7      G Rj  x€L
 pVP                  '       d   Ké  \        R	VP                   24      u # 	  Vf   \        R
4      # RRRRRVRVP2                  /#  ELë ELf L]  \4         d   p\        RT 24      u Rp?# Rp?ii ; i5i)z]standalone_sender_fn: out-of-process delivery (cron without gateway) via a transient adapter.NzPFeishu dependencies not installed. Run `hermes setup` to install Feishu support.r%  r[   r2  r  zFeishu send failed: zMedia file not found: zFeishu media send failed: zANo deliverable text or media remained after processing MEDIA tagsrd  Tr  rö  r€  )rQ   r  r  r.   rE  r0  r(  rÎ   rT  r  r|  rd  r  rö  r  r  Úsplitextr±  Ú_MIGRATION_IMAGE_EXTSr$  Ú_MIGRATION_VIDEO_EXTSr  Ú_MIGRATION_AUDIO_EXTSrû  r   r€  r«  )Úpconfigrö  r1   r2  rõ	  rö	  r§  r“   Úlast_resultÚ
media_pathÚ	_is_voicerú  rÈ   ru  s   &&&$$$        rK   Ú_standalone_sendr 
  Ø  sò  é € ä×"Ò"¤?Ó3×3Ö3ÜÐlÓmÐmð6Ü Ó(ˆØ!×4Ñ4´[ÄÈÐR`ÐbjÓAkÓ5lÓmˆŒß/8�K Ñ+¸dˆØˆØ�=‰=�?Š?Ø '§¡¨WÈ Ó Q×QˆKØ×&×&Ð&Ü!Ð$8¸×9JÑ9JÐ8KÐ"LÓMÐMØ%0×%6Ð%6°BÓ%6Ñ!ˆJÜ—7‘7—>‘> *×-Ò-Ü!Ð$:¸:¸,Ð"GÓHÒHÜ—'‘'×"Ñ" :Ó.¨qÕ1×7Ñ7Ó9ˆCØÔ+Ô+Ø ×0Ñ0‘ØÔ-Ô-Ø ×+Ñ+‘ØÔ-Ô-Ø ×+Ñ+‘à ×.Ñ.�Ù & wÀXÔ N×NˆKØ×&×&Ò&Ü!Ð$>¸{×?PÑ?PÐ>QÐ"RÓSÒSñ &7ð ÒÜÐaÓbÐbØ˜4 ¨X°yÀ'È<ÐYd×YoÑYoÐpÐpò9 4ò Rñ Oøô ô 6ÜÐ0°°Ð4Ó5Õ5ûð6üs±   ‚H9 H¡	H9«H9·AH ÂH Â(HÂ)H Â?H ÃH9ÃH Ã =H ÄH9ÄBH Æ3HÆ4H ÇH Ç%H9Ç&H Ç6H9Ç7H È
H9ÈH ÈH ÈH6ÈH1È+H6È,H9È1H6È6H9c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rL   û  s   € ÷ t'ñ t'˜4ñ t'rM   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p
V	^ 8X  d    \        4       p
T
'       g	   T! R4       \!        V
4      pV
'       g±   V! R4       V! R4       V! RRR7      pV'       g   V! R4       R# V! RRR7      pV'       g   V! R4       R# V! RRR.^ 4      ^8X  d   RMRpRp \#        WÞV4      pV'       d(   VP%                  R4      pT! RT;'       g    R 24       M	V! R 4        R"VR#VR$VR%RRV/p
V
R",          V
R#,          ríV
P%                  R$R4      pV
P%                  R%4      V
P%                  R4      ppV! RV4       V! R&V4       V! R'V4       V'       d   R(pM6V! R)R*R+.^ 4      pV^8X  d   R,MR(pVR,8X  d   V! R-4       V! R.4       V! R/4       V! R0V4       V'       d   V! R1V 24       V! R2. ROO^ 4      pT! R3V^8X  d   R4MR54       V^8X  d8   T! R6T;'       g    R7RR7      P'                  R8R74      pV! R9V4       V! R:4       M)V! R9R74       V^ 8X  d   V! R;4       V! R<4       MV! R=4       V! R>R?R@.^ 4      pT! RAV^ 8X  d   RBMRC4       T! V^ 8X  d   RDMRE4       V! RF4       V! RGRR7      P)                  4       pV'       d   V! RHV4       V! RIV 24       MV ! RH4      '       d	   V! RJ4       V! RK4       V! RLV 24       V! RMV 24       V'       d   V! RNV 24       R# R#   \         d    T! R4        R# \         d   pT! RT 24        Rp?ELýRp?ii ; i  \         d   pT! R!T 24        Rp?ELZRp?ii ; i)Puc   Interactive setup for Feishu / Lark â€” scan-to-create or manual creds (CLI helpers lazy-imported).)Úremove_env_valueÚsave_env_value)Úprompt_choice)r¨  Úprint_headerÚ
print_infoÚprint_successÚprint_warning)Údeclines_reconfigureúFeishu / LarkzReconfigure Feishu / Lark?r�  Nz+How would you like to set up Feishu / Lark?z<Scan QR code to create a new bot automatically (recommended)z-Enter existing App ID and App Secret manuallyzFeishu / Lark setup cancelled.zQR registration failed: z8QR setup did not complete. Continuing with manual input.zGGo to https://open.feishu.cn/ (or https://open.larksuite.com/ for Lark)zCCreate an app, enable the Bot capability, and copy the credentials.zApp IDF)Úpasswordu7   Skipped â€” Feishu / Lark won't work without an App ID.z
App SecretTu;   Skipped â€” Feishu / Lark won't work without an App Secret.ÚDomainzfeishu (China)zlark (International)r\   r[   r¡   u   Credentials verified â€” bot: Úunnamedz:Could not verify bot connection. Credentials saved anyway.z!Credential verification skipped: r—   r˜   r,  rq   rž  r'  r   zConnection modeu0   WebSocket (recommended â€” no public URL needed)z,Webhook (requires a reachable HTTP endpoint)r  z/Webhook defaults: 127.0.0.1:8765/feishu/webhookzMOverride with FEISHU_WEBHOOK_HOST / FEISHU_WEBHOOK_PORT / FEISHU_WEBHOOK_PATHzPFor signature verification, set FEISHU_ENCRYPT_KEY and FEISHU_VERIFICATION_TOKENrŸ  zBot created: z)How should direct messages be authorized?r´  rê   rU  z"Allowed user IDs (comma-separated)rd   r÷   r¤  zAllowlist saved.zDM pairing enabled.zHUnknown users can request access; approve with `hermes pairing approve`.z)Open DM access enabled for Feishu / Lark.z"How should group chats be handled?z4Respond only when @mentioned in groups (recommended)zDisable group chatsr£  r–  rP  z-Group chats enabled (bot must be @mentioned).zGroup chats disabled.zLLeave blank to clear a previously saved home channel (cron / notifications).z/Home chat ID (optional, for cron/notifications)ÚFEISHU_HOME_CHANNELzHome channel set to zHome channel cleared.u   ðŸª½ Feishu / Lark configured!zApp ID: zDomain: zBot: )z%Use DM pairing approval (recommended)zAllow all direct messageszOnly allow listed user IDs)Úhermes_cli.configr
  r
  Úhermes_cli.setupr
  Úhermes_cli.cli_outputr¨  r
  r
  r
  r	
  Úhermes_cli.setup_platformsr

  rð	  ÚKeyboardInterruptr«  rr   rÔ	  rñ   r  r  )r
  r
  r
  r¨  r
  r
  r
  r	
  r

  Ú
method_idxÚcredentialsrW   Úused_qrr—   r˜   r,  r¡   rô	  rq   rš   Úmode_idxÚ
access_idxr¾   Ú	group_idxÚhome_channels                            rK   Úinteractive_setupr
  û  sÞ  € çBÝ.ßdÕdÝ?á�Ô!Ù˜OÐ-IÈ?×[Ò[ÙáØ5Ø	GÐIxÐyØ	ó€Jð
 €KØ�Q„ð	<Ü%›-ˆK÷ ÙÐQÔRÜ�;Ó€GçÙÐ\Ô]ÙÐXÔYÙ˜¨5Ô1ˆßÙÐSÔTÙÙ˜L°4Ô8ˆ
ßÙÐWÔXÙÙ(¨Ð4DÐF\Ð3]Ð_`ÓaÐefÔf‘ÐltˆØˆð	EÜ  °VÓ<ˆHßØ#Ÿ<™<¨
Ó3�ÙÐ >¸x×?TÐ?TÈ9Ð>UÐVÕWáÐZÕ[ð   ¨°zÀ8ÈVÐU^Ð`dÐfpÐrzÐ{ˆà$ XÕ.°¸LÕ0IˆJØ�_‰_˜X xÓ0€FØ#Ÿ™¨	Ó2°K·O±OÀJÓ4OˆX€GÙ�? FÔ+ÙÐ&¨
Ô3Ù�? FÔ+çØ%‰á ØØ?ÐAoÐpØó
ˆð
 (0°1¤}™)¸+ˆØ˜iÔ'ÙÐHÔIÙÐfÔgÙÐiÔjÙÐ+¨_Ô=çÙ˜ h ZÐ0Ô1áØ3ÚlØ	ó€Jñ
 Ð+°zÀQ´©VÈGÔTØ�Q„ÙÐ?ÀÇÀÈBÐY^Ô_×gÑgÐhkÐmoÓpˆ	ÙÐ-¨yÔ9ÙÐ(Õ)áÐ-¨rÔ2Ø˜Œ?ÙÐ/Ô0ÙÐaÕbáÐEÔFáØ,Ø	?ÐAVÐWÐYZó€Iñ Ð(°IÀ´N©&È
ÔSÙÀ)ÈqÄ.Ñ>ÐVmÔnáÐ]Ô^ÙÐKÐV[Ô\×bÑbÓd€LßÙÐ,¨lÔ;ÙÐ,¨\¨NÐ;Õ<Ù	Ð/×	0Ò	0ÙÐ*Ô+áÐ2Ô3Ù�˜&˜Ð"Ô#Ù�˜&˜Ð"Ô#ßÙ�U˜8˜*Ð%Ö&ñ øô !ô 	ÙÐ:Ô;ÚÜô 	<ÙÐ4°S°EÐ:×;Ò;ûð	<ûô4 ô 	EÙÐ=¸c¸UÐC×DÒDûð	EúsH   Á
L) Ã 0M" Ä	M" ÄM" Ì)MÌ?MÍMÍ	MÍMÍ"NÍ-M>Í>Nc               ó$   € V ^8„  d   QhRRRRRR/# )rC   Úyaml_cfgr”   Ú
feishu_cfgrG   zdict | NonerI   )rJ   s   "rK   rL   rL   r  s&   € ÷ Qñ Q ð Q°4ð Q¸Kñ QrM   c                ór   € \        VR4      pV'       d#   R\        VR,          4      P                  4       /# R# )zÇ``apply_yaml_config_fn`` (#24849): bridge config.yaml feishu.allow_bots to FEISHU_ALLOW_BOTS (env wins) and
seed ``extra.allow_bots`` so a multiplexed secondary profile's adapter reads its own value.rµ   N))rµ   r—  r±  )Ú_apply_yaml_bridgerb   r±  )r
  r
  Úseededs   && rK   Ú_apply_yaml_configr#
  r  s6   € ô   
Ð,[Ó\€Fß@FˆLœ#˜f \Õ2Ó3×9Ñ9Ó;Ð<ÐPÈDÐPrM   c               ó   € V ^8„  d   QhRR/# rø  rI   )rJ   s   "rK   rL   rL   y  s   € ÷ %ñ %˜Tñ %rM   c                ód   € \        V R/ 4      ;'       g    / p\        VP                  R4      4      # )z5Feishu counts as connected once app_id is configured.rQ  r—   )rÎ   rr   rñ   )r;  rQ  s   & rK   Ú_is_connectedr&
  y  s,   € ä�F˜G RÓ(×.Ð.¨B€EÜ�—	‘	˜(Ó#Ó$Ð$rM   c               ó   € V ^8„  d   QhRR/# rH  rI   )rJ   s   "rK   rL   rL     s   € ÷ ñ �Tñ rM   c           
     ó\  € ^RI Hp ^RIHp ^RIHp ^RIHp V P                  ! R$/ VBRRRRR	\        /BVB/ R
\        bR\        bR\        bR\        bRRR.bRRbR\        bR\        bRRbR\        bRRbRRbRRbRVbRR bR!VP                   bR"VP"                  bBVP$                  B  R## )%u:   Plugin entry point â€” called by the Hermes plugin system.)ÚPLATFORM_HINT)ÚSEND_ENTRY_KWARGS)ÚDASHBOARD_CARD)Úgateway_envrp   r[   r¶  r
  Úadapter_factoryÚcheck_fnÚensure_deps_fnÚis_connectedÚvalidate_configÚrequired_envr�  rž  r   z-Run `hermes setup` to install Feishu support.Úsetup_fnÚapply_yaml_config_fnÚcron_deliver_env_varr
  Ústandalone_sender_fnÚmax_message_lengthrG  r­  u   ðŸª½Úallow_update_commandTÚplatform_hintÚdisplay_tierÚmediumÚenv_overridesÚenv_enable_credentialsNrI   )Úadapter_hintr)
  Úsend_targetsr*
  Údashboard_cardr+
  rd   r,
  Úregister_platformrE  r  r  r&
  r
  r#
  r 
  ÚENV_OVERRIDESÚENV_ENABLE_CREDENTIALSÚAUTHZ)Úctxr)
  r*
  r+
  r,
  s   &    rK   ÚregisterrF
    s  € å+Ý/Ý.ÝØ×Òñ Ø
ñàðà,ðä>Kñð òõ %ð	õ 6Oð	õ
 #ðõ
 5Bðð &Ð':Ñ;ðñ Eðõ Paðõ 0ðñ G\ðõ .ðñ CGðñ OUðñ "ðñ $ðñ ðð "×/Ò/ðð  +×AÒAðð FQ×EVÑEVôrM   ))zlark_oapi.api.application.v6)r;	  )zlark_oapi.api.im.v1)rm	  ri	  re	  r^	  rZ	  rU	  r,	  r3	  rQ	  r7	  r„  rE	  r?	  rM	  rI	  )zlark_oapi.core)r   r  )zlark_oapi.core.const)r'  r&  )zlark_oapi.core.model)r  )z5lark_oapi.event.callback.model.p2_card_action_trigger)rá  rà  )z"lark_oapi.event.dispatcher_handler)rÛ  >   ú.bmpr4  rê  ú.pngr(  ú.webp>   ú.aacú.m4aú.mp3r/   ú.wavú.flacr0   ú.webm>   ú.3gpú.aviú.m4vú.mkvú.movrÀ  rO
  >   rQ
  rR
  rT
  rÀ  i � i€Q i   i`T  i„  )r;  rh  )r_  rŒ   rO   r¶  rè   rp   ræ  r  rí  rp  r¬  >   ÚdivÚnoter:  r!  ÚcolumnÚlark_mdr8  Ú
column_setr4  r$  r%  >   rE  r  rŽ  Úlinkr   r  Úlocalerö  rq   rw   rc   r  r7  rß   r—  rÆ  r÷  rø  )r2  r4  r3  r5  rz  ))Úboldr˜  r˜  )ÚitalicrØ  rØ  )Ú	underlinez<u>z</u>)Ústrikethroughú~~r`
  )Nrõ   )rõ   r{   rI   r…	  >   r4  rê  rH
  r(  rI
  >   rP
  rQ
  rS
  rT
  rÀ  rO
  >   rK
  rL
  r/   rM
  rN
  r0   (	  Ú__conditional_annotations__r¸   Ú
__future__r   r  r   rQ   rn  Úconcurrent.futuresrø  r  r@  r1  r�  r?  rÒ  r  rö  rù   rU  rp  r(  r   Údataclassesr   r   r   Úpathlibr   Útypesr	   Útypingr
   r   r   r   r   r   Úurllib.errorr   r   Úurllib.parser   Úurllib.requestr   r   Úaiohttpr   r  r¶  r   r\   rû  r  r  rü  rV  rý  r	  r
	  Úgateway.configr   r   Ú
agent.i18nr   rô  r   r   r   r   r   r   r    r!   Úgateway.platforms.eventr"   r#   r$   Úgateway.statusr%   Úgateway.status_scoped_locksr&   r…  r'   Úutilsr(   r)   r*   Úgateway.platforms._sharedr+   r!
  r,   r“  r-   r�  r.   Ú	getLoggerrh   r¬  Úcompiler)  rr  r(  rT  rS  rR  Ú
IGNORECASEru  r  r  r  r  rÂ  r  rw	  ró  ru	  rv	  r¥  rá  r!	  r  r¸  r¹  rº  r»  r·  r¼  r½  r¾  ry  r  r-  rJ  rK  rL  r.  rŽ  r�  r  r@   rl   rA   rX   r¹   r"	  r{  r…  r|  r  r†	  r‹	  r‘	  r’	  ri  rð  rù  r  rÓ  r5  r  rä   rP  ro  rp  rL  r+  r*  r,  ra   ro   rv   r€   rŠ   r–   r»   rÂ   ÚRejectReasonrÏ   rà   ræ   rë   rò   r   r  r  r  r  r*  r2  r6  rB  r>  rq  rh  rw  rv  r²  ra  rµ  r¾  rÞ  rÑ  rÖ  r×  rØ  rï  r  r  r  rÔ  rÕ  r  r  r&  r  rî  rj  r  ra  rÒ  rk  rx  r´  rµ  Úlocalr‡  rz  rº  rö  r  r  r  r#  r(  r0  r5  r>  rC  rE  rˆ	  rŒ	  r”	  r�	  r­	  rÂ	  ÚqrcoderÇ	  r/  rÍ	  rÔ	  r×	  rk  rÑ	  rÒ	  rð	  rï	  rù	  rú	  rû	  r 
  r
  r#
  r&
  rF
  )rÆ  r¹  rp   rú  Úmimera
  s   00000@rK   Ú<module>rz
     sÜ  øðôõ$ #å Û Û Û Û Û Û Û Û Û Û Û 	Û 	Û Û Û Ý #ß (Ý Ý Ý !ß ?× ?ß ,Ý "ß +ðÛÝð
ÛñÐ ð Ð €€~Ù ƒ	× Ñ Ñ->ÕQÑ->¡ Ë5À4˜’*É5‘$Ñ->ÓQÔ RØÐ Ø—N’NÓ$Ð à'¨tÐ3Ð Ø"¨$Ð.Ð ç 3Ý ÷÷ ó ÷
 QÑ PÝ .Ý ;Ý ,ß 7Ñ 7÷ó ð 
×	Ò	˜8Ó	$€ð —J’Jðð ‡L�Ló!Ð ð$ —J’JÐ9Ó:Ð ØŸ*š*Ð%9Ó:Ð ØŸ:š: kÓ2Ð Ø—’˜LÓ)€ØŸ:š:Ð&UÐWY×WdÑWdÓeÐ ãFÐ ÛWÐ ÛMÐ Ø4L×4RÒ4RÔ4TÔUÑ4T¡y s˜šÑ4TÒUÐ Ø%Ð Ø#Ð Ø"(¨'Ð!2Ð Û"BÐ à
ˆE�6˜5 '¨5°&¸%ÀÈ%ÐQWÐY^Ð`gÐinðÐ ñ $Ð ØÐ ØÐ Ø(Ð Ø$'Ð !Ø#$Ð  Ø $Ð Ø%(Ð "Ø Ð Ø#Ð ØÐ Ø)Ð á(Ð Ù")Ð Ù!0Ð Ø&(Ð #Ø!$Ð Ø $Ð Ø')Ð $Ø$&Ð !Ù&1Ð #Ù(/Ð %ð �FÐ-¨yÐ:JÈHÐV\Ð^dð(Ð �nó ð
 Ð4°iÐAlØÐ8¸&ÐBjð(Ð �nó õñ  )¨&°&Ð)9Ó:Ð ð  (Ð Ø&Ð ð *.Ð &Ø"%Ð ð Ð*Ø
Ð,ðÐ ð Ð 8¸&ÐB^Ð_Ð Ø1Ð ØÐ ð +Ð Ø2Ð Ø*Ð Ø3Ð ØÐ Ø)Ð á'Ð ØŸZšZÐ(DÓEÐ ØŸ*š* ]Ó3Ð Ù#Ð$TÓUÐ Ù$Ð%:Ó;Ð Ø—’˜FÓ#€ñÐ óÐ ó€ñ �$Ô÷ ð  ó ð ñ �$Ô÷ð ó ðñ �$Ô÷5ð 5ó ð5ñ  �$Ô÷Gð Gó ðGñ �$Ô÷;ð ;ó ð;ñ �$Ô÷ ð  ó ð ðF ÷+ð +ó ð+ð ÷9ð 9ó ð9ð ÑuÕv€õ@õ
jõ9õ:õ'õ#õBñ AÐ õõ$9õ	!÷6ð 6÷1ð 1õHõ
!6ðH"ØKO÷"õJ\õõð ˜4  }°iÀÐOÐ ÷>Lð >LõB4÷
ð ð 9NØPTð9Ná0Ó2÷9NõxGõõ	õõ&"õ:@õ!õõ*dõ_õ
	4õ
õ)õð*ÑSU÷ *÷ð õõhõõ ?õ&ðB —^’^Ó%Ð ØÐ Ø—o“oÓ'Ð ÷Cñ Cõ 5'õpM'õ`õ*õ&ðAÐPT÷ AõCõCõpð	Ðae÷ 	õô]+0Ð'ô ]+0õFWPõHõ÷&
ð 
÷ð ð -ÐYa÷ -ð`Û õ
õ7õGõ
÷÷ñ0	¨ñ 	É#÷ 	ñ 	÷ð óL CÑ ÛIÑ ÛJÑ ñ 6À4ñ  6ÐUYñ  6Ðjoö  6÷Ft'ð t'÷nQð Q÷%ð %÷ò øðUJ ô Ø€GØ
ƒCðûð ô ØƒJðüô* Rùóp VøðT~ 	�YÐô Ø‚KðúsB   Â
X, Â!X> ÃYÈYÖY Ø,X;Ø:X;Ø>	YÙ
YÙY)Ù(Y)