+
    kHàjOÌ  ã                   ób  € R 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H	t	H
t
 ^ RIHtHtHtHtHt  ^ RIs^ RIHs ^ RIHsHs Rs ^ RIsRs ^ RIHtHt  ^ RI!Ht"Ht# ^ RI$Ht% ^ RI&Ht' Rt(^ RI)H*t*H+t+ ^ RI,H-t-H.t. ^ RI/H0t0 ^ RI1H2t2H3t3 ^ RI4H5t5 ^ RI6H7t8H9t:H;t<H=t>H?t? ^ RI@HAtA ^ RIBHCtCHDtDHEtE ]PŒ                  ! ]G4      tHRtI. RGOtJ^tKRtLRtMR R ltN ! R R]Pž                  4      tPRtQ]P¤                  ! R4      tS0 RHmtTRtURtVRI U Uu/ uF*  w  rV R V R!2R V R"2R V R#2R$VP¯                  4        R%23bK,  	  upp tX]P¤                  ! R&4      tYR'tZR( R) lt[R* R+ lt\R, R- lt]R. R/ lt^R0 R1 lt_ ! R2 R3]24      t` ! R4 R5\,        '       d   \"        PÂ                  M]b4      tcR6RR7RR8R/R9 ltdR: R; lteR< R= ltfR> R? ltgRJthR@ RA ltiRB RC ltjRD RE ltkR#   ] d    RsR;s;ss]! RRFR	^ÈR
R/4      s EL­i ; i  ] d	    RsRs EL¸i ; i  ] d    Rt(R;t;t ;t"t#R;t%t' ELµi ; iu upp i )Ka¹  DingTalk platform adapter (Stream Mode via dingtalk-stream >=0.20; replies via session webhook markdown or AI Cards).
Requires ``pip install "dingtalk-stream>=0.20" httpx``. config.yaml ``platforms.dingtalk``: ``enabled``, group gating
(``require_mention``, ``free_response_chats``, ``mention_patterns``, ``allowed_users``/``allowed_chats``) and
``extra.client_id`` / ``extra.client_secret`` (or DINGTALK_CLIENT_ID / DINGTALK_CLIENT_SECRET).N)ÚdatetimeÚtimezoneÚUTC)ÚAnyÚDictÚListÚOptionalÚSet©ÚChatbotMessage©ÚCallbackMessageÚ
AckMessageTFr   Ú	STATUS_OKÚSTATUS_SYSTEM_EXCEPTIONiô  )ÚclientÚmodels)r   )ÚPlatformÚPlatformConfig)ÚMessageDeduplicatorÚcompile_mention_patterns)Út)ÚBasePlatformAdapterÚ
SendResult)ÚMessageEvent)Úapply_yaml_bridgeÚdecode_json_list_literalÚextra_or_secretÚget_scoped_secretÚ
send_error)ÚStandaloneSendPolicy)Úcollect_download_codesÚextract_mediaÚextract_texti N  é,  g     Àr@c                ó>   € V ^8„  d   QhR\         R,          R\        /# )é   ÚexcNÚreturn©ÚBaseExceptionÚbool)Úformats   "ÚG/home/ubuntu/.hermes/hermes-agent/plugins/platforms/dingtalk/adapter.pyÚ__annotate__r.   G   s   € ÷ ñ œ-¨$Õ.ð ´4ñ ó    c                óÊ   € \        ^4       FS  pV f    R# \        V \        4      '       d   R\        V 4      9   d    R# V P                  ;'       g    V P
                  p KU  	  R# )zþTrue for #24851: ``websockets.connect`` is not an async CM for this dingtalk-stream.

The SDK may surface it as the bare TypeError, or as an AttributeError (its ``except``
clause touches the unloaded ``websockets.exceptions``) chained on that TypeError.
Fzasynchronous context managerT)ÚrangeÚ
isinstanceÚ	TypeErrorÚstrÚ	__cause__Ú__context__)r'   Ú_s   & r-   Ú_is_sdk_incompatr8   G   sQ   € ô �1ŽXˆØŠ;ÚÜ�cœ9×%Ò%Ð*HÌCÐPSËHÔ*TÚØ�m‰m×.Ð.˜sŸ™Šñ ñ r/   c                   ó\   a a€ ] tR t^Vt oRtR]3V3R lV 3R llltV3R lR ltRtVt	V ;t
# )Ú_SdkLogGuardu  Collapse repeated dingtalk_stream.client records; never raises on bad format args.

dingtalk-stream 0.24.3 logs ``logger.exception('unknown exception', e)`` every 3 s from its
retry loop â€” a malformed call that also triggers stdlib "--- Logging error ---" tracebacks.
Nc                ó    <€ V ^8„  d   QhRS[ /# )r&   Úwindow)Úfloat)r,   Ú__classdict__s   "€r-   r.   Ú_SdkLogGuard.__annotate__]   s   ø€ ÷ +ñ +±%ñ +r/   c                óN   <€ \         SV `  4        WuV n        V n        / V n        R # ©N)ÚsuperÚ__init__Ú_on_exceptionÚ_windowÚ_seen)ÚselfÚon_exceptionr<   Ú	__class__s   &&&€r-   rC   Ú_SdkLogGuard.__init__]   s$   ø€ Ü‰ÑÔØ+7Ð(ˆÔ˜DœLØ(*ˆŽ
r/   c                ó:   <€ V ^8„  d   QhRS[ P                  RS[/# )r&   Úrecordr(   )ÚloggingÚ	LogRecordr+   )r,   r>   s   "€r-   r.   r?   b   s!   ø€ ÷ ñ ™W×.Ñ.ð ±4ñ r/   c                óø  €   VP                  4       pVP                  '       d   VP                  ^,          MRpVe    V P                  e   V P                  V4       VP                  VR,          Ve   \        V4      P                  MR3p\        P                  ! 4       pV P                  P                  V4      pVe6   Wg^ ,          ,
          V P                   8  d   V^;;,          ^,          uu&   R# Ve,   V^,          '       d   V RV^,           R2R	uVn        Vn        \#        V P                  4      R8¼  d   V P                  P%                  4        V^ .V P                  V&   R#   \         dr    \        TP                  \        4      '       d   TP                  MTP                  3pR P                  R TP                  .TO 4       4      pTR	uTn        Tn         ELÓi ; i  \         d     R# i ; i)
Ú c              3   ó8   "  € T F  p\        V4      x € K  	  R # 5irA   ©r4   )Ú.0Úxs   & r-   Ú	<genexpr>Ú&_SdkLogGuard.filter.<locals>.<genexpr>h   s   é € ÐCÑ/B¨!œs 1Ÿv˜vÓ/Bùs   ‚N:Niô  NFz (suppressed z identical repeats)é   T© )Ú
getMessageÚ	Exceptionr2   ÚargsÚtupleÚjoinÚmsgÚexc_inforD   ÚlevelnoÚtypeÚ__name__ÚtimeÚ	monotonicrF   ÚgetrE   ÚlenÚclear)rG   rL   r^   r[   r'   ÚkeyÚnowÚentrys   &&      r-   ÚfilterÚ_SdkLogGuard.filterb   s›  € ð	ð2Ø×'Ñ'Ó)�ð
 )/¯¯¨�&—/‘/ !Ö$¸TˆCØŠ 4×#5Ñ#5Ò#AØ×"Ñ" 3Ô'Ø—>‘> 3 t¥9ÀCÂO¬d°3«i×.@Ò.@ÐY]Ð^ˆCÜ—.’.Ó"ˆCØ—J‘J—N‘N 3Ó'ˆEØÒ  S°­8¥^°d·l±lÔ%BØ�a—˜A•“ÙØÒ  U¨1§X¤XØ-0¨E°¸uÀQ½x¸jÐH[Ð*\Ð^`Ð'�”
˜FœKÜ�4—:‘:‹ #Ô%Ø—
‘
× Ñ Ô"Ø" A˜hˆD�J‰J�s‰Oñ øô) ô 2Ü&0°·±¼e×&DÒ&D�v—{’{È6Ï;É;È.�Ø—h‘hÑC°·
±
Ð/B¸TÑ/BÓCÓC�Ø*-¨rÐ'�”
˜FŸKð2ûô$ ô 	ØÙð	úsB   ƒE+ “G* ¥CG* Ã5G* ÄA!G* Å+A8G'Ç#G* Ç&G'Ç'G* Ç*G9Ç8G9)rD   rF   rE   )rb   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú_SDK_LOG_REPEAT_WINDOWrC   rk   Ú__static_attributes__Ú__classdictcell__Ú__classcell__©rI   r>   s   @@r-   r:   r:   V   s+   ù‡ € ñð %)Ð:P÷ +õ +÷
÷ ð r/   r:   z%^https://(?:api|oapi)\.dingtalk\.com/Ú2659900Úim_bg_1ÚRobotÚEmotionRequestTextEmotionÚEmotionRequestÚEmotionHeadersÚrobot_Ú_emotion_with_options_asyncz^\d+\.\szvDingTalk session webhook replies do not support local %s. Only markdown/text replies are supported without OpenAPI %s.c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r&   Úrawr(   )r   Úsetr4   )r,   s   "r-   r.   r.   ‡   s"   € ÷ Fñ F”#ð Fœ#œc�(ñ Fr/   c                ó  € \        V 4      p \        V \        4      '       d   T M\        V 4      P	                  R4      p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 )zaSplit a list, JSON-list string or comma-separated string into a set of stripped, non-empty items.Ú,)Ú_decode_json_list_literalr2   Úlistr4   ÚsplitÚstrip)r   ÚpartsÚparts   &  r-   Ú_csv_setr‰   ‡   s_   € ä
# CÓ
(€CÜ˜c¤4×(Ò(‰C¬c°#«h¯n©n¸SÓ.A€EÙ*/ÓE©% $´3°t³9·?±?×3DÔŒC�‹I�O‰OÖ©%ÑEÐEùÒEs   Á!BÁ(Bc                ó$   € V ^8„  d   QhR\         /# ©r&   r(   ©r+   )r,   s   "r-   r.   r.   Ž   s   € ÷ 9ñ 9œtñ 9r/   c                 ó*   € \         ;'       d    \        # )uk  PASSIVE registry ``check_fn`` â€” must never install; credentials are gated separately.

Registry ``check_fn`` â€” called from status displays and config loading, so it must never install
anything. The ACTIVE lazy-installer (``check_dingtalk_requirements``) is registered as
``ensure_deps_fn`` and runs from ``create_adapter()`` when this returns False (#79812).
)ÚDINGTALK_STREAM_AVAILABLEÚHTTPX_AVAILABLErX   r/   r-   Údingtalk_deps_presentr�   Ž   s   € ô %×8Ð8¬Ð8r/   c                ó$   € V ^8„  d   QhR\         /# r‹   rŒ   )r,   s   "r-   r.   r.   ˜   s   € ÷ ñ œdñ r/   c                 óÆ   € \         '       d   \        '       d   R#  ^ RIHp  V ! R4       ^ RIp^ RIp^ RIHp ^ RIHpH	p YYET3w  ssss	sR;s sR#   \         d     R# i ; i)uô  ACTIVE deps-only installer (registry ``ensure_deps_fn``); rebinds module globals. Deliberately does NOT
check credentials: an ``extra``-configured platform would otherwise be vetoed before ever installing (deadlock).

Lazy-installs dingtalk-stream/httpx and rebinds module globals. Deliberately does NOT check credentials
â€” ``ensure_deps_fn``'s contract is deps-only ("Returns True once deps are importable"); credentials are
gated by ``is_connected``/``validate_config``. Otherwise a platform configured via
``PlatformConfig.extra`` (which ``_is_connected`` accepts) would pass enablement, reach
``create_adapter()``, and have the installer veto on env-var grounds before ever installing â€”
re-creating the #79812 deadlock for extra-configured setups.
T)Úensure_importÚdingtalkNr
   r   F)rŽ   r�   Ú	pm.extrasr“   Údingtalk_streamÚhttpxr   Údingtalk_stream.framesr   r   rZ   )r“   Ú_dsÚ_httpxÚ_CMÚ_CBMÚ_AMs         r-   Úensure_dingtalk_depsrž   ˜   si   € ÷ !Ó §_£_ÙðÝ+Ù�jÔ!ß6Ý9ßUð KNÐTXÐ_eÐJeÑG€O�^ _°jÀ%Ø26Ð6Ð Ùøô	 ô Úðús   œ$A ÁA ÁA c                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r&   Úextrar(   )r   Údictr\   )r,   s   "r-   r.   r.   ³   s"   € ÷ \ñ \œ¤�ð \¬5ñ \r/   c                ó®   € T ;'       g    / p V P                  R4      ;'       g    \        RR4      V P                  R4      ;'       g    \        RR4      3# )zU(client_id, client_secret) from PlatformConfig.extra first, then env / scoped secret.Ú	client_idÚDINGTALK_CLIENT_IDÚ Úclient_secretÚDINGTALK_CLIENT_SECRET)re   Ú_get_scoped_secret)r    s   &r-   Ú_credentialsr©   ³   sV   € à�KˆK�R€Eð �I‰I�kÓ"×RÐRÔ&8Ð9MÈrÓ&RØ�I‰I�oÓ&×ZÐZÔ*<Ð=UÐWYÓ*Zð\ð \r/   c                ó$   € V ^8„  d   QhR\         /# r‹   rŒ   )r,   s   "r-   r.   r.   ¼   s   € ÷ >ñ >¤Tñ >r/   c                 óN   € \        4       ;'       d    \        \        R4      4      # )zLCombined deps (lazy-installed) + credentials check for setup/status callers.N)rž   Úallr©   rX   r/   r-   Úcheck_dingtalk_requirementsr­   ¼   s   € äÓ!×=Ð=¤c¬,°tÓ*<Ó&=Ð=r/   c                   ó2  a a€ ] tR t^Át oRt]t]V3R lR l4       t]tV3R lV 3R llt	RR/V3R lR	 llt
V3R
 lR ltV3R lR ltRR/V3R lR lltRQV3R lR lltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R  lR! ltV3R" lR# ltV3R$ lR% ltV3R& lR' ltV3R( lR) ltV3R* lR+ lt]! ]4      tV3R, lR- ltRRV3R. lR/ lltRSV3R0 lR1 llt RTV3R2 lR3 llt!RTV3R4 lR5 llt"RUV3R6 lR7 llt#V3R8 lR9 lt$V3R: lR; lt%R<R/V3R= lR> llt&R<R/V3R? lR@ llt']V3RA lRB l4       t(RVV3RC lRD llt)V3RE lRF lt*RGR/V3RH lRI llt+V3RJ lRK lt,V3RL lRM lt-]V3RN lRO l4       t.RPt/Vt0V ;t1# )WÚDingTalkAdapterzÎStream Mode adapter: the SDK keeps a long-lived WebSocket and messages arrive via a ChatbotHandler
callback; replies go through the message's session_webhook (httpx) or, with ``card_template_id``, AI Cards.c                ó    <€ V ^8„  d   QhRS[ /# r‹   rŒ   )r,   r>   s   "€r-   r.   ÚDingTalkAdapter.__annotate__È   s   ø€ ÷ ?ñ ?©$ñ ?r/   c                óT   € \        V P                  ;'       d    V P                  4      # )zPEdits only exist with AI Cards; the gateway gates streaming cursor/edit on this.)r+   Ú_card_template_idÚ	_card_sdk©rG   s   &r-   ÚSUPPORTS_MESSAGE_EDITINGÚ(DingTalkAdapter.SUPPORTS_MESSAGE_EDITINGÇ   s!   € ô �D×*Ñ*×=Ð=¨t¯~©~Ó>Ð>r/   c                ó    <€ V ^8„  d   QhRS[ /# )r&   Úconfig)r   )r,   r>   s   "€r-   r.   r±   Î   s   ø€ ÷ 2ñ 2™~ñ 2r/   c                óŠ  <€ \         SV `  V\        P                  4       VP                  ;'       g    / p\        V4      w  V n        V n        V P                  4       V n	        V P                  R R4       Uu0 uF  q3P                  4       kK  	  upV n        R;V n        ;V n        ;V n        ;V n        V n        VP%                  R4      ;'       g    V P                  V n        \)        RR7      V n        / V n        / V n        VP%                  R4      V n        \3        4       V n        / V n        \3        4       V n        R# u upi )Úallowed_usersÚDINGTALK_ALLOWED_USERSNÚ
robot_codeéè  )Úmax_sizeÚcard_template_id)rB   rC   r   ÚDINGTALKr    r©   Ú
_client_idÚ_client_secretÚ_compile_mention_patternsÚ_mention_patternsÚ_csv_settingÚlowerÚ_allowed_usersÚ_stream_clientÚ_stream_taskÚ_http_clientr´   Ú
_robot_sdkre   Ú_robot_coder   Ú_dedupÚ_session_webhooksÚ_message_contextsr³   r€   Ú_done_emoji_firedÚ_streaming_cardsÚ	_bg_tasks)rG   r¹   r    ÚitemrI   s   &&  €r-   rC   ÚDingTalkAdapter.__init__Î   s  ø€ Ü‰Ñ˜¤×!2Ñ!2Ô3Ø—‘×"Ð" ˆÜ/;¸EÓ/BÑ,ˆŒ˜Ô,à37×3QÑ3QÓ3SˆÔØBF×BSÑBSÐTcÐe}ÔB~Ó(ÑB~¸$¯©®ÑB~Ñ(ˆÔØimÐmˆÔÐm˜dÔ/Ðm°$Ô2CÐmÀdÄnÐW[ÔWfØ %§	¡	¨,Ó 7× JÐ J¸4¿?¹?ˆÔÜ)°4Ô8ˆŒØ=?ˆÔØ13ˆÔØ05·	±	Ð:LÓ0MˆÔÜ+.«5ˆÔð <>ˆÔÜ,/«EˆŽùò )@s   Á7E Úis_reconnectFc                ó&   <€ V ^8„  d   QhRS[ RS[ /# )r&   rÖ   r(   rŒ   )r,   r>   s   "€r-   r.   r±   á   s   ø€ ÷ ñ ©Tð ¹dñ r/   c             ƒ  ój  "  € \         R3\        R3V P                  ;'       d    V P                  R33 F7  w  r#V'       d   K  \        P                  RV,           V P                  4        R# 	   ^ RIHp \        P                  ! RV! 4       R7      V n        \        P                  ! \        P                  ! V P                  V P                  4      4      V n        \         '       dË   \"        P$                  ! 4       pR	R
uVn        Vn        V P*                  '       d   \,        P.                  ! V4      V n        \2        P.                  ! V4      V n        V P*                  '       d-   \        P7                  RV P                  V P*                  4       M \        P7                  RV P                  4       V P                  P9                  \        P:                  P<                  \?        V \@        PB                  ! 4       4      4       \@        PD                  ! V PG                  4       4      V n$        V PK                  4        \        P7                  RV P                  4       V PM                  V P                  4       R#   \N         d-   p\        PQ                  RT P                  T4        Rp?R# Rp?ii ; i5i)z$Connect to DingTalk via Stream Mode.zGdingtalk-stream not installed. Run: pip install 'dingtalk-stream>=0.20'z+httpx not installed. Run: pip install httpxz6DINGTALK_CLIENT_ID and DINGTALK_CLIENT_SECRET requiredz[%s] F)Úplatform_httpx_limitsç      >@)ÚtimeoutÚlimitsÚhttpsÚcentralz+[%s] Card SDK initialized with template: %sz+[%s] Robot SDK initialized (media download)z[%s] Connected via Stream ModeTz[%s] Failed to connect: %sN))rŽ   r�   rÂ   rÃ   ÚloggerÚwarningÚnameÚ%gateway.platforms._http_client_limitsrÙ   r—   ÚAsyncClientrË   r–   ÚDingTalkStreamClientÚ
CredentialrÉ   ÚCARD_SDK_AVAILABLEÚopen_api_modelsÚConfigÚprotocolÚ	region_idr³   Údingtalk_card_clientÚClientr´   Údingtalk_robot_clientrÌ   ÚinfoÚregister_callback_handlerr   ÚTOPICÚ_IncomingHandlerÚasyncioÚget_running_loopÚcreate_taskÚ_run_streamrÊ   Ú_mark_connectedÚ_wire_plugin_handlersrZ   Úerror)rG   rÖ   ÚokÚproblemrÙ   Ú
sdk_configÚes   &$     r-   ÚconnectÚDingTalkAdapter.connectá   s  é € ä6ð  9Bð  CÜ,Ð.[Ð\Ø!Ÿ_™_×DÐD°×1DÑ1DÐF~ÐóA‰KˆB÷ ‘2Ü—‘˜w¨Õ0°$·)±)Ô<ÚñAð	ÝSÜ %× 1Ò 1¸$ÑG\ÓG^Ô _ˆDÔÜ"1×"FÒ"FÄ×GaÒGaÐbf×bqÑbqÐsw÷  tGñ  tGó  HHó  #IˆDÔß!Ó!Ü,×3Ò3Ó5�
Ø<CÀYÐ9�
Ô# ZÔ%9Ø×)×)Ð)Ü%9×%@Ò%@ÀÓ%L�D”NÜ"7×">Ò">¸zÓ"J�”Ø×)×)Ð)Ü—K‘KÐ MÈtÏyÉyÐZ^×ZpÑZpÕqä—K‘KÐ MÈtÏyÉyÔYØ×Ñ×9Ñ9¼/×:XÑ:X×:^Ñ:^Ô`pÐquÔw~÷  xPò  xPó  xRó  aSô  TÜ '× 3Ò 3°D×4DÑ4DÓ4FÓ GˆDÔØ× Ñ Ô"Ü�K‰KÐ8¸$¿)¹)ÔDØ×&Ñ& t×':Ñ':Ô;ÙøÜô 	Ü�L‰LÐ5°t·y±yÀ!ÔDÝûð	üsD   ‚<J3Á,J3Á0A7I9 Ã(A=I9 Å&DI9 É7J3É9J0Ê!J+Ê%J3Ê+J0Ê0J3c                ó   <€ V ^8„  d   QhRR/# ©r&   r(   NrX   )r,   r>   s   "€r-   r.   r±     s   ø€ ÷ +ñ + 4ñ +r/   c              ƒ  ó¬  "  € \         P                  ! 4       V n        \        V P                  RR4      p\        V\        P                  4      '       g   \        P                  ! R4      p\        V P                  4      pVP                  V4        V P                  4       G Rj  x€L
  VP                  V4       R#  L  TP                  T4       i ; i5i)aƒ  Run the SDK stream client with auto-reconnection.

dingtalk-stream's ``start()`` runs its own catch-all retry loop, so most
errors never reach us: ``_SdkLogGuard`` collapses that loop's repeated
log records, and a dingtalk-stream/websockets incompatibility (#24851)
is handed to the gateway's reconnect watcher via ``_set_fatal_error``
instead of retrying forever.  For errors that do escape ``start()``,
exponential backoff (RECONNECT_BACKOFF) applies; after
RECONNECT_CIRCUIT_BREAKER_TRIPS identical errors in a row the breaker
trips and stays tripped (silent, RECONNECT_CIRCUIT_BREAKER_DELAY between
attempts) until the error type changes.
rß   Nzdingtalk_stream.client)rò   Úcurrent_taskÚ_sdk_loop_taskÚgetattrrÉ   r2   rM   ÚLoggerÚ	getLoggerr:   Ú_on_sdk_errorÚ	addFilterÚ_run_stream_loopÚremoveFilter)rG   Ú
sdk_loggerÚguards   &  r-   rõ   ÚDingTalkAdapter._run_stream  s¥   é € ô &×2Ò2Ó4ˆÔÜ˜T×0Ñ0°(¸DÓAˆ
Ü˜*¤g§n¡n×5Ò5Ü ×*Ò*Ð+CÓDˆJÜ˜T×/Ñ/Ó0ˆØ×Ñ˜UÔ#ð	+Ø×'Ñ'Ó)×)Ð)à×#Ñ# EÖ*ñ *øà×#Ñ# EÕ*üs0   ‚BCÂB> Â$B<Â%B> Â)CÂ<B> Â>CÃCc                ó   <€ V ^8„  d   QhRR/# r   rX   )r,   r>   s   "€r-   r.   r±     s   ø€ ÷ )!ñ )!¨ñ )!r/   c              ƒ  óÂ  "  € ^ p^ pRpV P                   '       dý    \        P                  RV P                  4       V P                  P                  4       G Rj  x€L
  T P                   '       g   R# T\        8”  d%   \        P$                  ! \"        4      G Rj  x€L
  K˜  \&        \)        T\+        \&        4      ^,
          4      ,          p\        P-                  R	T P                  T4       \        P$                  ! T4      G Rj  x€L
  T^,          pEK  R#  L¿  \        P                   d0    \        T RR4      R8X  d   T P                  4       G Rj  x€L 
   R# \         dï   pT P                   '       g    Rp?R# \        T4      '       d3   T P                  TRR7       T P                  4       G Rj  x€L 
   Rp?R# \        T4      pYSJ d   T^,          pM^pTpT\        8:  d(   \        P                  RT P                  T4        Rp?ELµT\        ^,           8X  d'   \        P!                  RT P                  Y$\"        4        Rp?ELóRp?ii ; i EL¿ ELV5i)
é    Nz[%s] Starting stream client...Ú_fatal_error_codeÚdingtalk_stream_errorF)Úcancelz[%s] Stream client error: %su€   [%s] Stream client error repeated %d times: %s â€” circuit breaker tripped; retrying every %ds silently until the error changes.z[%s] Reconnecting in %ds...)Ú_runningrß   Údebugrá   rÉ   Ústartrò   ÚCancelledErrorr  Ú_notify_fatal_errorrZ   r8   r  ra   ÚRECONNECT_CIRCUIT_BREAKER_TRIPSrà   rø   ÚRECONNECT_CIRCUIT_BREAKER_DELAYÚsleepÚRECONNECT_BACKOFFÚminrf   rî   )rG   Úbackoff_idxÚconsecutive_same_errorÚlast_error_typerü   Ú
error_typeÚdelays   &      r-   r	  Ú DingTalkAdapter._run_stream_loop  sÖ  é € ØˆØ!"ÐØ'+ˆØ�m�mˆmðÜ—‘Ð=¸t¿y¹yÔIØ×)Ñ)×/Ñ/Ó1×1Ð1ð4 —=—=�=ÙØ%Ô(GÔGÜ—m’mÔ$CÓD×DÒDä)¬#¨k¼3Ô?PÓ;QÐTUÕ;UÓ*VÕW�Ü—‘Ð9¸4¿9¹9ÀeÔLÜ—m’m EÓ*×*Ð*Ø˜qÕ “ñK ñ 2øÜ×)Ñ)ô Ü˜4Ð!4°dÓ;Ð?VÔVØ×2Ñ2Ó4×4Ñ4ÚÜô Ø—}—}�}ÝÜ# A×&Ò&Ø×&Ñ& q°Ð&Ô7Ø×2Ñ2Ó4×4Ñ4ÝÜ! !›W�
ØÓ0Ø*¨aÕ/Ñ*à-.Ð*Ø&0�OØ)Ô-LÔLÜ—N‘NÐ#AÀ4Ç9Á9Èa×PÒPØ+Ô/NÐQRÕ/RÔRÜ—L‘LðOàŸ	™	Ð#9Ô>]ôÿùð!úò0 Eò +ùs´   ‚Iœ=D ÁDÁD ÁIÁ0*IÂIÂA+IÄIÄIÄD Ä:IÅEÅIÅIÅIÅ'IÅ(IÅ:IÆ 7IÆ7F:Æ8IÆ=IÇA
IÈIÈ8IÉIÉIÉIÉIr  Tc                ó*   <€ V ^8„  d   QhRS[ RS[RR/# )r&   r'   r  r(   Nr)   )r,   r>   s   "€r-   r.   r±   D  s"   ø€ ÷ ñ ¡ð ¹4ð È4ñ r/   c               óP  € \        V4      '       d   \        V RR4      R8X  d   R# RV R2p\        P                  RV P                  V4       V P                  RVRR7       \        V R	R4      pV'       d1   Ve+   VP                  4       '       g   VP                  4        R# R# R# R# )
zYCalled (sync, possibly from the SDK logger) with an SDK exception; hands off on incompat.r  Nr  zQdingtalk-stream cannot open its websocket with the installed websockets package (z¦). Hermes pins dingtalk-stream==0.24.3 with websockets==15.0.1; reinstall the dingtalk extra so those versions are used (e.g. `pip install 'hermes-agent[dingtalk]'`).z[%s] %sF)Ú	retryabler  )r8   r  rß   rø   rá   Ú_set_fatal_errorÚdoner  )rG   r'   r  r^   Útasks   &&$  r-   r  ÚDingTalkAdapter._on_sdk_errorD  sœ   € ä ×$Ò$¬°Ð6IÈ4Ó(PÐTkÔ(kÙØbÐcfÐbgð h[ð [ˆô 	�‰�Y §	¡	¨3Ô/ð 	×ÑÐ5°sÀeÐÔLÜ�tÐ-¨tÓ4ˆß�dÒ&¨t¯y©y¯{ª{Ø�K‰KŽMñ 0;Ñ&‰6r/   c                ó$   <€ V ^8„  d   QhRS[ RR/# )r&   Ú	debug_fmtr(   NrR   )r,   r>   s   "€r-   r.   r±   S  s   ø€ ÷ =ñ =©Cð =Àñ =r/   c              ‡  ó¾   "  €  VG Rj  x€L
  R#  L  \          d>   pT'       d+   \        P                  ! Y P                  .TOTN5!    Rp?R#  Rp?R# Rp?ii ; i5i)zjAwait *coro*, swallowing any exception (logged at debug as ``debug_fmt % (name, *args, exc)`` when given).N)rZ   rß   r  rá   )rG   Úcoror,  r[   rü   s   &&&* r-   Ú_quietÚDingTalkAdapter._quietS  sE   é € ð	=Ø�JŒJøÜô 	=ßÜ—’˜Y¯	©	Ð<°DÐ<¸!×<Ò<õ ûð	=üs6   ‚A„ ‰Š ŽA� ’A�,AÁ	AÁAÁAc                ó   <€ V ^8„  d   QhRR/# r   rX   )r,   r>   s   "€r-   r.   r±   [  s   ø€ ÷ 4ñ 4 $ñ 4r/   c              ƒ  óØ  "  € RV n         V P                  4        V P                  '       d   \        V P                  RR4      MRpVe)   V P	                  VP                  4       R4      G Rj  x€L
  V P                  '       dª   \        V P                  R4      '       dB   V P	                  \        P                  ! V P                  P
                  4      4      G Rj  x€L
  V P                  P                  4         \        P                  ! V P                  RR7      G Rj  x€L
  RV n        \#        V P$                  4       F  pVP                  4        K  	  V P$                  '       d)   \        P&                  ! V P$                  R	R
/ G Rj  x€L
  \#        V P(                  4       F-  pV P	                  V P+                  V4      RV4      G Rj  x€L
  K/  	  V P,                  '       d#   V P,                  P/                  4       G Rj  x€L
  R;V n        V n        V P0                  V P2                  V P(                  V P4                  V P6                  V P$                  3 F  pVP9                  4        K  	  \        P;                  RV P                   4       R#  EL+ EL¿ EL}  \        \        P                  3 d%    \        P                  RT P                   4        EL¹i ; i ELU EL Là5i)zDisconnect from DingTalk.FÚ	websocketNz1[%s] websocket close during disconnect failed: %sÚcloseg      @©rÛ   z7[%s] stream task did not exit cleanly during disconnectÚreturn_exceptionsTz?[%s] Failed to finalize streaming card on disconnect for %s: %sz[%s] Disconnected)r  Ú_mark_disconnectedrÉ   r  r/  r4  rÊ   Úhasattrrò   Ú	to_threadr  Úwait_forÚTimeoutErrorr  rß   r  rá   r„   rÓ   ÚgatherrÒ   Ú_close_streaming_siblingsrË   ÚacloserÏ   rÐ   rÑ   rÎ   rg   rî   )rG   r3  r)  Ú_chat_idÚstores   &    r-   Ú
disconnectÚDingTalkAdapter.disconnect[  sf  é € àˆŒØ×ÑÔ!àGK×GZ×GZÐGZ”G˜D×/Ñ/°¸dÔCÐ`dˆ	ØÒ Ø—+‘+˜iŸo™oÓ/Ð1dÓe×eÐeØ××ÐÜ�t×*Ñ*¨G×4Ò4Ø—k‘k¤'×"3Ò"3°D×4GÑ4G×4MÑ4MÓ"NÓO×OÐOØ×Ñ×$Ñ$Ô&ðcÜ×&Ò& t×'8Ñ'8À#ÔF×FÐFð !%ˆDÔÜ˜Ÿ™Ö(ˆDØ�K‰KŽMñ )à�>�>ˆ>Ü—.’. $§.¡.ÐIÀDÑI×IÐIô ˜T×2Ñ2Ö3ˆHØ—+‘+˜d×<Ñ<¸XÓFð  IJð  LTó  U÷  Uò  Uñ 4à××ÐØ×#Ñ#×*Ñ*Ó,×,Ð,Ø26Ð6ˆÔ˜DÔ/Ø×,Ñ,¨d×.DÑ.DÀd×F[ÑF[Ð]a×]sÑ]sÐuy÷  vAñ  vAð  CG÷  CQñ  CQó  RˆEØ�K‰KŽMñ Rä�‰Ð'¨¯©Ö3ò/ fò Pò GøÜ ¤'×"8Ñ"8Ð9ô cÜ—‘ÐVÐX\×XaÑXa×bðcúò Jò Uá,ùs    ‚A*K*Á,JÁ-K*ÂAK*ÃJÃK*Ã;%J  Ä JÄ!J  Ä%AK*Å*#K*ÆK"ÆAK*ÇK%ÇK*Ç*K*ÈK(ÈBK*ÊK*ÊJ  Ê ;KËK*ËKËK*Ë%K*Ë(K*c                ó<   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          /# )r&   rh   Úenv_namer(   )r4   r€   )r,   r>   s   "€r-   r.   r±   {  s+   ø€ ÷ bñ b¡ð b©sð b±s¹3µxñ br/   c           	     óX   € \        \        V P                  P                  WRR7      4      # )zEList/CSV setting from config.extra[key], falling back to the env var.F©Úblank_is_unset)r‰   Ú_extra_or_secretr¹   r    )rG   rh   rD  s   &&&r-   rÆ   ÚDingTalkAdapter._csv_setting{  s"   € äÔ(¨¯©×):Ñ):¸CÐZ_Ô`ÓaÐar/   c                ó    <€ V ^8„  d   QhRS[ /# r‹   rŒ   )r,   r>   s   "€r-   r.   r±     s   ø€ ÷ bñ b©4ñ br/   c                óº   € \        V P                  P                  RRRRR7      p\        V\        4      '       d   VP                  4       \        9   # \        V4      # )z4Whether group chats require an explicit bot trigger.Úrequire_mentionÚDINGTALK_REQUIRE_MENTIONÚfalseFrF  )rH  r¹   r    r2   r4   rÇ   Ú_TRUTHYr+   )rG   Ú
configureds   & r-   Ú_dingtalk_require_mentionÚ)DingTalkAdapter._dingtalk_require_mention  sU   € ä% d§k¡k×&7Ñ&7Ð9JÐLfÐhoð  AFô  Gˆ
Ü0:¸:Äs×0KÒ0Kˆz×ÑÓ!¤WÑ,ÐaÔQUÐV`ÓQaÐar/   c                ó0   <€ V ^8„  d   QhRS[ S[,          /# r‹   )r€   r4   )r,   r>   s   "€r-   r.   r±   „  s   ø€ ÷ Lñ L©©S­ñ Lr/   c                ó&   € V P                  RR4      # )zUGroup chat whitelist; non-empty = hard gate even when @mentioned. DMs never filtered.Úallowed_chatsÚDINGTALK_ALLOWED_CHATS)rÆ   rµ   s   &r-   Ú_dingtalk_allowed_chatsÚ'DingTalkAdapter._dingtalk_allowed_chats„  s   € à× Ñ  Ð2JÓKÐKr/   c                óD   <€ V ^8„  d   QhRS[ S[P                  ,          /# r‹   )r„   ÚreÚPattern)r,   r>   s   "€r-   r.   r±   ˆ  s    ø€ ÷ Mñ M©4±·
±
Õ+;ñ Mr/   c                ó¢  € V P                   P                  ;'       g    / P                  R4      pVfM   \        \	        RR4      ;'       g    R4      P                  4       ;p'       d    \        P                  ! V4      pVf   . # \        WP                  RR\        R7      #   \         d¡    TP                  4        Uu. uF*  q3P                  4       '       g   K  TP                  4       NK,  	  Mu upi ppT'       gL   TP                  R4       Uu. uF*  q3P                  4       '       g   K  TP                  4       NK,  	  Mu upi pp LÍi ; i)zVCompile optional regex wake-word patterns (config list, or env as JSON / lines / CSV).Úmention_patternsÚDINGTALK_MENTION_PATTERNSr¥   r‚   r”   ÚDingTalk)Ú
log_prefixÚplatform_labelÚdisplay_labelÚlogger_)r¹   r    re   r4   r¨   r†   ÚjsonÚloadsrZ   Ú
splitlinesr…   r   rá   rß   )rG   Úpatternsr   rˆ   s   &   r-   rÄ   Ú)DingTalkAdapter._compile_mention_patternsˆ  s
  € à—K‘K×%Ñ%×+Ð+¨×0Ñ0Ð1CÓDˆØÒ¬Ô,>Ð?ZÐ\^Ó,_×,eÐ,eÐceÓ(f×(lÑ(lÓ(nÐ!n Ö!nðYÜŸ:š: c›?�ð
 ÒØˆIÜ'¨¿Y¹YÐWaÐq{ô  FLô  Mð  	Møô ô YØ58·^±^Ô5EÓVÑ5E¨TÏÉÏœL˜DŸJ™JžLÒ5EùÒV�ÐVßØ9<¿¹À3¼ÓX¹°Ï:É:Ï<¤ §
¡
¦ºùÒX�HÐXùðYús6   Á*B# Â#EÃ C1ÃC1Ã0#EÄEÄ/EÅEÅEc                ó,   <€ V ^8„  d   QhRS[ RS[ RS[/# )r&   Ú	sender_idÚsender_staff_idr(   ©r4   r+   )r,   r>   s   "€r-   r.   r±   –  s'   ø€ ÷ qñ q©#ð qÁð qÉñ qr/   c                óø   € V P                   '       d   R V P                   9   d   R# \        T;'       g    RP                  4       T;'       g    RP                  4       0R0,
          V P                   ,          4      # )Ú*Tr¥   )rÈ   r+   rÇ   )rG   rj  rk  s   &&&r-   Ú_is_user_allowedÚ DingTalkAdapter._is_user_allowed–  sc   € Ø×"×"Ð" c¨T×-@Ñ-@Ô&@ÙÜ�y—� B×-Ñ-Ó/°/×2GÐ2GÀR×1NÑ1NÓ1PÐQÐUWÐTXÕXÐ\`×\oÑ\oÕoÓpÐpr/   c                ó&   <€ V ^8„  d   QhRS[ RS[/# ©r&   Útextr(   rl  )r,   r>   s   "€r-   r.   r±   ›  s   ø€ ÷ mñ m±cð m¹dñ mr/   c                óî   a€ \        S;'       d    V P                  4      ;'       dO    \        ;QJ d)    V3R  lV P                   4       F  '       g   K   R# 	  R# ! V3R  lV P                   4       4      # )c              3   óD   <"  € T F  qP                  S4      x € K  	  R # 5irA   )Úsearch)rS   Úprs  s   & €r-   rU   ÚDDingTalkAdapter._message_matches_mention_patterns.<locals>.<genexpr>œ  s   øé € Ð<lÑUkÐPQ¿X¹XÀd¿^¸^ÓUkùs   ƒ TF)r+   rÅ   Úany)rG   rs  s   &fr-   Ú!_message_matches_mention_patternsÚ1DingTalkAdapter._message_matches_mention_patterns›  sU   ø€ Ü�D×3Ð3˜T×3Ñ3Ó4×lÐl¿»Ô<lÐUY×UkÒUkÓ<l¿¼ÐlºÐl¸Ô<lÐUY×UkÒUkÓ<lÓ9lÐlr/   c          
      ó8   <€ V ^8„  d   QhRS[ RS[RS[RS[RS[/# )r&   Úmessagers  Úis_groupÚchat_idr(   )r   r4   r+   )r,   r>   s   "€r-   r.   r±   ž  s3   ø€ ÷ 
ñ 
©~ð 
ÁSð 
ÑTXð 
Ñcfð 
Ñkoñ 
r/   c                ó\  € V'       g   R# V P                  4       pV'       d   V'       d	   WE9  d   R# \        T;'       d    W@P                  RR4      9   4      ;'       gM    V P                  4       '       * ;'       g0    \        \	        VRR4      4      ;'       g    V P                  V4      # )z×Group trigger rules (DMs always pass; ``allowed_users`` is enforced earlier): ``allowed_chats`` is a hard
gate, then any of free_response_chats / require_mention off / @mentioned (SDK ``is_in_at_list``) / wake-word.TFÚfree_response_chatsÚDINGTALK_FREE_RESPONSE_CHATSÚis_in_at_list)rW  r+   rÆ   rQ  r  rz  )rG   r}  rs  r~  r  Úalloweds   &&&&& r-   Ú_should_process_messageÚ'DingTalkAdapter._should_process_messagež  sš   € ÷ ÙØ×.Ñ.Ó0ˆß—w 7Ô#9Ùä�×pÐp˜W×(9Ñ(9Ð:OÐQoÓ(pÑpÓq÷ <ð <Ø×1Ñ1Ó3Ô3÷<ð <ä”G˜G _°eÓ<Ó=÷<ð <ð ×5Ñ5°dÓ;ð		
r/   c                ó   <€ V ^8„  d   QhRR/# r   rX   )r,   r>   s   "€r-   r.   r±   ­  s   ø€ ÷ 7ñ 7 ñ 7r/   c                ó²   € V P                   P                  \        P                  ! V4      ;p4       VP	                  V P                   P
                  4       R# )z;Start a fire-and-forget coroutine and track it for cleanup.N)rÓ   Úaddrò   rô   Úadd_done_callbackÚdiscard)rG   r.  r)  s   && r-   Ú	_spawn_bgÚDingTalkAdapter._spawn_bg­  s<   € à�‰×Ñ¤7×#6Ò#6°tÓ#<Ð<˜4Ô=Ø×Ñ˜tŸ~™~×5Ñ5Ö6r/   c                ó$   <€ V ^8„  d   QhRS[ RR/# ©r&   r  r(   NrR   )r,   r>   s   "€r-   r.   r±   ²  s   ø€ ÷ 	añ 	a±sð 	a¸tñ 	ar/   c              ƒ  óÚ  "  € V P                   P                  VR4      pV'       d   V P                  4       G Rj  x€L
 MRpV'       d   \        VP	                  4       4      MR FC  w  rE V P                  WCVRR7      G Rj  x€L
  \        P                  RV P                  V4       KE  	  R#  Lr L-  \         d-   p\        P                  RT P                  YF4        Rp?K  Rp?ii ; i5i)u¬   Finalize open streaming cards for this chat at the start of every ``send()`` â€” the gateway has no "turn end" signal, so this is what closes lingering tool-progress cards.NT©Úfinalizez[%s] AI Card sibling closed: %sz$[%s] Sibling close failed for %s: %srX   )
rÒ   ÚpopÚ_get_access_tokenr„   ÚitemsÚ_stream_card_contentrß   r  rá   rZ   )rG   r  ÚcardsÚtokenÚout_track_idÚlast_contentrü   s   &&     r-   r=  Ú)DingTalkAdapter._close_streaming_siblings²  sÁ   é € à×%Ñ%×)Ñ)¨'°4Ó8ˆß27�d×,Ñ,Ó.×.Ð.¸TˆßAF¬$¨u¯{©{«}Ô*=ÈBÒ*NÑ&ˆLðaØ×/Ñ/°À\Ð\`Ð/Óa×aÐaÜ—‘Ð>ÀÇ	Á	È<ÖXó +Oñ /ñ bøäô aÜ—‘ÐCÀTÇYÁYÐP\×`Ò`ûðaüsQ   ‚8C+ºB-»C+Á	 C+Á*B1ÂB/Â%B1Â'C+Â/B1Â1C(Â<!C#ÃC+Ã#C(Ã(C+c                ó$   <€ V ^8„  d   QhRS[ RR/# r�  rR   )r,   r>   s   "€r-   r.   r±   ½  s   ø€ ÷  ñ  ©3ð  °4ñ  r/   c                óz  a aa€ VS P                   9   d   R# S P                   P                  V4       S P                  P                  V4      pV'       d/   \	        VRR4      ;'       g    R\	        VRR4      ;'       g    R3MRw  ooS'       d	   S'       g   R# R VVV 3R llpS P                  V! 4       4       R# )uT   Swap ðŸ¤”Thinking â†’ ðŸ¥³Done on the original user message; idempotent per chat_id.NÚ
message_idr¥   Úconversation_idc                ó   € V ^8„  d   QhRR/# r   rX   )r,   s   "r-   r.   Ú9DingTalkAdapter._fire_done_reaction.<locals>.__annotate__Æ  s   € ÷ 	qñ 	q˜Tñ 	qr/   c               “   ó°   <"  € SP                  SS \        R 4      RR7      G Rj  x€L
  SP                  SS \        R4      RR7      G Rj  x€L
  R#  L, L5i)ú"platform.dingtalk.emotion.thinkingT©ÚrecallNzplatform.dingtalk.emotion.doneF)Ú_send_emotionr   )rŸ  Úmsg_idrG   s   €€€r-   Ú_swapÚ2DingTalkAdapter._fire_done_reaction.<locals>._swapÆ  sW   øé € Ø×$Ñ$ V¨_¼aÐ@dÓ>eÐnrÐ$Ós×sÐsØ×$Ñ$ V¨_¼aÐ@`Ó>aÐjoÐ$Óp×pÒpñ tÙpùs!   ƒ"A¥A¦%AÁAÁAÁA)r¥   r¥   )rÑ   r‰  rÐ   re   r  rŒ  )rG   r  r^   r¨  rŸ  r§  s   f&  @@r-   Ú_fire_done_reactionÚ#DingTalkAdapter._fire_done_reaction½  s    ú€ à�d×,Ñ,Ô,ÙØ×Ñ×"Ñ" 7Ô+Ø×$Ñ$×(Ñ(¨Ó1ˆß{~¤7¨3°¸dÓ#C×#IÐ#IÀrÌ7ÐSVÐXiÐkoÓKp×KvÐKvÐtvÑ"wð  EMÑˆ�ßŸ?Ù÷	qò 	qð 	�‰‘u“wÖr/   c                ó$   <€ V ^8„  d   QhRS[ RR/# ©r&   r}  r(   Nr
   )r,   r>   s   "€r-   r.   r±   Ë  s   ø€ ÷ %uñ %u©ð %u¸Dñ %ur/   c              ƒ  óÀ  a"  € \        SRR4      ;'       g     \        P                  ! 4       P                  pV P                  P                  V4      '       d"   \        P                  RV P                  V4      # V3R lR 4       w  r4rV\        \        SRR4      4      R8H  pT;'       g    TpT;'       g    TpV P                  WF4      '       g"   \        P                  RV P                  Wd4      # T P                  SV P                  S4      ;'       g    R	Wx4      '       g"   \        P                  R
V P                  W(4      # V'       d+   SV P                  V&   V P                  P                  V4       \        SRR4      ;'       g    R	p	V	'       dŸ   V'       d—   \         P#                  V	4      '       d|   \%        V P&                  4      \(        8¼  d8   V P&                  P+                  \-        \/        V P&                  4      4      4       T	\        SR^ 4      ;'       g    ^ 3V P&                  V&   V P1                  S4      G Rj  x€L
  V P                  S4      p
V P3                  S4      w  r¼pV
'       g)   V'       g!   \        P                  RV P                  4      # T P5                  T\        SRR4      V'       d   RMRYEV'       d   TMRVR7      p\        SRR4      p V'       d-   \6        P8                  ! \;        V4      R,          \<        R7      M\6        P>                  ! \<        R7      p\        P                  RV P                  YX'       d
   VR,          MRV
'       d
   V
R,          MR4       V PG                  \I        W«WâSWÍVR7      4      G Rj  x€L
  R#  ELZ  \@        \B        \D        3 d    \6        P>                  ! \<        R7      p L£i ; i L@5i)z-Process an incoming DingTalk chatbot message.rž  Nz#[%s] Duplicate message %s, skippingc              3   óR   <"  € T F  p\        SVR 4      ;'       g    R x € K  	  R# 5i)r¥   N)r  )rS   Úkr}  s   & €r-   rU   Ú.DingTalkAdapter._on_message.<locals>.<genexpr>Ð  s7   øé € ð  Doñ  lnÐfgÄGÈGÐUVÐXZÓD[×DaÐDaÐ_aÔDaó  lnùs   ƒ'œ'Úconversation_typeÚ1Ú2zH[%s] Dropping message from non-allowlisted user staff_id=%s sender_id=%sr¥   zM[%s] Dropping group message that failed mention gate message_id=%s chat_id=%sÚsession_webhookÚsession_webhook_expired_timez[%s] Empty message, skippingÚconversation_titleÚgroupÚdm)r  Ú	chat_nameÚ	chat_typeÚuser_idÚ	user_nameÚuser_id_altrž  Ú	create_atr¾   ©Útzz[%s] Message from %s in %s: %s:Né   NÚ?:NéP   Nz(media))rs  Úmessage_typeÚsourcerž  Úraw_messageÚ
media_urlsÚmedia_typesÚ	timestamp)rŸ  rj  Úsender_nickrk  )%r  ÚuuidÚuuid4ÚhexrÎ   Úis_duplicaterß   r  rá   r4   ro  r…  Ú_extract_textrÐ   rÑ   r‹  Ú_DINGTALK_WEBHOOK_REÚmatchrf   rÏ   Ú_SESSION_WEBHOOKS_MAXr“  ÚnextÚiterÚ_resolve_media_codesÚ_extract_mediaÚbuild_sourcer   ÚfromtimestampÚintr   ri   Ú
ValueErrorÚOSErrorr3   Úhandle_messager   )rG   r}  r§  rŸ  rj  rË  rk  r~  r  rµ  rs  Úmsg_typerÈ  rÉ  rÆ  r¿  rÊ  s   &f               r-   Ú_on_messageÚDingTalkAdapter._on_messageË  sb  øé € ä˜ ,°Ó5×IÐI¼¿º»×9IÑ9IˆØ�;‰;×#Ñ# F×+Ò+Ü—<‘<Ð EÀtÇyÁyÐRXÓYÐYô Doñ  lnó  DoÑ@ˆ KÜ”w˜wÐ(;¸SÓAÓBÀcÑIˆØ!×.Ð. YˆØ!×.Ð. YˆØ×$Ñ$ Y×@Ò@Ü—<‘<Ð jÐlp×luÑluð  xGó  Sð  SØ×+Ñ+¨G°T×5GÑ5GÈÓ5P×5VÐ5VÐTVÐX`×jÒjÜ—<‘<Ð oÐqu×qzÑqzð  }Có  Mð  MçØ.5ˆD×"Ñ" 7Ñ+Ø×"Ñ"×*Ñ*¨7Ô3Ü! 'Ð+<¸dÓC×IÐIÀrˆßŸwÔ+?×+EÑ+EÀo×+VÒ+VÜ�4×)Ñ)Ó*Ô.CÔCØ×&Ñ&×*Ñ*¬4´°T×5KÑ5KÓ0LÓ+MÔNØ/>ÄÈÐQoÐqrÓ@s×@xÐ@xÐwxÐ.yˆD×"Ñ" 7Ñ+Ø×'Ñ'¨Ó0×0Ð0Ø×!Ñ! 'Ó*ˆØ,0×,?Ñ,?ÀÓ,HÑ)ˆ˜kßŸJÜ—<‘<Ð >ÀÇ	Á	ÓJÐJØ×"Ñ"¨7¼gÀgÐOcÐeiÓ>j÷  BJÑv}ð  PTØ+4×l{ÑYhð  BFØ.4ð #ó 6ˆô ˜G [°$Ó7ˆ	ð	-ßQZœ×.Ò.¬s°9«~ÀÕ/DÌÕMÔ`h×`lÒ`lÔpsÔ`tˆIô 	�‰Ð5°t·y±yÀ+Ö_fÈwÐWZÎ|Ðlo÷  CÐquÐvyÖqzð  IRô  	SØ×!Ñ!¤,°DÐX^ð  @GØ:DÐirô#tó u÷ 	uò 	uò 	1øô œG¤YÐ/ô 	-Ü Ÿš¬Ô,ŠIð	-úñ	uùs‰   ƒAOÁAOÂ7AOÄ6OÅ=OÆ
OÆOÆOÆ9A)OÈ#%OÉN"É	8OÊA#OË&AN% Ì54OÍ*1OÎOÎOÎ%1OÏOÏOÏOc                ó    <€ V ^8„  d   QhRS[ /# ©r&   r}  r
   )r,   r>   s   "€r-   r.   r±   ô  s   ø€ ÷ &ñ &¡nñ &r/   c                ó   € \        V4      # rA   )r"   )rG   r}  s   &&r-   r×  ÚDingTalkAdapter._extract_mediaô  s   € Ü˜WÓ%Ð%r/   c                ón   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[S[S[ S[3,          ,          RS[/# )r&   r  ÚcontentÚreply_toÚmetadatar(   )r4   r   r¡   r   r   )r,   r>   s   "€r-   r.   r±   ÷  sL   ø€ ÷ ';ñ ';¡#ð ';±ð ';¹xÉ½}ð ';Ñ_gÑhlÑmpÑruÐmuÕhvÕ_wð ';ñ  DNñ ';r/   c              ƒ  ó(  "  € T;'       g    / p\         P                  RV P                  T\        V P                  ;'       d    V P
                  4      4       VP                  R4      ;'       g#    V P                  V4      ;'       g    R^ ,          pV'       g/   \         P                  RV P                  V4       \        RRR7      # V P                  '       g   \        RRR7      # V P                  P                  V4      pVRJpV P                  '       dÎ   V'       dÆ   V P
                  '       d´   V P                  V4      G Rj  x€L
  V P                  WW'R	7      G Rj  x€L
 pV'       dX   VP                  '       dF   V'       d   V P                  V4       V# W P                   P#                  V/ 4      VP$                  &   V# \         P                  R
V P                  4       \         P                  RV P                  4       RRRRRRV P'                  VRV P(                   4      //p	 V P                  P+                  WYRR7      G Rj  x€L
 p
V
P,                  R8  dK   V'       d   V P                  V4       \        R\.        P0                  ! 4       P2                  R,          R7      # \         P                  RV P                  V
P,                  V
P4                  R,          4       \        RRV
P,                   RV
P4                  R,           2R7      #  ELÑ EL¹ LÐ  \6        P8                   d    \        RRR7      u # \:         dB   p\         P=                  RT P                  T4       \        R\?        T4      R7      u Rp?# Rp?ii ; i5i)zPSend a reply via AI Card (when configured) or DingTalk session webhook markdown.z&[%s] send() chat_id=%s card_enabled=%srµ  z,[%s] No valid session_webhook for chat_id=%sFzJNo valid session_webhook available. Reply must follow an incoming message.©Úsuccessrø   zHTTP client not initializedNr‘  z1[%s] AI Card send failed, falling back to webhookz[%s] Sending via webhookÚmsgtypeÚmarkdownÚtitleÚHermesrs  g      .@)rd  rÛ   r$   TºNé   N©rë  rž  z[%s] Send failed HTTP %d: %s:NéÈ   NzHTTP z: z#Timeout sending message to DingTalkz[%s] Send error: %s©r¥   ) rß   r  rá   r+   r³   r´   re   Ú_get_valid_webhookrà   r   rË   rÐ   r=  Ú_create_and_stream_cardrë  rª  rÒ   Ú
setdefaultrž  Ú_normalize_markdownÚMAX_MESSAGE_LENGTHÚpostÚstatus_coderÌ  rÍ  rÎ  rs  r—   ÚTimeoutExceptionrZ   rø   r4   )rG   r  ræ  rç  rè  rµ  Úcurrent_messageÚis_final_replyÚresultÚpayloadÚresprü   s   &&&&&       r-   ÚsendÚDingTalkAdapter.send÷  s  é € à—>�>˜rˆÜ�‰Ð=¸t¿y¹yÈ'ÔSWÐX\×XnÑXn÷  YBð  YBÐsw÷  tBñ  tBó  TCô  	DØ"Ÿ,™,Ð'8Ó9×kÐk¸d×>UÑ>UÐV]Ó>^×>gÐ>gÐbgÐijÕ=kˆßÜ�N‰NÐIÈ4Ï9É9ÐV]Ô^Ü eÐ3ô  Að  AØ× × Ð Ü eÐ3PÔQÐQØ×0Ñ0×4Ñ4°WÓ=ˆð "¨Ð-ˆØ×!×!Ð!§o¸$¿.¿.¸.Ø×0Ñ0°Ó9×9Ð9Ø×7Ñ7¸ÐRYÐ7Ós×sˆFß˜&Ÿ.Ÿ.˜.ß!Ø×,Ñ,¨WÔ5ð �ð X_×)Ñ)×4Ñ4°W¸bÓAÀ&×BSÑBSÑTØ�Ü�N‰NÐNÐPT×PYÑPYÔZÜ�‰Ð/°·±Ô;Ø˜j¨*°wÀÈ&ÐRV×RjÑRjÐkrð  tMÐuy÷  vMñ  vMð  lNó  SOð  7Pð  Qˆð	;Ø×*Ñ*×/Ñ/°ÐW[Ð/Ó\×\ˆDØ×Ñ #Ô%ß!Ø×,Ñ,¨WÔ5Ü!¨$¼4¿:º:»<×;KÑ;KÈCÕ;PÔQÐQÜ�N‰NÐ9¸4¿9¹9Àd×FVÑFVÐX\×XaÑXaÐbfÕXgÔhÜ e°U¸4×;KÑ;KÐ:LÈBÈtÏyÉyÐY]ÍÐN_Ð3`ÔaÐaò% :Úsñ ]øô ×%Ñ%ô 	ZÜ eÐ3XÔYÒYÜô 	;Ü�L‰LÐ.°·	±	¸1Ô=Ü e´3°q³6Ô:Õ:ûð	;üsÏ   ‚A NÁ,NÁ0NÂ	NÂ?NÃ=NÄNÄ!NÄ3NÅLÅNÅ"LÅ#NÅ/NÆNÆ	B#NÈ- L  ÉLÉL  É+AL  Ê,NÊ-A*L  ÌNÌNÌL  Ì "NÍNÍNÍNÍ6N
ÎNÎNÎ
NÎNc                ó$   <€ V ^8„  d   QhRS[ RR/# r�  rR   )r,   r>   s   "€r-   r.   r±      s   ø€ ÷ ;ñ ;©ð ;Àñ ;r/   c              ƒ  ó   "  € R# 5i)z,DingTalk does not support typing indicators.NrX   )rG   r  rè  s   &&&r-   Úsend_typingÚDingTalkAdapter.send_typing   s   é ‚ ùs   ‚c          
      óX   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[S[ ,          RS[/# )r&   r  Ú	image_urlÚcaptionrç  r(   ©r4   r   r   )r,   r>   s   "€r-   r.   r±   #  sG   ø€ ÷ Yñ Y©ð Y¹ð YÁhÉsÅmð YÑfnÑorÕfsð Yñ  OYñ Yr/   c              ƒ  ón   "  € RV R2pT P                  Y'       d   V RV 2MTWER7      G Rj  x€L
 #  L5i)zVRender a remote image inline via markdown (session webhook has no native attachments).z	![image](Ú)z

)r  ræ  rç  rè  N)r  )rG   r  r	  r
  rç  rè  Úimage_blocks   &&&&&& r-   Ú
send_imageÚDingTalkAdapter.send_image#  sP   é € à! ) ¨AÐ.ˆØ—Y‘Y wÖY`¸7¸)À4ÈÀ}Ñ8UÐfqð  }E�Yó  Y÷  Yð  	Yñ  Yùs   ‚,5®3¯5c          
      óX   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[S[ ,          RS[/# )r&   r  Ú
image_pathr
  rç  r(   r  )r,   r>   s   "€r-   r.   r±   (  sH   ø€ ÷ eñ e©Sð e¹cð eÉHÑUXÍMð eÑltÑuxÕlyð eñ  _iñ er/   c              ‹  ó:   "  € \        R\        R,          R7      # 5i)z+Webhook replies cannot upload local images.Frê  )zimage uploadszmedia upload©r   Ú_NO_LOCAL_UPLOAD)rG   r  r  r
  rç  rè  Úkwargss   &&&&&&,r-   Úsend_image_fileÚDingTalkAdapter.send_image_file(  s   é € ä %Ô/?ÐBcÕ/cÔdÐdùó   ‚c          
      óX   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[S[ ,          RS[/# )r&   r  Ú	file_pathr
  Ú	file_namer(   r  )r,   r>   s   "€r-   r.   r±   ,  sH   ø€ ÷ hñ h©3ð h¹3ð hÉÑRUÍð hÑjrÑsvÕjwð hñ  lvñ hr/   c              ‹  ó:   "  € \        R\        R,          R7      # 5i)z*Webhook replies cannot upload local files.Frê  )zfile attachmentszmessage sendr  )rG   r  r  r
  r  rç  rè  r  s   &&&&&&&,r-   Úsend_documentÚDingTalkAdapter.send_document,  s   é € ä %Ô/?ÐBfÕ/fÔgÐgùr  c                ó<   <€ V ^8„  d   QhRS[ RS[S[ S[3,          /# ©r&   r  r(   )r4   r¡   r   )r,   r>   s   "€r-   r.   r±   0  s'   ø€ ÷ Zñ Z©3ð Z±4¹¹S¸µ>ñ Zr/   c              ƒ  óF   "  € RTRRVP                  4       9   d   R/# R/# 5i)z0Return basic info about a DingTalk conversation.rá   ra   r¸  r¹  )rÇ   )rG   r  s   &&r-   Úget_chat_infoÚDingTalkAdapter.get_chat_info0  s*   é € à˜ °G¸w¿}¹}»Ô4N¨ÐYÐYÐTXÐYÐYùs   ‚!c                óL   <€ V ^8„  d   QhRS[ RS[S[S[ S[3,          ,          /# r!  )r4   r   r\   rÚ  )r,   r>   s   "€r-   r.   r±   4  s(   ø€ ÷ ñ ©#ð ±(¹5ÁÁcÀ½?Õ2Kñ r/   c                óZ  € V P                   P                  V4      pV'       d
   V^,          M^ pV'       dk   V^ 8”  dd   \        \        P                  ! \
        R7      P                  4       R,          4      R,           V8¼  d   V P                   P                  VR4       R# T;'       g    R# )zGGet a non-expired session webhook for chat_id (5-minute safety margin).rÀ  r¾   Nià“ )rÏ   re   rÚ  r   ri   r   rÊ  r“  )rG   r  rî   Úexpired_time_mss   &&  r-   rõ  Ú"DingTalkAdapter._get_valid_webhook4  s†   € à×%Ñ%×)Ñ)¨'Ó2ˆß%)˜$˜qž'¨qˆß˜°Ô2´s¼8¿<º<Ì3Ô;O×;YÑ;YÓ;[Ð^bÕ;bÓ7cÐfsÕ7sð  xGô  8GØ×"Ñ"×&Ñ& w°Ô5ÙØ�|ˆ|�tÐr/   r’  c                óH   <€ V ^8„  d   QhRS[ RS[RS[ RS[RS[S[,          /# )r&   r  r}  ræ  r’  r(   )r4   r   r+   r   r   )r,   r>   s   "€r-   r.   r±   =  sA   ø€ ÷ ñ ±Sð Á3ð ÑQTð Ñcgð Ñs{ñ  }Gõ  tHñ r/   c             ƒ  ó$  "  €  V P                  4       G Rj  x€L
 pV'       g   R# R\        P                  ! 4       P                  R,           2\        rv\        \        VRR4      4      R8H  p\        VRR4      ;'       g    Rp	VP                  V P                  VR	VP                  R
R/R7      VP                  RR7      VP                  RR7      R7      p
V P                  V P                  P                  W§P                  V4      G Rj  x€L
  V'       d:   R\        VRR4      ;'       g    R 2pRVP!                  V P"                  R7      /pMBV	'       d   RV	 2pRVP%                  RR7      /pM \&        P)                  RV P*                  4      # VP,                  ! R!RVR^RV/VB pV P                  V P                  P.                  W×P0                  V4      G Rj  x€L
  V P3                  WeW4R7      G Rj  x€L
  \&        P5                  RV P*                  V'       d   RMRV4       \7        RVR7      #  EL! EL0 L^ LE  \8         dA   p\&        P)                  R T P*                  T\:        P<                  ! 4       4        Rp?R# Rp?ii ; i5i)"znCreate, deliver and stream an AI Card; ``finalize=False`` leaves it open for ``edit_message`` by out_track_id.NÚhermes_rð  r²  r³  r´  rk  r¥   ÚSTREAMræ  )Úcard_param_mapT)Úsupport_forward)rÀ   r™  Úcallback_typeÚ	card_dataÚim_group_open_space_modelÚim_robot_open_space_modelzdtv1.card//IM_GROUP.rŸ  Úim_group_open_deliver_model)r½   zdtv1.card//IM_ROBOT.Úim_robot_open_deliver_modelÚIM_ROBOT)Ú
space_typez4[%s] AI Card skipped: missing sender_staff_id for DMr™  Úuser_id_typeÚopen_space_idr‘  z[%s] AI Card %s: %szcreated+finalizedzcreated (streaming)rò  z![%s] AI Card create failed: %s
%srX   )r”  rÌ  rÍ  rÎ  Údingtalk_card_modelsr4   r  ÚCreateCardRequestr³   ÚCreateCardRequestCardDataÚ&CreateCardRequestImGroupOpenSpaceModelÚ&CreateCardRequestImRobotOpenSpaceModelÚ	_sdk_callr´   Úcreate_card_with_options_asyncÚCreateCardHeadersÚ)DeliverCardRequestImGroupOpenDeliverModelrÍ   Ú)DeliverCardRequestImRobotOpenDeliverModelrß   rà   rá   ÚDeliverCardRequestÚdeliver_card_with_options_asyncÚDeliverCardHeadersr–  rî   r   rZ   Ú	tracebackÚ
format_exc)rG   r  r}  ræ  r’  r˜  r™  r   r~  rk  Úcreate_requestr8  Údeliver_modelÚdeliver_requestrü   s   &&&&$          r-   rö  Ú'DingTalkAdapter._create_and_stream_card=  s§  é € ð	Ø×0Ñ0Ó2×2ˆEßÙØ%,¬T¯ZªZ«\×-=Ñ-=¸cÕ-BÐ,CÐ#DÔFZ˜&Üœ7 7Ð,?ÀÓEÓFÈ#ÑMˆHÜ% gÐ/@À"ÓE×KÐKÈˆOØ#×5Ñ5Ø!%×!7Ñ!7ÀlÐbjØ ×:Ñ:È9ÐVXÈ/Ð:ÓZØ*0×*WÑ*WÐhlÐ*WÓ*mØ*0×*WÑ*WÐhlÐ*WÓ*mð	 6ó oˆNð
 —.‘. §¡×!NÑ!NÐP^×`xÑ`xÐzó  A÷  Að  AßØ"6´w¸wÐHYÐ[]Ó7^×7dÐ7dÐbdÐ6eÐ f�Ø!>À×@pÑ@pð  }A÷  }Mñ  }MÐ@pó  ANð  !O‘ß Ø"6°Ð6GÐ H�Ø!>À×@pÑ@pð  }GÐ@pó  AHð  !I‘ä—~‘~Ð&\Ð^b×^gÑ^gÓhÐhØ$×7Ò7ñ  QÀ\ð  QÐ`að  QÐq~ð  Qð  CPñ  QˆOØ—.‘. §¡×!OÑ!OÐQ`×b{Ñb{ð  ~Có  D÷  Dð  DØ×+Ñ+¨LÀÐ+Ó\×\Ð\Ü�K‰KÐ-¨t¯y©y×QYÑ:MÐ_tð  wCô  DÜ d°|ÔDÐDò1 3ò Añ DÙ\øô ô 	Ü�N‰NÐ?ÀÇÁÈAÌy×OcÒOcÓOeÔfÝûð	üs¤   ‚J„I —H8˜I ¤J¦C%I ÄH;ÄI ÄI Ä-+I Å9I ÆJÆAI ÇH>Ç I Ç:I Ç;&I È"I È7JÈ8I È;I È>I É I ÉJÉ5JÊJÊJÊJc          
      ó8   <€ V ^8„  d   QhRS[ RS[ RS[ RS[RS[/# )r&   r  rž  ræ  r’  r(   )r4   r+   r   )r,   r>   s   "€r-   r.   r±   ]  s2   ø€ ÷ ;ñ ;©#ð ;¹3ð ;Éð ;Ñ[_ð ;Ñlvñ ;r/   c             ƒ  óR  "  € V P                   '       g   \        RRR7      # V'       d   V P                  4       G Rj  x€L
 MRpV'       g   \        RV'       g   RR7      # RR7      #  V P                  W%W4R7      G Rj  x€L
  V'       d�   V P                  P                  V/ 4      P                  VR4       V P                  P                  V4      '       g   V P                  P                  VR4       \        P                  RV P                  V4       V P                  V4       MW0P                  P                  V/ 4      V&   \        R	VR
7      #  EL LÖ  \         dB   p\        P                  RT P                  T4       \        R\        T4      R7      u Rp?# Rp?ii ; i5i)z«Stream updated content to an AI Card; ``message_id`` is the creating ``send()``'s out_track_id (callers track their own ids so parallel flows on one chat don't interfere).Fz/AI Cards are not configured for message editingrê  Nzmessage_id requiredzNo access tokenr‘  z![%s] AI Card finalized (edit): %sTrò  z[%s] Card edit failed: %s)r¶   r   r”  r–  rÒ   re   r“  rß   r  rá   rª  r÷  rZ   rà   r4   )rG   r  rž  ræ  r’  r˜  rü   s   &&&&$  r-   Úedit_messageÚDingTalkAdapter.edit_message]  sR  é € à×,×,Ð,Ü eÐ3dÔeÐeß2<�d×,Ñ,Ó.×.Ð.À$ˆßÜ e×PZÐ3HÔrÐrÐ`qÔrÐrð	;Ø×+Ñ+¨J¸wÐ+ÓZ×ZÐZßØ×%Ñ%×)Ñ)¨'°2Ó6×:Ñ:¸:ÀtÔLØ×,Ñ,×0Ñ0°×9Ò9Ø×)Ñ)×-Ñ-¨g°tÔ<Ü—‘Ð@À$Ç)Á)ÈZÔXØ×(Ñ(¨Õ1àLS×%Ñ%×0Ñ0°¸"Ó=¸jÑIÜ d°zÔBÐBò /ñ [øô ô 	;Ü�N‰NÐ6¸¿	¹	À1ÔEÜ e´3°q³6Ô:Õ:ûð	;üsj   ‚'F'ªF'½E¾F'ÁF'Á)E Á?EÂ E ÂAE ÃA9E ÅF'ÅE ÅF$Å#6FÆF$ÆF'ÆF$Æ$F'c                ó    <€ V ^8„  d   QhRS[ /# )r&   r˜  rR   )r,   r>   s   "€r-   r.   r±   t  s   ø€ ÷ wñ w¹Sñ wr/   c              ƒ  ód   "  € V ! W! VR7      \         P                  ! 4       4      G Rj  x€L
 #  L5i)ud   ``await method(request, headers_cls(token), RuntimeOptions())`` â€” the alibabacloud SDK call shape.)Úx_acs_dingtalk_access_tokenN)Útea_util_modelsÚRuntimeOptions)ÚmethodÚrequestÚheaders_clsr˜  s   &&&&r-   r>  ÚDingTalkAdapter._sdk_calls  s+   é € ñ ˜G [ÈUÔ%SÔUd×UsÒUsÓUuÓv×vÐvÑvùs   ‚'0©.ª0c          
      ó6   <€ V ^8„  d   QhRS[ RS[ RS[ RS[RR/# )r&   r™  r˜  ræ  r’  r(   Nrl  )r,   r>   s   "€r-   r.   r±   x  s:   ø€ ÷ Uñ U±sð UÁ3ð UÑQTð UÑ`dð UÐquñ Ur/   c           
   ƒ  ó  "  € \         P                  ! V\        \        P                  ! 4       4      RVRV P
                   RVRR7      pV P                  V P                  P                  V\         P                  V4      G Rj  x€L
  R#  L5i)z&Stream content to an existing AI Card.ræ  NTF)r™  Úguidrh   ræ  Úis_fullÚis_finalizeÚis_error)
r9  ÚStreamingUpdateRequestr4   rÌ  rÍ  rù  r>  r´   Ú#streaming_update_with_options_asyncÚStreamingUpdateHeaders)rG   r™  r˜  ræ  r’  Ústream_requests   &&&&& r-   r–  Ú$DingTalkAdapter._stream_card_contentx  s‚   é € ä-×DÒDØ%¬C´·
²
³Ó,=À9ÐV]Ð^wÐ`d×`wÑ`wÐVxØ h¸ô
ˆð �n‰n˜TŸ^™^×OÑOÐQ_Ôau÷  bMñ  bMð  OTó  U÷  	Uô  	Uùs   ‚B BÂB	ÂBc                ó0   <€ V ^8„  d   QhRS[ S[,          /# r‹   )r   r4   )r,   r>   s   "€r-   r.   r±   €  s   ø€ ÷ ñ ©±#­ñ r/   c              ƒ  ó  "  € V P                   '       g   R#  \        P                  ! V P                   P                  4      G Rj  x€L
 #  L  \         d-   p\
        P                  RT P                  T4        Rp?R# Rp?ii ; i5i)zDGet access token via the SDK's cached (sync, requests-based) getter.Nz#[%s] Failed to get access token: %s)rÉ   rò   r9  Úget_access_tokenrZ   rß   rø   rá   )rG   rü   s   & r-   r”  Ú!DingTalkAdapter._get_access_token€  sc   é € à×"×"Ð"Ùð	Ü ×*Ò*¨4×+>Ñ+>×+OÑ+OÓP×PÐPÑPøÜô 	Ü�L‰LÐ>ÀÇ	Á	È1ÔMÝûð	üs@   ‚B˜-A ÁA
ÁA Á	BÁ
A ÁBÁ!A>Á8BÁ>BÂBr¥  c          
      ó6   <€ V ^8„  d   QhRS[ RS[ RS[ RS[RR/# )r&   Úopen_msg_idÚopen_conversation_idÚ
emoji_namer¥  r(   Nrl  )r,   r>   s   "€r-   r.   r±   Š  s>   ø€ ÷ [ñ [©sð [É#ð [Ñ[^ð [Ñkoð [ð  }Añ [r/   c          	   ƒ  óž  "  € V P                   '       d   V'       d	   V'       g   R# V'       d   RMRp V P                  4       G Rj  x€L
 pV'       g   R# \        V,          w  rxrš\        \        V4      ! \
        W3\        R7      p\        \        V4      ! V P                  W^W;R7      pV P                  \        V P                   V
4      V\        \        V	4      V4      G Rj  x€L
  \        P                  RV P                  WSVR,          4       R#  LÌ L1  \         d(    \        P                  RT P                  TR	R
7        R# i ; i5i)z/Add (or recall) an emoji reaction on a message.Nr¥  Úreply)Ú
emotion_idÚemotion_namers  Úbackground_id)r½   ri  rj  Úemotion_typero  Útext_emotionz#[%s] _send_emotion: %s %s on msg=%s:Né   Nz[%s] _send_emotion %s failedT)r_   )rÌ   r”  Ú_EMOTION_SDKr  Údingtalk_robot_modelsÚ_EMOTION_IDÚ_EMOTION_BGrÍ   r>  rß   rî   rá   rZ   r  )rG   ri  rj  rk  r¥  Úactionr˜  Útext_emotion_clsÚrequest_clsrW  Ú
sdk_methodrr  rV  s   &&&&$        r-   r¦  ÚDingTalkAdapter._send_emotionŠ  s   é € à��ˆ§k×9MÙß#‘¨ˆð	[Ø×0Ñ0Ó2×2ˆEßÙÜEQÐRXÕEYÑBÐ¨;Ü"Ô#8Ð:JÔKÔWbÐq{ô  ]hô  iˆLÜÔ3°[ÔAÈT×M]ÑM]ÐkvØOPÐ_iôFˆGà—.‘.¤¨¯©¸*Ó!EÀwÔPWÔXmÐozÓP{ð  ~Có  D÷  Dð  DÜ�K‰KÐ=¸t¿y¹yÈ&Ð^iÐjmÕ^nÖoñ 3ñ Døäô 	[Ü�L‰LÐ7¸¿¹ÀFÐUYˆL×Zð	[üsh   ‚E�E¥	E¯E´D ÁDÁD ÁEÁBD Ã$DÃ%-D ÄEÄD ÄD Ä.E
ÅEÅ	E
Å
Ec                ó$   <€ V ^8„  d   QhRS[ RR/# r­  r
   )r,   r>   s   "€r-   r.   r±   œ  s   ø€ ÷ 	Añ 	A±.ð 	AÀTñ 	Ar/   c              ƒ  ó  "  € V P                  4       G Rj  x€L
 pV'       g   R# \        VRR4      ;'       g    V P                  p\        V4       UUu. uF5  w  rE\	        WE4      '       d   \        WER4      MVP                  V4      WE3NK7  	  pppV UUUu. uF"  w  rtqW'       g   K  V P                  WsW$V4      NK$  	  ppppV'       d!   \        P                  ! VRR/ G Rj  x€L
  R# R#  L×u uppi u upppi  L5i)zKResolve download codes in the message to real URLs (in place, in parallel).Nr½   r6  T)	r”  r  rÂ   r!   r8  re   Ú_fetch_download_urlrò   r<  )	rG   r}  r˜  r½   Úobjrh   ÚpairsÚcodeÚtaskss	   &&       r-   rÖ  Ú$DingTalkAdapter._resolve_media_codesœ  só   é € à×,Ñ,Ó.×.ˆßÙÜ˜W l°DÓ9×LÐL¸T¿_¹_ˆ
ô mCð  DKô  mLô  Mñ  mLÑ`hÐ`c¬W°S×->Ò->”'˜# DÔ)ÀCÇGÁGÈCÃLÐRUÓ[ñ  mLˆñ  MÙchÕqÑchÑQ_ÐQUÐ\_ÓlpÔL�×)Ñ)¨$¸EÈÖLÑchˆÒqßÜ—.’. %Ð@¸4Ñ@×@Ò@ñ ñ /ùó MùÜqá@ùsI   ‚C?–C.—C?£C?¹C?Á;C0Â	C?ÂC6Â)C6Ã %C?Ã%C=Ã&	C?Ã0C?c          
      ó6   <€ V ^8„  d   QhRS[ RS[ RS[ RS[ RR/# )r&   r‚  r½   r˜  rh   r(   NrR   )r,   r>   s   "€r-   r.   r±   §  s9   ø€ ÷ Wñ W©cð W¹sð WÉ3ð WÑZ]ð WÐbfñ Wr/   c              ƒ  óÜ  "  € V P                   '       g!   \        P                  RV P                  4      #  V P	                  V P                   P
                  \        P                  ! WR7      \        P                  V4      G Rj  x€L
 pV'       d   VP                  MRpV'       d   \        VRR4      MRpV'       g$   \        P                  RV P                  V4       R# V'       d    \        WE4      '       d   \        WEV4       R# V'       d   \        V\        4      '       d   W„V&   R# R# R#  L«  \         d-   p	\        P!                  RT P                  Y4        Rp	?	R# Rp	?	ii ; i5i)zXFetch the download URL for one code via the robot SDK and write it back to ``obj[key]``.z9[%s] Robot SDK not initialized, cannot resolve media code)Údownload_coder½   NÚdownload_urlz9[%s] Failed to download media: empty response for code %sz&[%s] Error resolving media code %s: %s)rÌ   rß   rà   rá   r>  Ú.robot_message_file_download_with_options_asyncru  ÚRobotMessageFileDownloadRequestÚRobotMessageFileDownloadHeadersÚbodyr  r8  Úsetattrr2   r¡   rZ   rø   )
rG   r‚  r½   r˜  r€  rh   ÚresponserŒ  Úurlrü   s
   &&&&&&    r-   r  Ú#DingTalkAdapter._fetch_download_url§  s  é € à��ˆÜ—>‘>Ð"]Ð_c×_hÑ_hÓiÐið	WØ!Ÿ^™^¨D¯O©O×,jÑ,jÜ,A×,aÒ,aÐptô  -MÜ,A×,aÑ,aÐchój÷ jˆH÷ %-�8—=’=°$ˆDß9=”'˜$ °Ô5À4ˆCßÜ—‘ÐZÐ\`×\eÑ\eÐgkÖlßœ ×*Ò*Ü˜ #Ö&ßœ C¬×.Ò.Ø�C“ñ /‘ñjøô ô 	WÜ�L‰LÐAÀ4Ç9Á9Èd×VÒVûð	Wüsw   ‚3E,¶AD2 ÂD0ÂD2 ÂD2 Â'D2 Â>!D2 ÃE,Ã!D2 Ã)D2 ÄE,ÄD2 ÄD2 Ä*E,Ä0D2 Ä2E)Ä=!E$ÅE,Å$E)Å)E,c                ó&   <€ V ^8„  d   QhRS[ RS[ /# rr  rR   )r,   r>   s   "€r-   r.   r±   »  s   ø€ ÷ 	ñ 	¡#ð 	©#ñ 	r/   c                ó  € V P                  R4      p. p\        V4       FÎ  w  r4V^ 8”  d   W^,
          ,          P                  4       MRpV'       dV   \        P	                  VP                  4       4      '       d-   \        P	                  V4      '       g   VP                  R4       TP                  VP                  4       P                  R4      '       d   VP                  4       MT4       KÐ  	  RP                  V4      # )zZWork around DingTalk renderer quirks: blank line before numbered lists, dedent ``` fences.Ú
r¥   z```)	r…   Ú	enumerater†   Ú_NUMBERED_RErÒ  ÚappendÚ
startswithÚlstripr]   )rs  ÚlinesÚoutÚiÚlineÚprevs   &     r-   rø  Ú#DingTalkAdapter._normalize_markdownº  s³   € ð —
‘
˜4Ó ˆØˆÜ  Ö'‰GˆAØ+,¨q¬5�5˜Q�•<×%Ñ%Ô'°bˆDßœ×*Ñ*¨4¯:©:«<×8Ò8Ä×ASÑASÐTX×AYÒAYØ—
‘
˜2”Ø�J‰J¨¯
©
«×(?Ñ(?À×(FÒ(F�t—{‘{”}ÈDÖQñ	 (ð
 �y‰y˜‹~Ðr/   )rÈ   rÓ   r´   r³   rÂ   rÃ   rÎ   rÑ   rË   rÅ   rÐ   rÍ   rÌ   r  r  rÏ   rÉ   rÊ   rÒ   rô  )NNrA   )NNN)NNNN)F)2rb   rm   rn   ro   rp   rù  Úpropertyr¶   ÚREQUIRES_EDIT_FINALIZErC   rý   rõ   r	  r  r/  rA  rÆ   rQ  rW  rÄ   ro  rz  r…  rŒ  r=  rª  rß  Ústaticmethodr#   rÐ  r×  r  r  r  r  r  r#  rõ  rö  rN  r>  r–  r”  r¦  rÖ  r  rø  rr   rs   rt   ru   s   @@r-   r¯   r¯   Á   sÿ  ù‡ € ñsð ,Ðà÷?ó ð?ð 6Ð÷2ó 2ð&°E÷ ò ÷@+ð +÷0)!ð )!ðVÀ$÷ ò ÷=ò =÷4ð 4÷@bð b÷bð b÷
Lð L÷Mð M÷qð q÷
mð m÷
ð 
÷7ð 7÷
	að 	a÷ ð  ÷%uð %uñN ! Ó.€M÷&ð &÷';ò ';÷R;ò ;÷Yò Y÷
eò e÷hò h÷Zð Z÷ð ðÐjn÷ ò ð@;Ðbg÷ ;ò ;ð, ÷wó ðw÷Uò U÷ð ð[Ðrw÷ [ò [÷$	Að 	A÷Wð Wð& ÷	ó ÷	ð 	r/   r¯   c                   ó|   a a€ ] tR tRt oRtRV3R lV 3R llltV3R lR ltV3R lR ltV3R	 lR
 ltRt	Vt
V ;t# )rñ   iÇ  zrChatbotHandler forwarding to the adapter (SDK >= 0.20: async ``process()`` gets a CallbackMessage ``.data`` dict).c                óJ   <€ V ^8„  d   QhRS[ RS[S[P                  ,          /# )r&   ÚadapterÚloop)r¯   r   rò   ÚAbstractEventLoop)r,   r>   s   "€r-   r.   Ú_IncomingHandler.__annotate__Ê  s&   ø€ ÷ 2ñ 2¡ð 2±xÁ×@YÑ@YÕ7Zñ 2r/   c                óX   <€ \         '       d   \        SV `	  4        WuV n        V n        R # rA   )rŽ   rB   rC   Ú_adapterÚ_loop)rG   r¤  r¥  rI   s   &&&€r-   rC   Ú_IncomingHandler.__init__Ê  s"   ø€ ß$Ó$Ü‰GÑÔØ$+Ð!ˆŒ�t–zr/   c                ó   <€ V ^8„  d   QhRR/# r   rX   )r,   r>   s   "€r-   r.   r§  Ï  s   ø€ ÷ ñ ˜4ñ r/   c                ó   € R# )ud   No-op hook the SDK calls on every handler before opening the WebSocket (missing â†’ AttributeError).NrX   rµ   s   &r-   Ú	pre_startÚ_IncomingHandler.pre_startÏ  s   € ár/   c                ó    <€ V ^8„  d   QhRS[ /# râ  )r   )r,   r>   s   "€r-   r.   r§  Ó  s   ø€ ÷ *ñ *¡_ñ *r/   c           	   ƒ  ó  "  €  \        VP                  \        4      '       d!   \        P                  ! VP                  4      MVP                  p\
        P                  ! V4      p\        V\        4      '       d   TM/ pVP                  R4      ;'       g    VP                  R4      ;'       g    RpV'       d   \        VRR4      '       g   WCn
        \        VRR4      '       g   VP                  R4      '       d   RVn        \        VR	R4      ;'       g    R\        VR
R4      ;'       g    RreV'       dI   V'       dA   V P                  P                  V P                  P                  WV\        R4      RR7      4       \         P"                  ! V P%                  V4      4       \.        P2                  R3#   \&         d@    \(        P+                  RT P                  P,                  4       \.        P0                  R3u # i ; i5i)zpConvert to ChatbotMessage, dispatch as a background task, ACK immediately (blocking would stall SDK heartbeats).ÚsessionWebhookrµ  r¥   Nrƒ  FÚ
isInAtListTrž  rŸ  r£  r¤  z%[%s] Error preparing incoming messagerø   ÚOK)r2   Údatar4   rd  re  r   Ú	from_dictr¡   re   r  rµ  rƒ  r©  rŒ  r¦  r   rò   rô   Ú_safe_on_messagerZ   rß   Ú	exceptionrá   r   r   r   )rG   r}  rµ  Úchatbot_msgÚwebhookr§  rŸ  s   &&     r-   ÚprocessÚ_IncomingHandler.processÓ  s±  é € ð	?Ü/9¸'¿,¹,Ì×/LÒ/L”4—:’:˜gŸl™lÔ+ÐRY×R^ÑR^ˆDÜ(×2Ò2°4Ó8ˆKÜ% d¬D×1Ò1‘4°rˆDØ—h‘hÐ/Ó0×UÐU°D·H±HÐ=NÓ4O×UÐUÐSUˆGßœw {Ð4EÀt×LÒLØ.5Ô+Ü˜;¨¸×?Ò?ÀDÇHÁHÈ\×DZÒDZØ,0�Ô)Ü&-¨k¸<ÈÓ&N×&TÐ&TÐRTÔV]Ð^iÐk|ð  Có  WD÷  WJð  WJð  HJ�OßŸ/Ø—‘×'Ñ'¨¯©×(CÑ(CÀFÔ]^ð  `Dó  ^Eð  NSÐ(Có  )Tô  UÜ×Ò × 5Ñ 5°kÓ BÔCô ×#Ñ# TÐ)Ð)øô ô 	?Ü×ÑÐDÀdÇmÁm×FXÑFXÔYÜ×5Ñ5°wÐ>Ò>ð	?üsV   ‚H„BF: ÂF: Â1
F: Â<AF: Ã?F: ÄF: Ä0F: ÅA%F: Æ(HÆ:AHÈHÈHÈHc                ó$   <€ V ^8„  d   QhRS[ RR/# )r&   r¹  r(   Nr
   )r,   r>   s   "€r-   r.   r§  ç  s   ø€ ÷ [ñ [±.ð [ÀTñ [r/   c              ƒ  óÒ   "  €  V P                   P                  V4      G R j  x€L
  R #  L  \         d/    \        P	                  RT P                   P
                  4        R # i ; i5i)Nz&[%s] Error processing incoming message)r©  rß  rZ   rß   r¸  rá   )rG   r¹  s   &&r-   r·  Ú!_IncomingHandler._safe_on_messageç  sN   é € ð	[Ø—-‘-×+Ñ+¨KÓ8×8Ô8øÜô 	[Ü×ÑÐEÀtÇ}Á}×GYÑGY×Zð	[üs1   ‚A'„+ ¢)£+ §A'©+ «5A$Á A'Á#A$Á$A')r©  rª  rA   )rb   rm   rn   ro   rp   rC   r®  r»  r·  rr   rs   rt   ru   s   @@r-   rñ   rñ   Ç  s8   ù‡ € Ù|÷2õ 2÷
ð ÷*ð *÷([÷ [ð [r/   rñ   Ú	thread_idÚmedia_filesÚforce_documentc          
   ƒ  ó,  "  €  ^ RI p\        T R/ 4      ;'       g    / P	                  R4      ;'       g    \        RR4      pT'       g   \        R4      #  TP                  ! RR	7      ;_uu_4       GRj  x€L
 pTP                  TR
RRRT//R7      G Rj  x€L
 p	T	P                  4        T	P                  4       p
RRR4      GRj  x€L
  X
P	                  R^ 4      ^ 8w  d   \        RT
P	                  RR4       24      # RRRRRT/#   \         d    \        R4      u # i ; i L® L� La  + GRj  x€L 
 '       g   i     Lx; i  \         dA   p ^ RIHp T! RT 24      u Rp?#   \         d    \        RT 24      u u Rp?# i ; iRp?ii ; i5i)u²   Out-of-process delivery (standalone_sender_fn) via the static robot webhook (DINGTALK_WEBHOOK_URL / extra
``webhook_url``) â€” per-session webhooks aren't available to cron jobs.Nzhttpx not installedr    Úwebhook_urlÚDINGTALK_WEBHOOK_URLr¥   zkDingTalk not configured. Set DINGTALK_WEBHOOK_URL env var or webhook_url in dingtalk platform extra config.rÚ   r5  rì  rs  ræ  )rd  ÚerrcodezDingTalk API error: ÚerrmsgÚunknownrë  TÚplatformr”   r  )Ú_errorzDingTalk send failed: )r—   ÚImportErrorr   r  re   r¨   rã   rú  Úraise_for_statusrd  rZ   Útools.send_message_toolrÊ  )Úpconfigr  r}  rÀ  rÁ  rÂ  r—   rÄ  r   r  rµ  rü   Ú_redact_errors   &&&$$$       r-   Ú_standalone_sendrÐ  î  s€  é € ð1Ûô
 ˜7 G¨RÓ0×6Ð6°B×;Ñ;¸MÓJ×|Ð|ÔN`ÐawÐy{ÓN|€KßÜð  Hó  Ið  	Ið<Ø×$Ò$¨T×2×2Õ2°fØŸ™ [¸	À6È6ÐT]Ð_fÐSgÐ7h˜Ói×iˆDØ×!Ñ!Ô#Ø—9‘9“;ˆD÷ 3×2ð �8‰8�I˜qÓ! QÔ&ÜÐ 4°T·X±X¸hÈ	Ó5RÐ4SÐTÓUÐUØ˜4 ¨Z¸ÀGÐLÐLøô ô 1ÜÐ/Ó0Ò0ð1úñ 3Ùi÷ 3×2×2Ò2ûô ô <ð	<ÝGÙ Ð#9¸!¸Ð!=Ó>Õ>øÜô 	<ÜÐ 6°q°cÐ:Ó;×;ð	<þð	<üs÷   ‚F„D ˆFœFµFÁ
FÁE Á5D$Á6E Á9D*ÂD&Â$D*Â;E ÃD(Ã8E Ã?FÄ E ÄFÄD!ÄFÄ D!Ä!FÄ$E Ä&D*Ä(E Ä*E	Ä0D3Ä1
E	Ä<E	Ä>E ÅFÅE(Å"FÅ#FÅ(F	ÆFÆFÆFÆF	Æ	FÆFÆFc                ó   € V ^8„  d   QhRR/# r   rX   )r,   s   "r-   r.   r.   
  s   € ÷ Dñ D˜4ñ Dr/   c                 óˆ  € ^ RI Hp  ^ RIHp ^ RIHpHpHpHp ^ RI	H
p V! R4       V! RRR4      '       d   R# R	R
.pRpV! RV^ R7      ^ 8X  dD    ^ RIHp	 V	! 4       pVf	   V! R4       Te&   \        RT4       F  w  r¼T ! Y¼4       K  	  T! R4      # \        W V4       R#   \         d   p
T! RT
 R24        Rp
?
LSRp
?
ii ; i)uH   Configure DingTalk â€” QR scan (recommended) or manual credential entry.)Úsave_env_value)Úprompt_choice)ÚpromptÚprint_headerÚprint_successÚprint_warning)Údeclines_reconfigurer_  zReconfigure DingTalk?r¤   NzCQR Code Scan (Recommended, auto-obtain Client ID and Client Secret)z*Manual Input (Client ID and Client Secret)zChoose setup method)Údefault)Údingtalk_qr_authz1QR auth incomplete, falling back to manual input.zQR auth module failed to load (z ), falling back to manual input.z DingTalk configured via QR scan!©r¤   r§   )Úhermes_cli.configrÓ  Úhermes_cli.setuprÔ  Úhermes_cli.cli_outputrÕ  rÖ  r×  rØ  Úhermes_cli.setup_platformsrÙ  Úhermes_cli.dingtalk_authrÛ  rË  ÚzipÚ_manual_credential_entry)rÓ  rÔ  rÕ  rÖ  r×  rØ  rÙ  Úchoicesrÿ  rÛ  r'   rh   Úvalues                r-   Úinteractive_setupræ  
  sÛ   € å0Ý.ßXÓXÝ?Ù�ÔÙ˜JÐ(?ÐAU×VÒVÙØTð  WCð  D€GØ€FÙÐ*¨G¸QÔ?À1ÔDð	cÝAÙ%Ó'ˆFØŠ~ÙÐQÔRð ÒÜ!Ð"RÐTZÖ[‘
�Ù˜sÖ*ñ \á Ð!CÓDÐDÜ˜V°]ÖCøô ô 	cÙÐ;¸C¸5Ð@`Ða×bÑbûð	cús   ÁB  Â CÂ+B<Â<Cc                ó   € V ^8„  d   QhRR/# r   rX   )r,   s   "r-   r.   r.   $  s   € ÷ 0ñ 0Àtñ 0r/   c                 ó‚   € V ! R 4      pV'       g   R# V! RV4       V ! RRR7      ;p'       d
   V! RV4       V! R4       R# )zDingTalk Client ID (app key)Nr¤   zDingTalk Client SecretT)Úpasswordr§   zDingTalk credentials savedrX   )rÕ  rÓ  r×  r£   r¦   s   &&&  r-   rã  rã  $  sE   € ÙÐ5Ó6€IßÙÙÐ'¨Ô3ÙÐ7À$ÔGÐG€}ÖGÙÐ/°Ô?ÙÐ.Ö/r/   c                ó0   € V ^8„  d   QhR\         R\         /# )r&   Úyaml_cfgÚdingtalk_cfg©r¡   )r,   s   "r-   r.   r.   .  s   € ÷ ñ ¤Dð ¼ñ r/   c                ó�  € V P                  R4      p\        V\        4      '       d   VP                  R4      MRV P                  R4      3pV.R V 4       O Fj  p\        V\        4      '       d   VP                  R4      MRp\        V\        4      '       g   KD  VP                  R4      f   KY  VP                  R4      u # 	  R# )z‘Allowlist from ``extra.allowed_users``: this block's own extra first, then ``gateway.platforms.dingtalk.extra`` and ``platforms.dingtalk.extra``.ÚgatewayÚ	platformsNc              3   ót   "  € T F.  p\        V\        4      '       d   VP                  R 4      MRx € K0  	  R# 5i)r”   N)r2   r¡   re   )rS   Úcs   & r-   rU   Ú(_nested_allowed_users.<locals>.<genexpr>2  s.   é € Ð"jÑ_iÐZ[¼
À1Äd×8KÒ8K 1§5¡5¨Ô#4ÐQUÔ#UÓ_iùs   ‚68r    r»   )re   r2   r¡   )rë  rì  Ú_gwÚ
containersÚholderÚ_extras   &&    r-   Ú_nested_allowed_usersrø  .  s    € à
�,‰,�yÓ
!€CÜ*4°S¼$×*?Ò*?�#—'‘'˜+Ô&ÀTÈ8Ï<É<ÐXcÓKdÐe€JØÐkÑ"jÑ_iÓ"jÓkˆÜ(2°6¼4×(@Ò(@�—‘˜GÔ$ÀdˆÜ�fœd×#Ô#¨¯
©
°?Ó(CÔ(OØ—:‘:˜oÓ.Ò.ñ lñ r/   c                óJ   € V ^8„  d   QhR\         R\         R\         R,          /# )r&   rë  rì  r(   Nrí  )r,   s   "r-   r.   r.   @  s%   € ÷ 1ñ 1¤ð 1´Tð 1¼dÀT½kñ 1r/   c                óz   € \        V4      pVP                  R4      f   \        W4      VR&   \        V\        4      # )ub  ``apply_yaml_config_fn`` (#24849): config.yaml dingtalk: keys â†’ DINGTALK_* env (env wins; skipped under a
multiplexed secondary profile's scope) + ``PlatformConfig.extra``. The docs put the allowlist at
``gateway.platforms.dingtalk.extra.allowed_users`` but gateway authz only consults DINGTALK_ALLOWED_USERS,
so nested-only allowlists are bridged too.r»   )r¡   re   rø  Ú_apply_yaml_bridgeÚ_YAML_BRIDGE)rë  rì  Úcfgs   && r-   Ú_apply_yaml_configrþ  @  s9   € ô
 ˆ|Ó
€CØ
‡w�wˆÓÒ'Ü4°XÓLˆˆOÑÜ˜c¤<Ó0Ð0r/   c                ó$   € V ^8„  d   QhR\         /# r‹   rŒ   )r,   s   "r-   r.   r.   L  s   € ÷ ;ñ ;œTñ ;r/   c           	     ó@   € \        \        \        V R/ 4      4      4      # )z\Connected when client_id + client_secret are present (PlatformConfig.extra first, then env).r    )r¬   r©   r  )r¹   s   &r-   Ú_is_connectedr  L  s   € äŒ|œG F¨G°RÓ8Ó9Ó:Ð:r/   c                ó   € V ^8„  d   QhRR/# r   rX   )r,   s   "r-   r.   r.   R  s   € ÷ ñ �Tñ r/   c           	     óN  € ^RI Hp V P                  ! R%/ R\        RR7      bRRbRRbR	\        bR
\
        bRRbRRbRR&bR\        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P                  bR#VP                  bVP                  B  R$# )'u:   Plugin entry point â€” called by the Hermes plugin system.)Úgateway_envÚstandalone_sendT)Útext_directrá   r”   Úlabelr_  Úadapter_factoryÚcheck_fnÚdashboard_descriptionu+   Connect Hermes to DingTalk groups (é’‰é’‰).Údocs_urlzGhttps://open.dingtalk.com/document/orgapp/the-robot-development-processÚdashboard_env_varsr¤   r§   Úensure_deps_fnÚis_connectedÚvalidate_configÚrequired_envÚinstall_hintz)pip install 'dingtalk-stream>=0.20' httpxÚsetup_fnÚapply_yaml_config_fnÚcron_deliver_env_varÚDINGTALK_HOME_CHANNELÚstandalone_sender_fnÚemojiu   ðŸ�³Úallow_update_commandÚdisplay_tierÚlowÚenv_overridesÚenv_enable_credentialsNrX   rÜ  )r¥   r  Úregister_platformr    r¯   r�   rž   r  ræ  rþ  rÐ  ÚENV_OVERRIDESÚENV_ENABLE_CREDENTIALSÚAUTHZ)Úctxr  s   & r-   Úregisterr"  R  s  € åØ×Òò Ü,¸Õ>ðáðá)ðå;JðåUjðñ Lðñ [ð	ñ
 Lðõ ,ðõ ;Hðõ Zgðð +Ð,DÑEðñ U@ðõ #ðõ :Lðñ czðõ .ðñ 6<ðñ SWðñ ðð "×/Ò/ðð  +×AÒAÀ[×EVÑEVôr/   rX   )r&   é   é
   é   é<   >   r³  ÚonÚyesÚtrue))TÚRecall)FÚReply))rL  rM  rÇ   )r]  r^  rd  )r�  r‚  Úcsv)rU  rV  r,  )r»   r¼   r,  )lrp   rò   rd  rM   rZ  rc   rF  rÌ  r   r   r   Útypingr   r   r   r   r	   r–   r   r˜   r   r   rŽ   rZ   ra   r—   r�   rË  Úalibabacloud_dingtalk.card_1_0r   rë   r   r9  Úalibabacloud_dingtalk.robot_1_0rí   ru  Úalibabacloud_tea_openapirç   Úalibabacloud_tea_utilrS  ræ   Úgateway.configr   r   Úgateway.platforms.helpersr   r   Ú
agent.i18nr   Úgateway.platforms.baser   r   Úgateway.platforms.eventr   Úgateway.platforms._sharedr   rû  r   rƒ   r   rH  r   r¨   r   Úgateway.platforms.send_targetsr    Ú"plugins.platforms.dingtalk.inboundr!   r"   r#   r  rb   rß   rù  r  r  r  rq   r8   ÚFilterr:   rÓ  ÚcompilerÑ  rO  rv  rw  rÇ   rt  r•  r  r‰   r�   rž   r©   r­   r¯   ÚChatbotHandlerÚobjectrñ   rÐ  ræ  rã  rø  rü  rþ  r  r"  )r¥  Úvs   00r-   Ú<module>r?     s½  ðñcó
 Û Û Û 	Û Û Û ß ,Ñ ,ß 1Õ 1ð	\ÛÝ.ßBà $ÐðÛà€Oð

-ßmßpÝBÝ?àÐ÷ 4ß SÝ ß BÝ 0÷õ õ @ß bÑ bð 
×	Ò	˜8Ó	$€àÐ Ú&Ð Ø"#Ð Ø"%Ð ØÐ õô$�7—>‘>ô $ðJ Ð Ø—z’zÐ"JÓKÐ Ú
$€Ø€Ø€ñ "FôGÙ!E‘I�Fð ˜5  Ð#<Ð=ÀÀqÀcÈÐ?XÐ\aÐbcÐadÐdrÐZsÐw}Ð~÷  Fñ  Fó  Hð  ~Ið  Idð  veð  fò  fÙ!EòG€à�zŠz˜+Ó&€ð LÐ õFõ9õõ6\õ>ô
CÐ)ô CôL$[×9RÓ9R”×5Ò5ÐX^ô $[ðN<À4ð <ÐUYð <Ðjoô <õ8Dõ40õð€õ1õ;÷øðu ô \Ø %ÐØ9=Ð=€OÐ=�n Ù�l B¨°cÐ;TÐVYÐ(ZÓ[ƒJð\ûð ô Ø€OØƒEðûð ô -ØÐØbfÐfÐÐfÐ/ÐfÐ2GÐJ_Ø(,Ð,€O“oð-üójGs;   ¸G ÁG= ÁH Ä0H+ÇG:Ç9G:Ç=HÈHÈH(È'H(