§
    ‰eîiy ã                   ó(  — d Z ddlZddlZddlZddlZddlZddlZddlZddl	m
Z
mZmZmZ  ej        e¦  «        Z	 ddlmZmZmZmZmZ 	 ddlmZ n# e$ r dZY nw xY wddlmZmZmZmZmZm Z  ddl!m"Z"m#Z# ddl$m%Z% d	Z&n8# e$ r0 d
Z&eZeZeZeZeZdZeZeZeZeZeZ%dZ dZ"dZ# G d„ d¦  «        Z'e'ZY nw xY wddl(Z(ddl)m*Z+ e(j,         -                    d e. e+e/¦  «         0                    ¦   «         j1        d         ¦  «        ¦  «         ddl2m3Z3m4Z4 ddl5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZC ddlDmEZEmFZFmGZG deHfd„ZI ejJ        d¦  «        ZKde.de.fd„ZLde.de.fd„ZM ejJ        d¦  «        ZNde.deHfd„ZOde.de.fd„ZP G d„ de6¦  «        ZQdS )z¡
Telegram platform adapter.

Uses python-telegram-bot library for:
- Receiving messages from users/groups
- Sending responses back
- Handling media and commands
é    N)ÚDictÚListÚOptionalÚAny)ÚUpdateÚBotÚMessageÚInlineKeyboardButtonÚInlineKeyboardMarkup)ÚLinkPreviewOptions)ÚApplicationÚCommandHandlerÚCallbackQueryHandlerÚMessageHandlerÚContextTypesÚfilters)Ú	ParseModeÚChatType)ÚHTTPXRequestTFc                   ó   — e Zd ZeZdS )Ú_MockContextTypesN)Ú__name__Ú
__module__Ú__qualname__r   ÚDEFAULT_TYPE© ó    ú</home/div/.hermes/hermes-agent/gateway/platforms/telegram.pyr   r   9   s   € € € € € Øˆˆˆr   r   )ÚPathé   )ÚPlatformÚPlatformConfig)ÚBasePlatformAdapterÚMessageEventÚMessageTypeÚProcessingOutcomeÚ
SendResultÚcache_image_from_bytesÚcache_audio_from_bytesÚcache_video_from_bytesÚcache_document_from_bytesÚresolve_proxy_urlÚSUPPORTED_VIDEO_TYPESÚSUPPORTED_DOCUMENT_TYPESÚ	utf16_lenÚ_prefix_within_utf16_limit)ÚTelegramFallbackTransportÚdiscover_fallback_ipsÚparse_fallback_ip_envÚreturnc                  ó   — t           S )z-Check if Telegram dependencies are available.)ÚTELEGRAM_AVAILABLEr   r   r   Úcheck_telegram_requirementsr7   Y   s   € åÐr   z([_*\[\]()~`>#\+\-=|{}.!\\])Útextc                 ó8   — t                                d| ¦  «        S )zIEscape Telegram MarkdownV2 special characters with a preceding backslash.z\\\1)Ú_MDV2_ESCAPE_REÚsub©r8   s    r   Ú_escape_mdv2r=   c   s   € å×Ò˜w¨Ñ-Ô-Ð-r   c                 óâ   — t          j        dd| ¦  «        }t          j        dd|¦  «        }t          j        dd|¦  «        }t          j        dd|¦  «        }t          j        dd|¦  «        }|S )zÎStrip MarkdownV2 escape backslashes to produce clean plain text.

    Also removes MarkdownV2 formatting markers so the fallback
    doesn't show stray syntax characters from format_message conversion.
    z\\([_*\[\]()~`>#\+\-=|{}.!\\])ú\1z\*([^*]+)\*z(?<!\w)_([^_]+)_(?!\w)z	~([^~]+)~z\|\|([^|]+)\|\|©Úrer;   )r8   Úcleaneds     r   Ú_strip_mdv2rC   h   sm   € õ ŒfÐ6¸¸tÑDÔD€GåŒf�^ U¨GÑ4Ô4€Gõ ŒfÐ.°°wÑ?Ô?€GåŒf�\ 5¨'Ñ2Ô2€GåŒfÐ'¨°Ñ8Ô8€GØ€Nr   z0^\s*\|?\s*:?-+:?\s*(?:\|\s*:?-+:?\s*){1,}\|?\s*$Úlinec                 óP   — |                       ¦   «         }t          |¦  «        od|v S )z:Return True if *line* could plausibly be a table data row.Ú|)ÚstripÚbool)rD   Ústrippeds     r   Ú_is_table_rowrJ   �   s$   € à�zŠz‰|Œ|€HÝ�‰>Œ>Ð-˜c X˜oÐ-r   c                 óÖ  — d| vsd| vr| S |                       d¦  «        }g }d}d}|t          |¦  «        k     �rœ||         }|                     ¦   «         }|                     d¦  «        r| }|                     |¦  «         |dz  }Œc|r|                     |¦  «         |dz  }Œ€d|v rþ|dz   t          |¦  «        k     rèt
                               ||dz            ¦  «        rÅ|||dz            g}|dz   }|t          |¦  «        k     r]t          ||         ¦  «        rH|                     ||         ¦  «         |dz  }|t          |¦  «        k     rt          ||         ¦  «        °H|                     d¦  «         |                     |¦  «         |                     d¦  «         |}�Œ‚|                     |¦  «         |dz  }|t          |¦  «        k     �°œd 	                    |¦  «        S )	at  Wrap GFM-style pipe tables in ``` fences so Telegram renders them.

    Detected by a row containing '|' immediately followed by a delimiter
    row matching :data:`_TABLE_SEPARATOR_RE`.  Subsequent pipe-containing
    non-blank lines are consumed as the table body and included in the
    wrapped block.  Tables inside existing fenced code blocks are left
    alone.
    rF   Ú-Ú
Fr   ú```é   r    )
ÚsplitÚlenÚlstripÚ
startswithÚappendÚ_TABLE_SEPARATOR_REÚmatchrJ   ÚextendÚjoin)	r8   ÚlinesÚoutÚin_fenceÚirD   rI   Útable_blockÚjs	            r   Ú_wrap_markdown_tablesr_   “   sþ  € ð �$€€˜# T˜/˜/Øˆà�JŠJ�tÑÔ€EØ€CØ€HØ	€AØ
�c�%‰jŒjŠ.‰.Ø�QŒxˆØ—;’;‘=”=ˆð ×Ò˜uÑ%Ô%ð 	Ø#�|ˆHØ�JŠJ�tÑÔÐØ�‰FˆAØØð 	Ø�JŠJ�tÑÔÐØ�‰FˆAØð
 �4ˆKˆKØ�A‘�˜E™
œ
Ò"Ð"Ý#×)Ò)¨%°°A±¬,Ñ7Ô7ð #ð    q¨1¡u¤Ð.ˆKØ�A‘ˆAØ•c˜%‘j”j’.�.¥]°5¸´8Ñ%<Ô%<�.Ø×"Ò" 5¨¤8Ñ,Ô,Ð,Ø�Q‘�ð •c˜%‘j”j’.�.¥]°5¸´8Ñ%<Ô%<�.ð �JŠJ�uÑÔÐØ�JŠJ�{Ñ#Ô#Ð#Ø�JŠJ�uÑÔÐØˆAÙà�
Š
�4ÑÔÐØ	ˆQ‰ˆðE �c�%‰jŒjŠ.‰.ðH �9Š9�S‰>Œ>Ðr   c                   óP	  ‡ — e Zd ZdZdZdZdZdZdefˆ fd„Z	e
ded	efd
„¦   «         Zedeeeef                  d	ee         fd„¦   «         Zedee         d	ee         fd„¦   «         Zedee         d	ee         fd„¦   «         Ze
ded	efd„¦   «         Zd	ee         fd„Ze
ded	efd„¦   «         Ze
ded	efd„¦   «         Zd‡deded	efd„Zd	eeef         fd„Zded	dfd„Zded	dfd„Z	 	 dˆdededee         d ee         d	ee         f
d!„Z ded"eded	dfd#„Z!d‰d$„Z"d	efd%„Z#d‰d&„Z$d'ee         d(ed	efd)„Z%	 	 dˆded*ed'ee         deeeef                  d	e&f
d+„Z'dd,œded-ed*ed.ed	e&f
d/„Z(	 	 dŠded1eded2ed	e&f
d3„Z)	 	 d‹ded5ed2ed6edeeeef                  d	e&fd7„Z*	 dŒded8ed9ed:ed2edeeeef                  d	e&fd;„Z+d<Z,d=ed>ed	e-fd?„Z.d@eded	dfdA„Z/	 	 	 	 	 	 d�dF„Z0dGedHed	efdI„Z1	 	 	 dŽdedJedKee         d'ee         deeeef                  d	e&fˆ fdL„Z2	 	 	 dŽdedMedKee         d'ee         deeeef                  d	e&fˆ fdN„Z3	 	 	 	 d�dedOedKee         dPee         d'ee         deeeef                  d	e&fˆ fdQ„Z4	 	 	 dŽdedRedKee         d'ee         deeeef                  d	e&fˆ fdS„Z5	 	 	 dŽdedTedKee         d'ee         deeeef                  d	e&fˆ fdU„Z6	 	 	 dŽdedVedKee         d'ee         deeeef                  d	e&fdW„Z7dŒdedeeeef                  d	dfdX„Z8ded	eeef         fdY„Z9d*ed	efdZ„Z:d	efd[„Z;d	e<e         fd\„Z=d	e<e         fd]„Z>d	e?e@jA                 fd^„ZBd_eCd	efd`„ZDd_eCd	efda„ZEd_eCd	efdb„ZFd_eCd	efdc„ZGddee         d	ee         fde„ZHddfœd_eCdged	efdh„ZIdBeJdDeKjL        d	dfdi„ZMdBeJdDeKjL        d	dfdj„ZNdBeJdDeKjL        d	dfdk„ZOdlePd	efdm„ZQdlePd	dfdn„ZRded	dfdo„ZSdlePdpeCd	efdq„ZTdred	dfds„ZUdredlePd	dfdt„ZVdBeJdDeKjL        d	dfdu„ZWdvedlePd	dfdw„ZXdved	dfdx„ZYdpeCdldyd	dfdz„ZZd‰d{„Z[dedee         d	eeeef                  fd|„Z\deded"ed	dfd}„Z]	 dŒd_eCd~e^dee         d	ePfd€„Z_d	efd�„Z`ded-ed‚ed	efdƒ„ZadlePd	dfd„„ZbdlePd…ecd	dfd†„Zdˆ xZeS )�ÚTelegramAdapterzË
    Telegram bot adapter.
    
    Handles:
    - Receiving messages from users and groups
    - Sending responses with Telegram markdown
    - Forum topics (thread_id support)
    - Media messages
    i   i   gš™™™™™é?Ú1Úconfigc                 ó  •— t          ¦   «                              |t          j        ¦  «         d | _        d | _        d| _        |                      ¦   «         | _        t          |dd¦  «        pd| _
        |                      dd¦  «        | _        t          t          j        dd¦  «        ¦  «        | _        i | _        i | _        i | _        i | _        t          t          j        dd¦  «        ¦  «        | _        t          t          j        d	d
¦  «        ¦  «        | _        i | _        i | _        d | _        d| _        d| _        d | _        i | _        | j        j                              dg ¦  «        | _!        i | _"        i | _#        d S )NFÚreply_to_modeÚfirstÚdisable_link_previewsÚ)HERMES_TELEGRAM_MEDIA_BATCH_DELAY_SECONDSz0.8Ú(HERMES_TELEGRAM_TEXT_BATCH_DELAY_SECONDSz0.6Ú.HERMES_TELEGRAM_TEXT_BATCH_SPLIT_DELAY_SECONDSz2.0r   Ú	dm_topics)$ÚsuperÚ__init__r!   ÚTELEGRAMÚ_appÚ_botÚ_webhook_modeÚ_compile_mention_patternsÚ_mention_patternsÚgetattrÚ_reply_to_modeÚ_coerce_bool_extraÚ_disable_link_previewsÚfloatÚosÚgetenvÚ_media_batch_delay_secondsÚ_pending_photo_batchesÚ_pending_photo_batch_tasksÚ_media_group_eventsÚ_media_group_tasksÚ_text_batch_delay_secondsÚ_text_batch_split_delay_secondsÚ_pending_text_batchesÚ_pending_text_batch_tasksÚ_polling_error_taskÚ_polling_conflict_countÚ_polling_network_error_countÚ_polling_error_callback_refÚ
_dm_topicsrc   ÚextraÚgetÚ_dm_topics_configÚ_model_picker_stateÚ_approval_state)Úselfrc   Ú	__class__s     €r   rm   zTelegramAdapter.__init__Ý   sg  ø€ Ý‰Œ×Ò˜¥Ô!2Ñ3Ô3Ð3Ø+/ˆŒ	Ø#'ˆŒ	Ø#(ˆÔØ!%×!?Ò!?Ñ!AÔ!AˆÔÝ#*¨6°?ÀGÑ#LÔ#LÐ#WÐPWˆÔØ,0×,CÒ,CÐD[Ð]bÑ,cÔ,cˆÔ#õ +0µ´	Ð:eÐglÑ0mÔ0mÑ*nÔ*nˆÔ'Ø?AˆÔ#ØCEˆÔ'Ø<>ˆÔ Ø;=ˆÔõ */­r¬yÐ9cÐejÑ/kÔ/kÑ)lÔ)lˆÔ&Ý/4µR´YÐ?oÐqvÑ5wÔ5wÑ/xÔ/xˆÔ,Ø>@ˆÔ"ØBDˆÔ&Ø;?ˆÔ Ø,-ˆÔ$Ø12ˆÔ)Ø+/ˆÔ(à*,ˆŒà7;´{Ô7H×7LÒ7LÈ[ÐZ\Ñ7]Ô7]ˆÔà46ˆÔ à/1ˆÔÐÐr   Úuser_idr4   c                 ó¦   — t          j        dd¦  «                             ¦   «         }|sdS d„ |                     d¦  «        D ¦   «         }d|v p| |v S )zIReturn whether a Telegram inline-button caller may perform gated actions.ÚTELEGRAM_ALLOWED_USERSÚ Tc                 ó^   — h | ]*}|                      ¦   «         ¯|                      ¦   «         ’Œ+S r   ©rG   )Ú.0Úuids     r   ú	<setcomp>z?TelegramAdapter._is_callback_user_authorized.<locals>.<setcomp>  s-   € ÐTÐTÐT sÈÏ	Ê	ÉÌÐT�s—y’y‘{”{ÐTÐTÐTr   Ú,Ú*)ry   rz   rG   rP   )r�   Úallowed_csvÚallowed_idss      r   Ú_is_callback_user_authorizedz,TelegramAdapter._is_callback_user_authorizedÿ   se   € õ ”iÐ 8¸"Ñ=Ô=×CÒCÑEÔEˆØð 	Ø�4ØTÐT¨k×.?Ò.?ÀÑ.DÔ.DÐTÑTÔTˆØ�kÐ!Ð; W°Ð%;Ð;r   Úmetadatac                 ó„   — |sd S |                      d¦  «        p|                      d¦  «        }|�t          |¦  «        nd S )NÚ	thread_idÚmessage_thread_id)rŠ   Ústr)Úclsrž   r    s      r   Ú_metadata_thread_idz#TelegramAdapter._metadata_thread_id  sG   € àð 	Ø�4Ø—L’L Ñ-Ô-ÐR°·²Ð>QÑ1RÔ1Rˆ	Ø!*Ð!6�s�9‰~Œ~ˆ~¸DÐ@r   r    c                 óX   — |rt          |¦  «        | j        k    rd S t          |¦  «        S ©N)r¢   Ú_GENERAL_TOPIC_THREAD_IDÚint©r£   r    s     r   Ú_message_thread_id_for_sendz+TelegramAdapter._message_thread_id_for_send  s.   € àð 	�C 	™NœN¨cÔ.JÒJÐJØ�4Ý�9‰~Œ~Ðr   c                 ó(   — |sd S t          |¦  «        S r¦   )r¨   r©   s     r   Ú_message_thread_id_for_typingz-TelegramAdapter._message_thread_id_for_typing  s   € àð 	Ø�4Ý�9‰~Œ~Ðr   Úerrorc                 óH   — dt          | ¦  «                             ¦   «         v S )Nzthread not found)r¢   Úlower)r­   s    r   Ú_is_thread_not_found_errorz*TelegramAdapter._is_thread_not_found_error  s   € à!¥S¨¡Z¤Z×%5Ò%5Ñ%7Ô%7Ð7Ð7r   c                 ó&  — t          | j        dd¦  «        r | j        j                             dg ¦  «        ng }t	          |t
          ¦  «        r|                     d¦  «        }t          |rd                     d„ |D ¦   «         ¦  «        nd¦  «        S )zNReturn validated fallback IPs from config (populated by _apply_env_overrides).r‰   NÚfallback_ipsr™   c              3   ó4   K  — | ]}t          |¦  «        V — Œd S r¦   )r¢   )r–   Úvs     r   ú	<genexpr>z0TelegramAdapter._fallback_ips.<locals>.<genexpr>$  s(   è è € Ð-IÐ-I¸­c°!©f¬fÐ-IÐ-IÐ-IÐ-IÐ-IÐ-Ir   )	rt   rc   r‰   rŠ   Ú
isinstancer¢   rP   r3   rX   ©rŽ   Ú
configureds     r   Ú_fallback_ipszTelegramAdapter._fallback_ips  s�   € åBIÈ$Ì+ÐW^Ð`dÑBeÔBeÐm�T”[Ô&×*Ò*¨>¸2Ñ>Ô>Ð>Ðkmˆ
Ý�j¥#Ñ&Ô&ð 	/Ø#×)Ò)¨#Ñ.Ô.ˆJÝ$ÈZÐ%a S§X¢XÐ-IÐ-I¸jÐ-IÑ-IÔ-IÑ%IÔ%IÐ%IÐ]aÑbÔbÐbr   c                 ó˜   — t          | ¦  «                             ¦   «         }| j        j                             ¦   «         dk    pd|v pd|v S )NÚconflictz&terminated by other getupdates requestzanother bot instance is running)r¢   r¯   r�   r   )r­   r8   s     r   Ú_looks_like_polling_conflictz,TelegramAdapter._looks_like_polling_conflict&  sQ   € å�5‰zŒz×ÒÑ!Ô!ˆàŒOÔ$×*Ò*Ñ,Ô,°
Ò:ð 9Ø7¸4Ð?ð9à0°DÐ8ð	
r   c                 óÐ   — | j         j                             ¦   «         }|dv rdS 	 ddlm}m} t          | ||f¦  «        rdS n# t          $ r Y nw xY wt          | t          ¦  «        S )zJReturn True for transient network errors that warrant a reconnect attempt.)ÚnetworkerrorÚtimedoutÚconnectionerrorTr   ©ÚNetworkErrorÚTimedOut)	r�   r   r¯   Útelegram.errorrÂ   rÃ   r¶   ÚImportErrorÚOSError)r­   ÚnamerÂ   rÃ   s       r   Ú_looks_like_network_errorz)TelegramAdapter._looks_like_network_error/  s™   € ð ŒÔ'×-Ò-Ñ/Ô/ˆØÐBÐBÐBØ�4ð	Ø=Ð=Ð=Ð=Ð=Ð=Ð=Ð=Ý˜% ,°Ð!9Ñ:Ô:ð Ø�tðøåð 	ð 	ð 	ØˆDð	øøøå˜%¥Ñ)Ô)Ð)s   ¦A Á
AÁAFÚkeyÚdefaultc                 ó(  — t          | j        dd ¦  «        r| j        j                             |¦  «        nd }|€|S t	          |t
          ¦  «        r4|                     ¦   «                              ¦   «         }|dv rdS |dv rdS |S t          |¦  «        S )Nr‰   ©Útruerb   ÚyesÚonT)ÚfalseÚ0ÚnoÚoffF)	rt   rc   r‰   rŠ   r¶   r¢   rG   r¯   rH   )rŽ   rÉ   rÊ   ÚvalueÚlowereds        r   rv   z"TelegramAdapter._coerce_bool_extra=  s›   € Ý.5°d´kÀ7ÈDÑ.QÔ.QÐ[�”Ô!×%Ò% cÑ*Ô*Ð*ÐW[ˆØˆ=ØˆNÝ�e�SÑ!Ô!ð 	Ø—k’k‘m”m×)Ò)Ñ+Ô+ˆGØÐ4Ð4Ð4Ø�tØÐ5Ð5Ð5Ø�uØˆNÝ�E‰{Œ{Ðr   c                 ób   — t          | dd¦  «        si S t          �dt          d¬¦  «        iS ddiS )Nrw   FÚlink_preview_optionsT)Úis_disabledÚdisable_web_page_preview)rt   r   ©rŽ   s    r   Ú_link_preview_kwargsz$TelegramAdapter._link_preview_kwargsJ  sD   € Ý�tÐ5°uÑ=Ô=ð 	ØˆIÝÐ)Ø*Õ,>È4Ð,PÑ,PÔ,PÐQÐQØ*¨DÐ1Ð1r   Nc              ƒ   ó†  K  — | j         rdS d}d}d}| xj        dz  c_        | j        }||k    r[d|z  }t                               d| j        ||¦  «         |                      d|d	¬
¦  «         |                      ¦   «         ƒ d{V —† dS t          |d|dz
  z  z  |¦  «        }t                               d| j        ||||¦  «         t          j
        |¦  «        ƒ d{V —† 	 | j        rA| j        j        r5| j        j        j        r$| j        j                             ¦   «         ƒ d{V —† n# t          $ r Y nw xY w	 | j        j                             t"          j        d| j        ¬¦  «        ƒ d{V —† t                               d| j        |¦  «         d| _        dS # t          $ r™}t                               d| j        |¦  «         | j         sft          j        |                      |¦  «        ¦  «        }	| j                             |	¦  «         |	                     | j        j        ¦  «         Y d}~dS Y d}~dS d}~ww xY w)aK  Reconnect polling after a transient network interruption.

        Triggered by NetworkError/TimedOut in the polling error callback, which
        happen when the host loses connectivity (Mac sleep, WiFi switch, VPN
        reconnect, etc.).  The gateway process stays alive but the long-poll
        connection silently dies; without this handler the bot never recovers.

        Strategy: exponential back-off (5s, 10s, 20s, 40s, 60s cap) up to
        MAX_NETWORK_RETRIES attempts, then mark the adapter retryable-fatal so
        the supervisor restarts the gateway process.
        Né
   é   é<   rO   zXTelegram polling could not reconnect after %d network error retries. Restarting gateway.z[%s] %s Last error: %sÚtelegram_network_errorT©Ú	retryabler    zK[%s] Telegram network error (attempt %d/%d), reconnecting in %ds. Error: %sF©Úallowed_updatesÚdrop_pending_updatesÚerror_callbackz>[%s] Telegram polling resumed after network error (attempt %d)r   z*[%s] Telegram polling reconnect failed: %s)Úhas_fatal_errorr†   Úloggerr­   rÇ   Ú_set_fatal_errorÚ_notify_fatal_errorÚminÚwarningÚasyncioÚsleepro   ÚupdaterÚrunningÚstopÚ	ExceptionÚstart_pollingr   Ú	ALL_TYPESr‡   ÚinfoÚensure_futureÚ_handle_polling_network_errorÚ_background_tasksÚaddÚadd_done_callbackÚdiscard)
rŽ   r­   ÚMAX_NETWORK_RETRIESÚ
BASE_DELAYÚ	MAX_DELAYÚattemptÚmessageÚdelayÚ	retry_errÚtasks
             r   r÷   z-TelegramAdapter._handle_polling_network_errorQ  sþ  è è € ð Ôð 	ØˆFà ÐØˆ
Øˆ	àÐ)Ô)¨QÑ.Ð)Ô)ØÔ3ˆàÐ(Ò(Ð(ð&Ø(;ñ<ð õ �LŠLÐ1°4´9¸gÀuÑMÔMÐMØ×!Ò!Ð":¸GÈtÐ!ÑTÔTÐTØ×*Ò*Ñ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,ØˆFå�J !¨°!©Ñ"4Ñ5°yÑAÔAˆÝ�ŠØYØŒI�wÐ 3°U¸Eñ	
ô 	
ð 	
õ Œm˜EÑ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"Ð"ð	ØŒyð /˜TœYÔ.ð /°4´9Ô3DÔ3Lð /Ø”iÔ'×,Ò,Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.øøÝð 	ð 	ð 	ØˆDð	øøøð	GØ”)Ô#×1Ò1Ý &Ô 0Ø%*Ø#Ô?ð 2ñ ô ð ð ð ð ð ð ð õ
 �KŠKØPØ”	˜7ñô ð ð 12ˆDÔ-Ð-Ð-øÝð 		Gð 		Gð 		GÝ�NŠNÐGÈÌÐT]Ñ^Ô^Ð^ð Ô'ð GÝÔ,Ø×6Ò6°yÑAÔAñô �ð Ô&×*Ò*¨4Ñ0Ô0Ð0Ø×&Ò& tÔ'=Ô'EÑFÔFÐFÐFÐFÐFÐFÐFÐFðGð Gð Gð Gð Gð Gøøøøð			Gøøøs-   Ã"AD+ Ä+
D8Ä7D8Ä<AF Æ
I Æ'BH;È;I c              ƒ   ó„  K  — | j         r| j        dk    rd S | xj        dz  c_        d}d}| j        |k    �r=t                               d| j        | j        |||¦  «         	 | j        rA| j        j        r5| j        j        j        r$| j        j         	                    ¦   «         ƒ d {V —† n# t          $ r Y nw xY wt          j        |¦  «        ƒ d {V —† 	 | j        j                             t          j        d| j        ¬¦  «        ƒ d {V —† t                               d| j        | j        ¦  «         d	| _        d S # t          $ r,}t                               d
| j        |¦  «         Y d }~d S d }~ww xY wd|z  }t                               d| j        ||¦  «         |                      d|d¬¦  «         	 | j        r0| j        j        r$| j        j         	                    ¦   «         ƒ d {V —† n:# t          $ r-}t                               d| j        |d¬¦  «         Y d }~nd }~ww xY w|                      ¦   «         ƒ d {V —† d S )NÚtelegram_polling_conflictrO   é   rÝ   zD[%s] Telegram polling conflict (%d/%d), will retry in %ds. Error: %sFrã   z5[%s] Telegram polling resumed after conflict retry %dr   z&[%s] Telegram polling retry failed: %suú   Another process is already polling this Telegram bot token (possibly OpenClaw or another Hermes instance). Hermes stopped Telegram polling after %d retries. Only one poller can run per token â€” stop the other process and restart with 'hermes start'.z[%s] %s Original error: %srá   z8[%s] Failed stopping Telegram polling after conflict: %sT©Úexc_info)rç   Úfatal_error_coder…   rè   rì   rÇ   ro   rï   rð   rñ   rò   rí   rî   ró   r   rô   r‡   rõ   r­   ré   rê   )rŽ   r­   ÚMAX_CONFLICT_RETRIESÚRETRY_DELAYr  r   Ú
stop_errors          r   Ú_handle_polling_conflictz(TelegramAdapter._handle_polling_conflict”  sï  è è € ØÔð 	 DÔ$9Ð=XÒ$XÐ$XØˆFð 	Ð$Ô$¨Ñ)Ð$Ô$à ÐØˆàÔ'Ð+?Ò?Ñ?Ý�NŠNØVØ”	˜4Ô7Ð9MØ˜Uñô ð ð
Ø”9ð 3 ¤Ô!2ð 3°t´yÔ7HÔ7Pð 3Øœ)Ô+×0Ò0Ñ2Ô2Ð2Ð2Ð2Ð2Ð2Ð2Ð2øøÝð ð ð Ø�ðøøøå”- Ñ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,ðØ”iÔ'×5Ò5Ý$*Ô$4Ø).Ø#'Ô#Cð 6ñ ô ð ð ð ð ð ð ð õ
 —’ÐSÐUYÔU^Ð`dÔ`|Ñ}Ô}Ð}Ø/0�Ô,Ø�øÝð ð ð Ý—’ÐGÈÌÐT]Ñ^Ô^Ð^ð �����øøøøð	øøøð/ð
 #ñ#ð 	õ 	�ŠÐ1°4´9¸gÀuÑMÔMÐMØ×ÒÐ9¸7ÈeÐÑTÔTÐTð	}ØŒyð /˜TœYÔ.ð /Ø”iÔ'×,Ò,Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.øøÝð 	}ð 	}ð 	}Ý�NŠNÐUÐW[ÔW`ÐblÐw{ˆNÑ|Ô|Ð|Ð|Ð|Ð|Ð|Ð|øøøøð	}øøøà×&Ò&Ñ(Ô(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ð(sD   Á!AB* Â*
B7Â6B7ÃA$D; Ä;
E1Å!E,Å,E1Æ47G, Ç,
H#Ç6#HÈH#Úchat_idrÇ   Ú
icon_colorÚicon_custom_emoji_idc              ƒ   ó,  K  — | j         sdS 	 ||dœ}|�||d<   |r||d<    | j         j        di |¤Žƒ d{V —†}|j        }t                               d| j        |||¦  «         |S # t          $ r¥}t          |¦  «                             ¦   «         }	d|	v sd|	v r#t                               d| j        ||¦  «         nNd	|	v sd
|	v r#t           	                    d| j        ||¦  «         n#t           	                    d| j        |||¦  «         Y d}~dS d}~ww xY w)zÇCreate a forum topic in a private (DM) chat.

        Uses Bot API 9.4's createForumTopic which now works for 1-on-1 chats.
        Returns the message_thread_id on success, None on failure.
        N)r  rÇ   r  r  z5[%s] Created DM topic '%s' in chat %s -> thread_id=%sÚtopic_name_duplicateÚalreadyzT[%s] DM topic '%s' already exists in chat %s (will be mapped from incoming messages)znot a forumÚforums_disabledzÝ[%s] Cannot create DM topic '%s' in chat %s: Topics mode is not enabled. The user must open the DM with this bot in Telegram, tap the bot name at the top, and enable 'Topics' in chat settings before topics can be created.z2[%s] Failed to create DM topic '%s' in chat %s: %sr   )
rp   Úcreate_forum_topicr¡   rè   rõ   rÇ   rò   r¢   r¯   rì   )
rŽ   r  rÇ   r  r  ÚkwargsÚtopicr    ÚeÚ
error_texts
             r   Ú_create_dm_topicz TelegramAdapter._create_dm_topicÎ  s–  è è € ð Œyð 	Ø�4ð#	Ø18À$Ð%GÐ%GˆFØÐ%Ø'1��|Ñ$Ø#ð FØ1E�Ð-Ñ.à6˜$œ)Ô6Ð@Ð@¸Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@ˆEØÔ/ˆIÝ�KŠKØGØ”	˜4 ¨)ñô ð ð ÐøÝð 	ð 	ð 	Ý˜Q™œŸš™œˆJð &¨Ð3Ð3°yÀJÐ7NÐ7NÝ—’ØjØ”I˜t Wñô ð ð ð  *Ð,Ð,Ð0AÀZÐ0OÐ0OÝ—’ðeð ”I˜t Wñ	ô ð ð õ —’ØHØ”I˜t W¨añô ð ð �4�4�4�4�4øøøøð+	øøøs   �AA$ Á$
DÁ.BDÄDÚ
topic_namec                 óž  — 	 ddl m}  |¦   «         dz  }|                     ¦   «         s#t                               d| j        |¦  «         dS ddl}t          |d¦  «        5 }|                     |¦  «        pi }ddd¦  «         n# 1 swxY w Y   | 	                    di ¦  «         	                    di ¦  «         	                    d	i ¦  «         	                    d
g ¦  «        }	|	sdS d}
|	D ]‡}t          | 	                    dd¦  «        ¦  «        t          |¦  «        k    rŒ7| 	                    dg ¦  «        D ]9}| 	                    d¦  «        |k    r| 	                    d¦  «        s	||d<   d}
 nŒ:Œˆ|
�rt          j        t          |j        ¦  «        dd¬¦  «        \  }}	 t          j        |dd¬¦  «        5 }|                     ||dd¬¦  «         |                     ¦   «          t          j        |                     ¦   «         ¦  «         ddd¦  «         n# 1 swxY w Y   t          j        ||¦  «         n5# t,          $ r( 	 t          j        |¦  «         n# t0          $ r Y nw xY w‚ w xY wt                               d| j        ||¦  «         dS dS # t4          $ r.}t                               d| j        |d¬¦  «         Y d}~dS d}~ww xY w)zTSave a newly created thread_id back into config.yaml so it persists across restarts.r   ©Úget_hermes_homeúconfig.yamlz:[%s] Config file not found at %s, cannot persist thread_idNÚrÚ	platformsÚtelegramr‰   rk   Fr  ÚtopicsrÇ   r    Tú.tmpz.config_)ÚdirÚsuffixÚprefixÚwúutf-8)Úencoding)Údefault_flow_styleÚ	sort_keysz9[%s] Persisted thread_id=%s for topic '%s' in config.yamlz.[%s] Failed to persist thread_id to config: %sr  )Úhermes_constantsr  Úexistsrè   rì   rÇ   ÚyamlÚopenÚ	safe_loadrŠ   r¨   ÚtempfileÚmkstempr¢   Úparentry   ÚfdopenÚdumpÚflushÚfsyncÚfilenoÚreplaceÚBaseExceptionÚunlinkrÆ   rõ   rò   )rŽ   r  r  r    r  Úconfig_pathÚ_yamlÚfrc   rk   ÚchangedÚ
chat_entryÚtÚfdÚtmp_pathr  s                   r   Ú_persist_dm_topic_thread_idz+TelegramAdapter._persist_dm_topic_thread_id  s¯  € ð6	jØ8Ð8Ð8Ð8Ð8Ð8Ø)˜/Ñ+Ô+¨mÑ;ˆKØ×%Ò%Ñ'Ô'ð Ý—’Ð[Ð]aÔ]fÐhsÑtÔtÐtØ�à Ð Ð Ð Ý�k 3Ñ'Ô'ð 2¨1ØŸš¨Ñ+Ô+Ð1¨r�ð2ð 2ð 2ñ 2ô 2ð 2ð 2ð 2ð 2ð 2ð 2øøøð 2ð 2ð 2ð 2ð
 —
’
˜;¨Ñ+Ô+ß’�Z Ñ$Ô$ß’�W˜bÑ!Ô!ß’�[ "Ñ%Ô%ð	 ð ð Ø�àˆGØ'ð ð �
Ý�z—~’~ i°Ñ3Ô3Ñ4Ô4½¸G¹¼ÒDÐDØØ#Ÿš¨°"Ñ5Ô5ð ð �AØ—u’u˜V‘}”}¨
Ò2Ð2¸1¿5º5ÀÑ;MÔ;MÐ2Ø)2˜˜+™Ø"&˜Ø˜øøàñ Ý'Ô/Ý˜KÔ.Ñ/Ô/Ø!Ø%ð ñ  ô  ‘��Hð
Ýœ 2 s°WÐ=Ñ=Ô=ð -ÀØŸ
š
 6¨1ÀÐRW˜
ÑXÔXÐXØŸš™	œ	˜	Ýœ §¢¡¤Ñ,Ô,Ð,ð-ð -ð -ñ -ô -ð -ð -ð -ð -ð -ð -øøøð -ð -ð -ð -õ ”J˜x¨Ñ5Ô5Ð5Ð5øÝ$ð ð ð ðÝœ	 (Ñ+Ô+Ð+Ð+øÝ"ð ð ð Ø˜ðøøøàðøøøõ —’ØOØ”I˜y¨*ñô ð ð ð ð%ð øõ, ð 	jð 	jð 	jÝ�NŠNÐKÈTÌYÐXYÐdhˆNÑiÔiÐiÐiÐiÐiÐiÐiÐiøøøøð	jøøøs«   ‚AJ ÁJ Á BÁ8J ÂBÂJ ÂBÂAJ Ã%B;J Æ!H9 Æ8AHÈH9 ÈHÈH9 ÈHÈ H9 È8J È9
I+ÉIÉI+É
I&É#I+É%I&É&I+É+%J Ê
KÊ#KËKc              ƒ   ó0  K  — | j         sdS | j         D �]�}|                     d¦  «        }|                     dg ¦  «        }|r|sŒ3t                               d| j        t          |¦  «        |¦  «         |D �]}|                     d¦  «        }|sŒ|› d|› �}|                     d¦  «        }|r:t          |¦  «        | j        |<   t                               d| j        ||¦  «         Œs|                     d	¦  «        }|                     d
¦  «        }	|                      t          |¦  «        |||	¬¦  «        ƒ d{V —†}
|
rP|
| j        |<   t                               d| j        ||
¦  «         |  	                    t          |¦  «        ||
¦  «         �Œ�ŒƒdS )uþ  Load or create configured DM topics for specified chats.

        Reads config.extra['dm_topics'] â€” a list of dicts:
        [
            {
                "chat_id": 123456789,
                "topics": [
                    {"name": "General", "icon_color": 7322096, "thread_id": 100},
                    {"name": "Accessibility Auditor", "icon_color": 9367192, "skill": "accessibility-auditor"}
                ]
            }
        ]

        If a topic already has a thread_id in the config (persisted from a previous
        creation), it is loaded into the cache without calling createForumTopic.
        Only topics without a thread_id are created via the API, and their thread_id
        is then saved back to config.yaml for future restarts.
        Nr  r#  z*[%s] Setting up %d DM topic(s) for chat %srÇ   ú:r    z4[%s] DM topic loaded from config: %s -> thread_id=%sr  r  )r  rÇ   r  r  z([%s] DM topic cached: %s -> thread_id=%s)
r‹   rŠ   rè   rõ   rÇ   rQ   r¨   rˆ   r  rE  )rŽ   rA  r  r#  Ú
topic_confr  Ú	cache_keyÚexisting_thread_idr  Ú
icon_emojir    s              r   Ú_setup_dm_topicsz TelegramAdapter._setup_dm_topics;  s  è è € ð& Ô%ð 	ØˆFàÔ0ð .	Zñ .	ZˆJØ —n’n YÑ/Ô/ˆGØ—^’^ H¨bÑ1Ô1ˆFØð  &ð Øå�KŠKØ<Ø”	�3˜v™;œ;¨ñô ð ð
 %ð #Zñ #Z�
Ø'Ÿ^š^¨FÑ3Ô3�
Ø!ð Øà&Ð5Ð5¨Ð5Ð5�	ð &0§^¢^°KÑ%@Ô%@Ð"Ø%ð Ý14Ð5GÑ1HÔ1H�D”O IÑ.Ý—K’KØNØœ	 9Ð.@ñô ð ð ð (Ÿ^š^¨LÑ9Ô9�
Ø'Ÿ^š^Ð,BÑCÔC�
à"&×"7Ò"7Ý ™LœLØ#Ø)Ø)3ð	 #8ñ #ô #ð ð ð ð ð ð �	ð ð ZØ1:�D”O IÑ.Ý—K’KØBØœ	 9¨iñô ð ð
 ×4Ò4µS¸±\´\À:ÈyÑYÔYÐYùñG#Zð.	Zð .	Zr   c           
   ƒ   ó®  ‡ ‡ ‡!K  — t           s"t                               d‰ j        ¦  «         dS ‰ j        j        s"t                               d‰ j        ¦  «         dS 	 ‰                      d‰ j        j        d¦  «        sdS t          j        ¦   «                              ‰ j        j        ¦  «        }‰ j        j	         
                    d¦  «        }|ri|                     |¦  «        }|                     ‰ j        j	         
                    d|¦  «        ¦  «        }t                               d‰ j        |¦  «         d	t          d
t          dt          fd„}d	t          d
t           dt           fd„} |dd¦  «         |dd¦  «         |dd¦  «         |dd¦  «         |dd¦  «        dœ}t#          j        dd¦  «                             ¦   «                              ¦   «         dv }‰                      ¦   «         }|sHt-          ¦   «         ƒ d{V —†}t                               d‰ j        d                     |¦  «        ¦  «         dg|¢}t1          d|¬ ¦  «        }	|rw|	su|sst                               d!‰ j        d                     |¦  «        ¦  «         t3          dOi |¤d"d#t5          |¦  «        ii¤Ž}
t3          dOi |¤d"d#t5          |¦  «        ii¤Ž}n~|	rBt                               d$‰ j        |	¦  «         t3          dOi |¤d%|	i¤Ž}
t3          dOi |¤d%|	i¤Ž}n:|r t                               d&‰ j        ¦  «         t3          dOi |¤Ž}
t3          dOi |¤Ž}|                     |
¦  «                             |¦  «        }|                     ¦   «         ‰ _        ‰ j        j        ‰ _         ‰ j         !                    tE          tF          j$        tF          j%         z  ‰ j&        ¦  «        ¦  «         ‰ j         !                    tE          tF          j%        ‰ j'        ¦  «        ¦  «         ‰ j         !                    tE          tF          j(        tS          tF          d'tF          j(        ¦  «        z  ‰ j*        ¦  «        ¦  «         ‰ j         !                    tE          tF          j+        tF          j,        z  tF          j-        z  tF          j.        z  tF          j/        j0        z  tF          j1        j0        z  ‰ j2        ¦  «        ¦  «         ‰ j         !                    tg          ‰ j4        ¦  «        ¦  «         	 d(d)l5m6}m7} n# tp          $ r tr          x}}Y nw xY wd*}tu          |¦  «        D ]œ}	 ‰ j         ;                    ¦   «         ƒ d{V —†  ny# ||tr          f$ ri}||d+z
  k     rUty          d,|z  d-¦  «        }t           =                    d.‰ j        |d+z   |||¦  «         t}          j?        |¦  «        ƒ d{V —† n‚ Y d}~Œ•d}~ww xY w‰ j         @                    ¦   «         ƒ d{V —† t#          j        d/d¦  «                             ¦   «         }|rÒt          t#          j        d0d1¦  «        ¦  «        }t#          j        d2d¦  «                             ¦   «         }|stƒ          d3¦  «        ‚d(d4lBmC}  ||¦  «        jD        pd5}‰ j        jE         F                    d6||||tŽ          jH        d7¬8¦  «        ƒ d{V —† d7‰ _I        t                               d9‰ j        ||¦  «         n“tS          ‰ j         d:d¦  «        }t•          |¦  «        r |d¬;¦  «        ƒ d{V —† t}          jK        ¦   «         Š!d<t˜          ddfˆ!ˆ fd=„}|‰ _M        ‰ j        jE         N                    tŽ          jH        d7|¬>¦  «        ƒ d{V —† 	 d(d?lOmPŠ  d(d@lQmR}  |dA¬B¦  «        \  }}‰ j          S                    ˆ fdC„|D ¦   «         ¦  «        ƒ d{V —† |r/t                               dD‰ j        t©          |¦  «        |¦  «         n:# t˜          $ r-}t           =                    dE‰ j        |d7¬F¦  «         Y d}~nd}~ww xY w‰  U                    ¦   «          ‰ jI        rdGndH}t                               dI‰ j        |¦  «         	 ‰  V                    ¦   «         ƒ d{V —† n:# t˜          $ r-}t           =                    dJ‰ j        |d7¬F¦  «         Y d}~nd}~ww xY wd7S # t˜          $ r_}‰  W                    ¦   «          dK|› �}‰  X                    dL|d7¬M¦  «         t                               dN‰ j        |d7¬F¦  «         Y d}~dS d}~ww xY w)Pa_  Connect to Telegram via polling or webhook.

        By default, uses long polling (outbound connection to Telegram).
        If ``TELEGRAM_WEBHOOK_URL`` is set, starts an HTTP webhook server
        instead.  Webhook mode is useful for cloud deployments (Fly.io,
        Railway) where inbound HTTP can wake a suspended machine.

        Env vars for webhook mode::

            TELEGRAM_WEBHOOK_URL    Public HTTPS URL (e.g. https://app.fly.dev/telegram)
            TELEGRAM_WEBHOOK_PORT   Local listen port (default 8443)
            TELEGRAM_WEBHOOK_SECRET Secret token for update verification
        zL[%s] python-telegram-bot not installed. Run: pip install python-telegram-botFz[%s] No bot token configuredztelegram-bot-tokenzTelegram bot tokenÚbase_urlÚbase_file_urlz'[%s] Using custom Telegram base_url: %srÇ   rÊ   r4   c                 ó”   — 	 t          t          j        | t          |¦  «        ¦  «        ¦  «        S # t          t
          f$ r |cY S w xY wr¦   )r¨   ry   rz   r¢   Ú	TypeErrorÚ
ValueError©rÇ   rÊ   s     r   Ú_env_intz)TelegramAdapter.connect.<locals>._env_int®  sP   € ð#Ý�rœy¨­s°7©|¬|Ñ<Ô<Ñ=Ô=Ð=øÝ!¥:Ð.ð #ð #ð #Ø"�N�N�Nð#øøøó   ‚.1 ±AÁAc                 ó”   — 	 t          t          j        | t          |¦  «        ¦  «        ¦  «        S # t          t
          f$ r |cY S w xY wr¦   )rx   ry   rz   r¢   rQ  rR  rS  s     r   Ú
_env_floatz+TelegramAdapter.connect.<locals>._env_float´  sP   € ð#Ý ¥¤¨4µ°W±´Ñ!>Ô!>Ñ?Ô?Ð?øÝ!¥:Ð.ð #ð #ð #Ø"�N�N�Nð#øøørU  ÚHERMES_TELEGRAM_HTTP_POOL_SIZEi   Ú!HERMES_TELEGRAM_HTTP_POOL_TIMEOUTg       @Ú$HERMES_TELEGRAM_HTTP_CONNECT_TIMEOUTg      $@Ú!HERMES_TELEGRAM_HTTP_READ_TIMEOUTg      4@Ú"HERMES_TELEGRAM_HTTP_WRITE_TIMEOUT)Úconnection_pool_sizeÚpool_timeoutÚconnect_timeoutÚread_timeoutÚwrite_timeoutÚ$HERMES_TELEGRAM_DISABLE_FALLBACK_IPSr“   )rb   rÍ   rÎ   rÏ   Nz.[%s] Auto-discovered Telegram fallback IPs: %sú, zapi.telegram.orgÚTELEGRAM_PROXY)Útarget_hostsz%[%s] Telegram fallback IPs active: %sÚhttpx_kwargsÚ	transportz;[%s] Proxy detected; passing explicitly to HTTPXRequest: %sÚproxyz4[%s] Telegram fallback-IP transport disabled via envÚVENUEr   rÁ   é   rO   r    é   u9   [%s] Connect attempt %d/%d failed: %s â€” retrying in %dsÚTELEGRAM_WEBHOOK_URLÚTELEGRAM_WEBHOOK_PORTÚ8443ÚTELEGRAM_WEBHOOK_SECRETuÁ  TELEGRAM_WEBHOOK_SECRET is required when TELEGRAM_WEBHOOK_URL is set. Without it, the webhook endpoint accepts forged updates from anyone who can reach it â€” see https://github.com/NousResearch/hermes-agent/security/advisories/GHSA-3vpc-7q5r-276h.

Generate a secret and set it in your .env:
  export TELEGRAM_WEBHOOK_SECRET="$(openssl rand -hex 32)"

Then register it with Telegram when setting the webhook via setWebhook's secret_token parameter.)Úurlparsez	/telegramz0.0.0.0T)ÚlistenÚportÚurl_pathÚwebhook_urlÚsecret_tokenrä   rå   z-[%s] Webhook server listening on 0.0.0.0:%d%sÚdelete_webhook)rå   r­   c                 óä  •— ‰j         r‰j                              ¦   «         sd S ‰                     | ¦  «        r/‰                     ‰                     | ¦  «        ¦  «        ‰_         d S ‰                     | ¦  «        rPt                               d‰j        | ¦  «         ‰                     ‰ 	                    | ¦  «        ¦  «        ‰_         d S t           
                    d‰j        | d¬¦  «         d S )Nz5[%s] Telegram network error, scheduling reconnect: %sz[%s] Telegram polling error: %sTr  )r„   Údoner¼   Úcreate_taskr  rÈ   rè   rì   rÇ   r÷   r­   )r­   ÚlooprŽ   s    €€r   Ú_polling_error_callbackz8TelegramAdapter.connect.<locals>._polling_error_callbackO  sî   ø€ ØÔ/ð ¸Ô8P×8UÒ8UÑ8WÔ8Wð Ø˜Ø×8Ò8¸Ñ?Ô?ð iØ37×3CÒ3CÀD×DaÒDaÐbgÑDhÔDhÑ3iÔ3i˜Ô0Ð0Ð0Ø×7Ò7¸Ñ>Ô>ð iÝŸšÐ'^Ð`dÔ`iÐkpÑqÔqÐqØ37×3CÒ3CÀD×DfÒDfÐglÑDmÔDmÑ3nÔ3n˜Ô0Ð0Ð0åŸšÐ%FÈÌ	ÐSXÐcg˜ÑhÔhÐhÐhÐhr   rã   )Ú
BotCommand)Útelegram_menu_commandséd   )Úmax_commandsc                 ó.   •— g | ]\  }} ‰||¦  «        ‘ŒS r   r   )r–   rÇ   Údescr|  s      €r   ú
<listcomp>z+TelegramAdapter.connect.<locals>.<listcomp>m  s6   ø€ ð 1ð 1ð 1Ù/9¨t°T�J�J˜t TÑ*Ô*ð1ð 1ð 1r   zd[%s] Telegram menu: %d commands registered, %d hidden (over 100 limit). Use /commands for full list.z1[%s] Could not register Telegram command menu: %sr  ÚwebhookÚpollingz$[%s] Connected to Telegram (%s mode)z+[%s] DM topics setup failed (non-fatal): %szTelegram startup failed: Útelegram_connect_errorrá   z&[%s] Failed to connect to Telegram: %sr   )Yr6   rè   r­   rÇ   rc   ÚtokenÚ_acquire_platform_lockr   Úbuilderr‰   rŠ   rN  rO  rõ   r¢   r¨   rx   ry   rz   rG   r¯   r¹   r2   rX   r,   r   r1   ÚrequestÚget_updates_requestÚbuildro   Úbotrp   Úadd_handlerÚTelegramMessageHandlerr   ÚTEXTÚCOMMANDÚ_handle_text_messageÚ_handle_commandÚLOCATIONrt   Ú_handle_location_messageÚPHOTOÚVIDEOÚAUDIOÚVOICEÚDocumentÚALLÚStickerÚ_handle_media_messager   Ú_handle_callback_queryrÄ   rÂ   rÃ   rÅ   rÆ   ÚrangeÚ
initializerë   rì   rí   rî   ÚstartÚRuntimeErrorÚurllib.parserp  Úpathrï   Ústart_webhookr   rô   rq   ÚcallableÚget_running_looprò   r‡   ró   r"  r|  Úhermes_cli.commandsr}  Úset_my_commandsrQ   Ú_mark_connectedrL  Ú_release_platform_lockré   )"rŽ   rˆ  Úcustom_base_urlrT  rW  Úrequest_kwargsÚdisable_fallbackr²   Úproxy_targetsÚ	proxy_urlr‰  rŠ  rÂ   rÃ   Ú_max_connectÚ_attemptÚinit_errÚwaitrt  Úwebhook_portÚwebhook_secretrp  Úwebhook_pathrv  r{  r}  Úmenu_commandsÚhidden_countr  ÚmodeÚ
topics_errr   r|  rz  s"   `                               @@r   ÚconnectzTelegramAdapter.connect�  s³  øøøè è € õ "ð 	Ý�LŠLØ^Ø”	ñô ð ð �5àŒ{Ô ð 	Ý�LŠLÐ7¸¼ÑCÔCÐCØ�5ðy	Ø×.Ò.Ð/CÀTÄ[ÔEVÐXlÑmÔmð Ø�uõ "Ô)Ñ+Ô+×1Ò1°$´+Ô2CÑDÔDˆGØ"œkÔ/×3Ò3°JÑ?Ô?ˆOØð Ø!×*Ò*¨?Ñ;Ô;�Ø!×/Ò/Ø”KÔ%×)Ò)¨/¸?ÑKÔKñô �õ —’Ø=Ø”I˜ñô ð ð#�sð #­Sð #µSð #ð #ð #ð #ð#¥ð #­uð #½ð #ð #ð #ð #ð )1¨Ð1QÐSVÑ(WÔ(WØ * 
Ð+NÐPSÑ TÔ TØ#- :Ð.TÐVZÑ#[Ô#[Ø * 
Ð+NÐPTÑ UÔ UØ!+ Ð,PÐRVÑ!WÔ!Wðð ˆNõ !#¤	Ð*PÐRTÑ UÔ U× [Ò [Ñ ]Ô ]× cÒ cÑ eÔ eð  jDð  !DÐØ×-Ò-Ñ/Ô/ˆLØð Ý%:Ñ%<Ô%<Ð<Ð<Ð<Ð<Ð<Ð<�Ý—’ØDØ”IØ—I’I˜lÑ+Ô+ñô ð ð 0Ð?°,Ð?ˆMÝ)Ð*:ÈÐWÑWÔWˆIØð E Ið EÐ6Fð EÝ—’Ø;Ø”IØ—I’I˜lÑ+Ô+ñô ð õ 'ð ð Ø$ðð à"-Õ/HÈÑ/VÔ/VÐ!Wðð ð �õ '3ð 'ð 'Ø$ð'ð 'à"-Õ/HÈÑ/VÔ/VÐ!Wð'ð 'ð 'Ð#Ð#ð ð EÝ—’ÐYÐ[_Ô[dÐfoÑpÔpÐpÝ&ÐIÐI¨ÐIÐI¸yÐIÐIÐI�Ý&2Ð&UÐ&U°^Ð&UÐ&UÈ9Ð&UÐ&UÐ&UÐ#Ð#à#ð cÝ—K’KÐ VÐX\ÔXaÑbÔbÐbÝ&Ð8Ð8¨Ð8Ð8�Ý&2Ð&DÐ&D°^Ð&DÐ&DÐ#à—o’o gÑ.Ô.×BÒBÐCVÑWÔWˆGØŸš™œˆDŒIØœ	œˆDŒIð ŒI×!Ò!Õ"8Ý”¥¤Ð/Ñ/ØÔ)ñ#ô #ñ ô ð ð ŒI×!Ò!Õ"8Ý”ØÔ$ñ#ô #ñ ô ð ð ŒI×!Ò!Õ"8ÝÔ ¥7­7°G½WÔ=MÑ#NÔ#NÑNØÔ-ñ#ô #ñ ô ð ð ŒI×!Ò!Õ"8Ý”¥¤Ñ-µ´Ñ=ÅÄÑMÕPWÔP`ÔPdÑdÕgnÔgvÔgzÑzØÔ*ñ#ô #ñ ô ð ð
 ŒI×!Ò!Õ"6°tÔ7RÑ"SÔ"SÑTÔTÐTð2ØAÐAÐAÐAÐAÐAÐAÐAÐAøÝð 2ð 2ð 2Ý*1Ð1�˜x˜x˜xð2øøøàˆLÝ! ,Ñ/Ô/ð ð �ðØœ)×.Ò.Ñ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ø�EøØ$ hµÐ8ð 	ð 	ð 	Ø ,°Ñ"2Ò2Ð2Ý" 1¨¡=°"Ñ5Ô5˜ÝŸšØWØ œI x°!¡|°\À8ÈTñô ð õ &œm¨DÑ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1àð 2Ð1Ð1Ð1Ð1øøøøð	øøøð ”)—/’/Ñ#Ô#Ð#Ð#Ð#Ð#Ð#Ð#Ð#õ œ)Ð$:¸BÑ?Ô?×EÒEÑGÔGˆKàð Hõ  #¥2¤9Ð-DÀfÑ#MÔ#MÑNÔN�Ý!#¤Ð+DÀbÑ!IÔ!I×!OÒ!OÑ!QÔ!Q�Ø%ð Ý&ð	Kñô ð ð 2Ð1Ð1Ð1Ð1Ð1Ø'˜x¨Ñ4Ô4Ô9ÐH¸[�à”iÔ'×5Ò5Ø$Ø%Ø)Ø +Ø!/Ý$*Ô$4Ø)-ð 6ñ ô ð ð ð ð ð ð ð ð &*�Ô"Ý—’ØCØ”I˜|¨\ñô ð ð õ ")¨¬Ð4DÀdÑ!KÔ!K�Ý˜NÑ+Ô+ð EØ(˜.¸eÐDÑDÔDÐDÐDÐDÐDÐDÐDÐDåÔ/Ñ1Ô1�ð	iµ9ð 	iÀð 	ið 	ið 	ið 	ið 	ið 	ið 	ið 4K�Ô0à”iÔ'×5Ò5Ý$*Ô$4Ø)-Ø#:ð 6ñ ô ð ð ð ð ð ð ð ðØ/Ð/Ð/Ð/Ð/Ð/ØFÐFÐFÐFÐFÐFð /EÐ.DÐRUÐ.VÑ.VÔ.VÑ+�˜|Ø”i×/Ò/ð 1ð 1ð 1ð 1Ø=Jð1ñ 1ô 1ñ ô ð ð ð ð ð ð ð ð  ð Ý—K’KØ~Øœ	¥3 }Ñ#5Ô#5°|ñô ð øøõ ð ð ð Ý—’ØGØ”IØØ!ð	 ñ ô ð ð ð ð ð ð øøøøðøøøð × Ò Ñ"Ô"Ð"Ø $Ô 2ÐA�9�9¸	ˆDÝ�KŠKÐ>ÀÄ	È4ÑPÔPÐPð
Ø×+Ò+Ñ-Ô-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-øÝð ð ð Ý—’ØAØ”I˜z°Dð ñ ô ð ð ð ð ð ð øøøøðøøøð �4øåð 	ð 	ð 	Ø×'Ò'Ñ)Ô)Ð)Ø5°!Ð5Ð5ˆGØ×!Ò!Ð":¸GÈtÐ!ÑTÔTÐTÝ�LŠLÐAÀ4Ä9ÈaÐZ^ˆLÑ_Ô_Ð_Ø�5�5�5�5�5øøøøð	øøøsÆ   Á!c+ ÂR c+ Ô"T+ Ô*c+ Ô+UÔ>c+ Õ UÕc+ ÕU9Õ7c+ Õ9W/ÖAW*×%c+ ×*W/×/F0c+ Þ A8` àc+ à
aà##aác+ áaáAc+ âb/ â.c+ â/
c&â9#c!ãc+ ã!c&ã&c+ ã+
eã5Aeåec              ƒ   óV  K  — t          | j                             ¦   «         ¦  «        }|D ]}|                     ¦   «          Œ|rt	          j        |ddiŽƒ d{V —† | j                             ¦   «          | j                             ¦   «          | j        rÇ	 | j        j	        r5| j        j	        j
        r$| j        j	                             ¦   «         ƒ d{V —† | j        j
        r| j                             ¦   «         ƒ d{V —† | j                             ¦   «         ƒ d{V —† n:# t          $ r-}t                               d| j        |d¬¦  «         Y d}~nd}~ww xY w|                      ¦   «          | j                             ¦   «         D ],}|r(|                     ¦   «         s|                     ¦   «          Œ-| j                             ¦   «          | j                             ¦   «          |                      ¦   «          d| _        d| _        t                               d| j        ¦  «         dS )zCStop polling/webhook, cancel pending album flushes, and disconnect.Úreturn_exceptionsTNz)[%s] Error during Telegram disconnect: %sr  z[%s] Disconnected from Telegram)Úlistr   ÚvaluesÚcancelrí   ÚgatherÚclearr~   ro   rï   rð   rñ   Úshutdownrò   rè   rì   rÇ   rª  r}   rx  r|   Ú_mark_disconnectedrp   rõ   )rŽ   Úpending_media_group_tasksr  r  s       r   Ú
disconnectzTelegramAdapter.disconnect•  sY  è è € å$(¨Ô)@×)GÒ)GÑ)IÔ)IÑ$JÔ$JÐ!Ø-ð 	ð 	ˆDØ�KŠK‰MŒMˆMˆMØ$ð 	UÝ”.Ð";ÐTÈtÐTÐTÐTÐTÐTÐTÐTÐTÐTØÔ×%Ò%Ñ'Ô'Ð'ØÔ ×&Ò&Ñ(Ô(Ð(àŒ9ð 		iðià”9Ô$ð 3¨¬Ô):Ô)Bð 3Øœ)Ô+×0Ò0Ñ2Ô2Ð2Ð2Ð2Ð2Ð2Ð2Ð2Ø”9Ô$ð +Øœ)Ÿ.š.Ñ*Ô*Ð*Ð*Ð*Ð*Ð*Ð*Ð*Ø”i×(Ò(Ñ*Ô*Ð*Ð*Ð*Ð*Ð*Ð*Ð*Ð*øÝð ið ið iÝ—’ÐJÈDÌIÐWXÐcg�ÑhÔhÐhÐhÐhÐhÐhÐhøøøøðiøøøà×#Ò#Ñ%Ô%Ð%àÔ3×:Ò:Ñ<Ô<ð 	ð 	ˆDØð ˜DŸIšI™KœKð Ø—’‘”�øØÔ'×-Ò-Ñ/Ô/Ð/ØÔ#×)Ò)Ñ+Ô+Ð+à×ÒÑ!Ô!Ð!ØˆŒ	ØˆŒ	Ý�ŠÐ5°t´yÑAÔAÐAÐAÐAs   ÂBD! Ä!
EÄ+#EÅEÚreply_toÚchunk_indexc                 óD   — |sdS | j         }|dk    rdS |dk    rdS |dk    S )a3  Determine if this message chunk should thread to the original message.

        Args:
            reply_to: The original message ID to reply to
            chunk_index: Index of this chunk (0 = first chunk)

        Returns:
            True if this chunk should be threaded to the original message
        FrÓ   ÚallTr   )ru   )rŽ   rÇ  rÈ  r¹  s       r   Ú_should_thread_replyz$TelegramAdapter._should_thread_reply¶  s@   € ð ð 	Ø�5ØÔ"ˆØ�5Š=ˆ=Ø�5Ø�UŠ]ˆ]Ø�4à !Ò#Ð#r   Úcontentc              ƒ   óz
  K  — | j         st          dd¬¦  «        S |r|                     ¦   «         st          dd¬¦  «        S 	 |                      |¦  «        }|                      || j        t          ¬¦  «        }t          |¦  «        dk    rd	„ |D ¦   «         }g }|                      |¦  «        }	 d
dl	m
}	 n# t          $ r
 t          }	Y nw xY w	 d
dl	m}
 n# t          $ r d}
Y nw xY w	 d
dl	m} n# t          t          f$ r d}Y nw xY wt!          |¦  «        D �]R\  }}|                      ||¦  «        }|rt%          |¦  «        nd}|                      |¦  «        }d}t)          d¦  «        D �]Ô}	 	  | j         j        d#t%          |¦  «        |t,          j        ||dœ|                      ¦   «         ¤Žƒ d{V —†}nÌ# t2          $ r¿}dt5          |¦  «                             ¦   «         v s#dt5          |¦  «                             ¦   «         v rnt8                               d| j        |¦  «         t?          |¦  «        } | j         j        d#t%          |¦  «        |d||dœ|                      ¦   «         ¤Žƒ d{V —†}n‚ Y d}~nd}~ww xY w �nº# |	$ �r}|
r¡tA          ||
¦  «        r‘|  !                    |¦  «        r+|�)t8                               d| j        |¦  «         d}Y d}~�Œtt5          |¦  «                             ¦   «         }d|v r+|�)t8                               d| j        |¦  «         d}Y d}~�ŒÄ‚ |rtA          ||¦  «        r‚ |dk     rFd|z  }t8                               d| j        |dz   ||¦  «         tE          j#        |¦  «        ƒ d{V —† n‚ Y d}~�Œ+d}~wt2          $ r›}tI          |dd¦  «        }|€#dt5          |¦  «                             ¦   «         v r_|dk     rY|�tK          |¦  «        nd}t8                               d| j        |dz   ||¦  «         tE          j#        |¦  «        ƒ d{V —† Y d}~�ŒÍ‚ d}~ww xY w| &                    t5          |j'        ¦  «        ¦  «         �ŒTt          d|r|d
         ndd|i¬¦  «        S # t2          $ r¥}t8           (                    d| j        |d¬¦  «         tS          ¦   «          *                    d ¦  «        }t5          |¦  «                             ¦   «         }|rtA          ||¦  «        pd!|v }t          dt5          |¦  «        | ¬"¦  «        cY d}~S d}~ww xY w)$z"Send a message to a Telegram chat.FúNot connected©Úsuccessr­   TN©rÐ  Ú
message_id)Úlen_fnrO   c                 ó:   — g | ]}t          j        d d|¦  «        ‘ŒS )z \((\d+)/(\d+)\)$z \\(\1/\2\\)r@   )r–   Úchunks     r   r‚  z(TelegramAdapter.send.<locals>.<listcomp>ã  s7   € ð ð ð àõ ”FÐ/°À%ÑHÔHðð ð r   r   )rÂ   )Ú
BadRequest)rÃ   r  )r  r8   Ú
parse_modeÚreply_to_message_idr¡   ÚparseÚmarkdownz<[%s] MarkdownV2 parse failed, falling back to plain text: %sz<[%s] Thread %s not found, retrying without message_thread_idzmessage to be replied not foundz8[%s] Reply target deleted, retrying without reply_to: %sr    z>[%s] Network error on send (attempt %d/3), retrying in %ds: %sÚretry_afterúretry afterç      ð?zI[%s] Telegram flood control on send (attempt %d/3), retrying in %.1fs: %sÚmessage_ids)rÐ  rÒ  Úraw_responsez([%s] Failed to send Telegram message: %sr  Ú	_TimedOutz	timed out)rÐ  r­   râ   r   )+rp   r'   rG   Úformat_messageÚtruncate_messageÚMAX_MESSAGE_LENGTHr/   rQ   r¤   rÄ   rÂ   rÅ   rÆ   rÖ  rÃ   ÚAttributeErrorÚ	enumeraterË  r¨   rª   rž  Úsend_messager   ÚMARKDOWN_V2rÛ   rò   r¢   r¯   rè   rì   rÇ   rC   r¶   r°   rí   rî   rt   rx   rT   rÒ  r­   ÚlocalsrŠ   )rŽ   r  rÌ  rÇ  rž   Ú	formattedÚchunksrÞ  r    Ú_NetErrÚ_BadReqrà  r\   rÕ  Úshould_threadÚreply_to_idÚeffective_thread_idÚmsgÚ_send_attemptÚmd_errorÚplain_chunkÚsend_errÚ	err_lowerr³  rÛ  r  Ú_toÚerr_strÚ
is_timeouts                                r   ÚsendzTelegramAdapter.sendÊ  sý  è è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCð ð 	=˜gŸmšm™oœoð 	=Ý d°tÐ<Ñ<Ô<Ð<ðJ	Uà×+Ò+¨GÑ4Ô4ˆIØ×*Ò*Ø˜4Ô2½9ð +ñ ô ˆFõ �6‰{Œ{˜QŠˆðð à!'ðñ ô �ð
 ˆKØ×0Ò0°Ñ:Ô:ˆIð"ØBÐBÐBÐBÐBÐBÐBøÝð "ð "ð "Ý!���ð"øøøðØ@Ð@Ð@Ð@Ð@Ð@Ð@øÝð ð ð Ø���ðøøøð!Ø@Ð@Ð@Ð@Ð@Ð@Ð@øÝ¥Ð0ð !ð !ð !Ø �	�	�	ð!øøøõ & fÑ-Ô-ð Z8ñ Z8‘��5Ø $× 9Ò 9¸(ÀAÑ FÔ F�Ø/<ÐF�c (™mœm˜mÀ$�Ø&*×&FÒ&FÀyÑ&QÔ&QÐ#à�Ý%*¨1¡X¤Xð Sñ S�MðRð&Ø(>¨¬	Ô(>ð )Ý(+¨G©¬Ø%*Ý+4Ô+@Ø4?Ø2Eð)ð )ð #'×";Ò";Ñ"=Ô"=ð)ð )ð #ð #ð #ð #ð #ð #˜C˜Cøõ  )ð &ð &ð &à&­#¨h©-¬-×*=Ò*=Ñ*?Ô*?Ð?Ð?À:ÕQTÐU]ÑQ^ÔQ^×QdÒQdÑQfÔQfÐCfÐCfÝ &§¢Ð/mÐosÔoxð  {Cñ  !Dô  !Dð  !DÝ.9¸%Ñ.@Ô.@ Ø,B¨D¬IÔ,Bð -"Ý,/°©L¬LØ)4Ø/3Ø8CØ6Ið-"ð -"ð '+×&?Ò&?Ñ&AÔ&Að-"ð -"ð '"ð '"ð '"ð '"ð '"ð '"  ð !&ð !$    øøøøð&øøøð ™øØ"ð ("ñ ("ð ("ð
 #ð "¥z°(¸GÑ'DÔ'Dð "Ø#×>Ò>¸xÑHÔHð 	)ÐM`ÐMlõ !'§¢Ø$bØ$(¤IÐ/Bñ!"ô !"ð !"ð 7;Ð 3Ø (   ¡Ý(+¨H©¬×(;Ò(;Ñ(=Ô(=˜IØ@ÀIÐMÐMÐR]ÐRiõ !'§¢Ø$^Ø$(¤I¨xñ!"ô !"ð !"ð /3 Ø (   ¡à!ð %ð "­°H¸iÑ)HÔ)Hð "Ø!Ø(¨1Ò,Ð,Ø#$¨Ñ#5˜DÝ"ŸNšNÐ+kØ+/¬9°mÀaÑ6GÈÈxñYô Yð Yå")¤-°Ñ"5Ô"5Ð5Ð5Ð5Ð5Ð5Ð5Ð5Ð5à!ð 6Ð5Ð5Ð5Ñ5øøøøõ %ð ð ð Ý&-¨h¸ÀtÑ&LÔ&L˜Ø&Ð2°mÅsÈ8Á}Ä}×GZÒGZÑG\ÔG\Ð6\Ð6\Ø,¨qÒ0Ð0Ø=HÐ=T¥u¨[Ñ'9Ô'9Ð'9ÐZ] Ý &§¢Ø$oØ$(¤IØ$1°AÑ$5Ø$(Ø$,ñ!"ô !"ð !"õ '.¤m°DÑ&9Ô&9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ø (   ¡Øøøøøðøøøð ×"Ò"¥3 s¤~Ñ#6Ô#6Ñ7Ô7Ð7Ñ7åØØ-8ÐB˜; qœ>˜>¸dØ+¨[Ð9ðñ ô ð øõ ð 	Uð 	Uð 	UÝ�LŠLÐCÀTÄYÐPQÐ\`ˆLÑaÔaÐaõ ‘(”(—,’,˜{Ñ+Ô+ˆCÝ˜!‘f”f—l’l‘n”nˆGØÐ4¥*¨Q°Ñ"4Ô"4ÐO¸ÈÐ9OˆJÝ eµ3°q±6´6ÈÀ^ÐTÑTÔTÐTÐTÐTÐTÐTÐTøøøøð	Uøøøs  ÁA-R Â1B8 Â7R Â8CÃ	R ÃCÃR ÃC ÃR ÃC&Ã#R Ã%C&Ã&R Ã*C1 Ã0R Ã1DÄR ÄDÄA*R Å3AF;Æ:J
Æ;
JÇB5I?É:J
É?JÊJ
ÊR Ê
QÊANËR Ë"A
NÌ,R Ì2A!NÎR ÎQÎ&BP<Ð5R Ð;P<Ð<QÑA	R Ò
T:ÒBT5Ô/T:Ô5T:)ÚfinalizerÒ  rú  c             ƒ   óº  K  — | j         st          dd¬¦  «        S 	 |                      |¦  «        }	 | j                              t	          |¦  «        t	          |¦  «        |t
          j        ¬¦  «        ƒ d{V —† n�# t          $ r€}dt          |¦  «         	                    ¦   «         v rt          d|¬¦  «        cY d}~S | j                              t	          |¦  «        t	          |¦  «        |¬	¦  «        ƒ d{V —† Y d}~nd}~ww xY wt          d|¬¦  «        S # t          $ �r6}t          |¦  «         	                    ¦   «         }d|v rt          d|¬¦  «        cY d}~S d
|v sd|v r€t          || j        dz
  ¦  «        dz   }		 | j                              t	          |¦  «        t	          |¦  «        |	¬	¦  «        ƒ d{V —† n# t          $ r Y nw xY wt          d|¬¦  «        cY d}~S t          |dd¦  «        }
|
€d|v �r|
r|
nd}t                               d| j        |¦  «         |dk    rt          dd|› �¬¦  «        cY d}~S t!          j        |¦  «        ƒ d{V —† 	 | j                              t	          |¦  «        t	          |¦  «        |¬	¦  «        ƒ d{V —† t          d|¬¦  «        cY d}~S # t          $ rN}t                               d| j        |¦  «         t          dt          |¦  «        ¬¦  «        cY d}~cY d}~S d}~ww xY wt                               d| j        ||d¬¦  «         t          dt          |¦  «        ¬¦  «        cY d}~S d}~ww xY w)z(Edit a previously sent Telegram message.FrÎ  rÏ  )r  rÒ  r8   r×  Nznot modifiedTrÑ  )r  rÒ  r8   Úmessage_too_longztoo longé   u   â€¦rÛ  rÜ  rÝ  z*[%s] Telegram flood control, waiting %.1fsg      @zflood_control:z+[%s] Edit retry failed after flood wait: %sz+[%s] Failed to edit Telegram message %s: %sr  )rp   r'   rá  Úedit_message_textr¨   r   rç  rò   r¢   r¯   r0   rã  rt   rè   rì   rÇ   rí   rî   r­   )rŽ   r  rÒ  rÌ  rú  ré  Úfmt_errr  r÷  Ú	truncatedrÛ  r³  r  s                r   Úedit_messagezTelegramAdapter.edit_messagee  sµ  è è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCðJ	;Ø×+Ò+¨GÑ4Ô4ˆIðØ”i×1Ò1Ý ™LœLÝ" :™œØ"Ý(Ô4ð	 2ñ ô ð ð ð ð ð ð ð ð øõ ð 	ð 	ð 	à!¥S¨¡\¤\×%7Ò%7Ñ%9Ô%9Ð9Ð9Ý%¨d¸zÐJÑJÔJÐJÐJÐJÐJÐJÐJà”i×1Ò1Ý ™LœLÝ" :™œØ ð 2ñ ô ð ð ð ð ð ð ð ð ð ð ð ð øøøøð	øøøõ  d°zÐBÑBÔBÐBøÝð 6	;ñ 6	;ð 6	;Ý˜!‘f”f—l’l‘n”nˆGà Ð(Ð(Ý!¨$¸:ÐFÑFÔFÐFÐFÐFÐFÐFÐFð " WÐ,Ð,°
¸gÐ0EÐ0EÝ6Ø˜TÔ4°rÑ9ñô àñ�	ðØœ)×5Ò5Ý # G¡¤Ý#& z¡?¤?Ø&ð 6ñ ô ð ð ð ð ð ð ð ð øõ
 !ð ð ð Ø�Dðøøøå!¨$¸:ÐFÑFÔFÐFÐFÐFÐFÐFÐFõ " ! ]°DÑ9Ô9ˆKØÐ&¨-¸7Ð*BÑ*BØ&1Ð:�{�{°s�Ý—’Ø@Ø”I˜tñô ð ð ˜#’:�:Ý%¨eÐ;RÈDÐ;RÐ;RÐSÑSÔSÐSÐSÐSÐSÐSÐSÝ”m DÑ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)ðKØœ)×5Ò5Ý # G¡¤Ý#& z¡?¤?Ø$ð 6ñ ô ð ð ð ð ð ð ð õ
 &¨d¸zÐJÑJÔJÐJÐJÐJÐJÐJÐJøÝ ð Kð Kð KÝ—L’LØEØœ	 9ñô ð õ &¨e½3¸y¹>¼>ÐJÑJÔJÐJÐJÐJÐJÐJÐJÐJÐJÐJÐJÐJøøøøðKøøøõ �LŠLØ=Ø”	ØØØð ñ ô ð õ  eµ3°q±6´6Ð:Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:øøøøðm6	;øøøsÚ   œD ²AA; Á:D Á;
DÂ3D Â8DÂ9D Â>=D Ã;D Ä DÄD ÄMÄ$5MÅMÅ#MÆ=GÇ MÇ
GÇMÇGÇMÇ!MÇ'AMÈ?MÉMÉ AJ3Ê-MÊ3
LÊ=>LË;LË<MÌ MÌLÌAMÍMÍMr“   ÚpromptÚsession_keyc              ƒ   ó8  K  — | j         st          dd¬¦  «        S 	 |rd|› d�nd}d|› |› �}t          t          dd	¬
¦  «        t          dd¬
¦  «        gg¦  «        } | j         j        dt          |¦  «        |t          j        |dœ|                      ¦   «         ¤Žƒ d{V —†}t          dt          |j
        ¦  «        ¬¦  «        S # t          $ rI}	t                               d| j        |	¦  «         t          dt          |	¦  «        ¬¦  «        cY d}	~	S d}	~	ww xY w)zÐSend an inline-keyboard update prompt (Yes / No buttons).

        Used by the gateway ``/update`` watcher when ``hermes update --gateway``
        needs user input (stash restore, config migration).
        FrÎ  rÏ  z (default: ú)r“   u    âš• *Update needs your input:*

u   âœ“ Yeszupdate_prompt:y©Úcallback_datau   âœ— Nozupdate_prompt:n©r  r8   r×  Úreply_markupNTrÑ  z"[%s] send_update_prompt failed: %sr   )rp   r'   r   r
   ræ  r¨   r   ÚMARKDOWNrÛ   r¢   rÒ  rò   rè   rì   rÇ   )
rŽ   r  r  rÊ   r  Údefault_hintr8   Úkeyboardrð  r  s
             r   Úsend_update_promptz"TelegramAdapter.send_update_prompt¼  s}  è è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCð	;Ø7>ÐFÐ3¨Ð3Ð3Ð3Ð3ÀBˆLØN¸ÐNÀÐNÐNˆDÝ+å(¨ÐBSÐTÑTÔTÝ(¨ÐARÐSÑSÔSðð-ñ ô ˆHð /˜œ	Ô.ð Ý˜G™œØÝ$Ô-Ø%ð	ð ð
 ×+Ò+Ñ-Ô-ðð ð ð ð ð ð ð ˆCõ  dµs¸3¼>Ñ7JÔ7JÐKÑKÔKÐKøÝð 	;ð 	;ð 	;Ý�NŠNÐ?ÀÄÈAÑNÔNÐNÝ eµ3°q±6´6Ð:Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:øøøøð	;øøøs   œB)C Ã
DÃ>DÄDÄDúdangerous commandÚcommandÚdescriptionc           	   ƒ   ó  K  — | j         st          dd¬¦  «        S 	 t          |¦  «        dk    r|dd…         dz   n|}dt          j        |¦  «        › dt          j        |¦  «        › �}|                      |¦  «        }d	dl}	t          | d
¦  «        s|	                     d¦  «        | _	        t          | j	        ¦  «        }
t          t          dd|
› �¬¦  «        t          dd|
› �¬¦  «        gt          dd|
› �¬¦  «        t          dd|
› �¬¦  «        gg¦  «        }t          |¦  «        |t          j        |dœ|                      ¦   «         ¥}|                      |¦  «        }|�||d<    | j         j        di |¤Žƒ d{V —†}|| j        |
<   t          dt)          |j        ¦  «        ¬¦  «        S # t,          $ rI}t.                               d| j        |¦  «         t          dt)          |¦  «        ¬¦  «        cY d}~S d}~ww xY w)uá   Send an inline-keyboard approval prompt with interactive buttons.

        The buttons call ``resolve_gateway_approval()`` to unblock the waiting
        agent thread â€” same mechanism as the text ``/approve`` flow.
        FrÎ  rÏ  iØ  Nú...u.   âš ï¸� <b>Command Approval Required</b>

<pre>z</pre>

Reason: r   Ú_approval_counterrO   u   âœ… Allow Oncezea:once:r  u   âœ… Sessionzea:session:u
   âœ… Alwaysz
ea:always:u   â�Œ Denyzea:deny:r  r¡   TrÑ  z"[%s] send_exec_approval failed: %sr   )rp   r'   rQ   Ú_htmlÚescaper¤   Ú	itertoolsÚhasattrÚcountr  Únextr   r
   r¨   r   ÚHTMLrÛ   rª   ræ  r�   r¢   rÒ  rò   rè   rì   rÇ   )rŽ   r  r  r  r  rž   Úcmd_previewr8   r    r  Úapproval_idr  r  r¡   rð  r  s                   r   Úsend_exec_approvalz"TelegramAdapter.send_exec_approvalÜ  sƒ  è è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCð1	;Ý47¸±L´LÀ4Ò4GÐ4G˜' % 4 %œ.¨5Ñ0Ð0ÈWˆKð7Ýœ [Ñ1Ô1ð7ð 7å œ<¨Ñ4Ô4ð7ð 7ð ð ×0Ò0°Ñ:Ô:ˆIð
 ÐÐÐÝ˜4Ð!4Ñ5Ô5ð <Ø)2¯ª¸Ñ);Ô);�Ô&Ý˜tÔ5Ñ6Ô6ˆKå+å(Ð)9ÐIaÐT_ÐIaÐIaÐbÑbÔbÝ(¨ÐFaÐT_ÐFaÐFaÐbÑbÔbðõ
 )¨ÐE_ÐR]ÐE_ÐE_Ð`Ñ`Ô`Ý(¨ÐC[ÈkÐC[ÐC[Ð\Ñ\Ô\ðð	-ñ 	ô 	ˆHõ ˜w™<œ<ØÝ'œnØ (ð	&ð &ð
 ×+Ò+Ñ-Ô-ð&ˆFð !%× @Ò @ÀÑ KÔ KÐØ Ð,Ø.?�Ð*Ñ+à.˜œ	Ô.Ð8Ð8°Ð8Ð8Ð8Ð8Ð8Ð8Ð8Ð8ˆCð 1<ˆDÔ  Ñ-å dµs¸3¼>Ñ7JÔ7JÐKÑKÔKÐKøÝð 	;ð 	;ð 	;Ý�NŠNÐ?ÀÄÈAÑNÔNÐNÝ eµ3°q±6´6Ð:Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:øøøøð	;øøøs   œFF1 Æ1
HÆ;>G?Ç9HÇ?HÚ	providersÚcurrent_modelÚcurrent_providerc           
   ƒ   ó˜  ‡K  — | j         st          dd¬¦  «        S 	 ddlm} n# t          $ r d„ }Y nw xY w	 g Š|D ]Ž}	|	                     dt          |	                     dg ¦  «        ¦  «        ¦  «        }
|	d	         › d
|
› d�}|	                     d¦  «        rd|› �}‰                     t          |d|	d         › �¬¦  «        ¦  «         Œ�ˆfd„t          dt          ‰¦  «        d¦  «        D ¦   «         }|                     t          dd¬¦  «        g¦  «         t          |¦  «        } ||¦  «        }d|pd› d|› d�}|r|                     d¦  «        nd} | j         j        d t          |¦  «        |t          j        ||rt          |¦  «        nddœ|                      ¦   «         ¤Žƒ d{V —†}|j        |||||dœ| j        t%          |¦  «        <   t          dt%          |j        ¦  «        ¬¦  «        S # t&          $ rI}t(                               d| j        |¦  «         t          dt%          |¦  «        ¬¦  «        cY d}~S d}~ww xY w)!u¿   Send an interactive inline-keyboard model picker.

        Two-step drill-down: provider selection â†’ model selection.
        Edits the same message in-place as the user navigates.
        FrÎ  rÏ  r   ©Ú	get_labelc                 ó   — | S r¦   r   ©Úslugs    r   r#  z4TelegramAdapter.send_model_picker.<locals>.get_label1  ó   € Ø�r   Útotal_modelsÚmodelsrÇ   ú (r  Ú
is_currentõ   âœ“ úmp:r&  r  c                 ó*   •— g | ]}‰||d z   …         ‘ŒS ©r    r   ©r–   r\   Úbuttonss     €r   r‚  z5TelegramAdapter.send_model_picker.<locals>.<listcomp>A  ó&   ø€ ÐJÐJÐJ¨1�G˜A  A¡˜IÔ&ÐJÐJÐJr   r    õ
   âœ— CancelÚmxõ+   âš™ *Model Configuration*

Current model: `Úunknownú`
Provider: ú

Select a provider:r    N)r  r8   r×  r	  r¡   )Úmsg_idr  r  Úon_model_selectedr  r   TrÑ  z![%s] send_model_picker failed: %sr   )rp   r'   Úhermes_cli.providersr#  rÅ   rŠ   rQ   rT   r
   rž  r   ræ  r¨   r   r
  rÛ   rÒ  rŒ   r¢   rò   rè   rì   rÇ   )rŽ   r  r  r  r   r  r:  rž   r#  Úpr  ÚlabelÚrowsr  Úprovider_labelr8   r    rð  r  r1  s                      @r   Úsend_model_pickerz!TelegramAdapter.send_model_picker  s  øè è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCð	Ø6Ð6Ð6Ð6Ð6Ð6Ð6øÝð 	ð 	ð 	ðð ð ð ð ð	øøøð0	;àˆGØð ð �ØŸš˜n­c°!·%²%¸À"Ñ2EÔ2EÑ.FÔ.FÑGÔG�Ø˜Vœ9Ð0Ð0¨Ð0Ð0Ð0�Ø—5’5˜Ñ&Ô&ð +Ø* 5˜N˜N�Eà—’Ý(¨Ð>OÀAÀfÄIÐ>OÐ>OÐPÑPÔPñô ð ð ð KÐJÐJÐJµ°a½¸W¹¼ÀqÑ0IÔ0IÐJÑJÔJˆDØ�KŠKÕ-¨lÈ$ÐOÑOÔOÐPÑQÔQÐQÝ+¨DÑ1Ô1ˆHà&˜YÐ'7Ñ8Ô8ˆNð&Ø#0Ð#=°Ið&ð &à+ð&ð &ð &ð ð 6>ÐG˜Ÿš [Ñ1Ô1Ð1À4ˆIØ.˜œ	Ô.ð Ý˜G™œØÝ$Ô-Ø%Ø4=Ð"G¥# i¡.¤. .À4ðð ð ×+Ò+Ñ-Ô-ðð ð ð ð ð ð ð ˆCð œ.Ø&Ø*Ø%6Ø!.Ø$4ð6ð 6ˆDÔ$¥S¨¡\¤\Ñ2õ  dµs¸3¼>Ñ7JÔ7JÐKÑKÔKÐKøÝð 	;ð 	;ð 	;Ý�NŠNÐ>ÀÄ	È1ÑMÔMÐMÝ eµ3°q±6´6Ð:Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:øøøøð	;øøøs*   �$ ¤4³4¸F=G6 Ç6
I	È >IÈ>I	ÉI	rj  r)  Úpagec                 óV  ‡— | j         }t          |¦  «        }t          d||z   dz
  |z  ¦  «        }t          dt          ||dz
  ¦  «        ¦  «        }||z  }t          ||z   |¦  «        }|||…         }g Št	          |¦  «        D ]r\  }	}
||	z   }d|
v r|
                     d¦  «        d         n|
}t          |¦  «        dk    r|dd…         dz   }‰                     t          |d	|› �¬
¦  «        ¦  «         Œsˆfd„t          dt          ‰¦  «        d¦  «        D ¦   «         }|dk    r¦g }|dk    r*|                     t          dd|dz
  › �¬
¦  «        ¦  «         |                     t          |dz   › d|› �d¬
¦  «        ¦  «         ||dz
  k     r*|                     t          dd|dz   › �¬
¦  «        ¦  «         |                     |¦  «         |                     t          dd¬
¦  «        t          dd¬
¦  «        g¦  «         |dk    rd|dz   › d|› d|› d�nd}t          |¦  «        |fS )zBBuild paginated model buttons. Returns (keyboard, page_info_text).rO   r   ú/éÿÿÿÿé&   Né#   r  úmm:r  c                 ó*   •— g | ]}‰||d z   …         ‘ŒS r/  r   r0  s     €r   r‚  z9TelegramAdapter._build_model_keyboard.<locals>.<listcomp>}  s&   ø€ ÐFÐFÐF q�˜˜A ™E˜	Ô"ÐFÐFÐFr   r    u   â—€ Prevúmg:zmx:noopu   Next â–¶u   â—€ BackÚmbr3  r4  r*  u   â€“z of r  r“   )
Ú_MODEL_PAGE_SIZErQ   Úmaxrë   rå  rP   rT   r
   rž  r   )rŽ   r)  rA  Ú	page_sizeÚtotalÚtotal_pagesr   ÚendÚpage_modelsr\   Úmodel_idÚabs_idxÚshortr>  ÚnavÚ	page_infor1  s                   @r   Ú_build_model_keyboardz%TelegramAdapter._build_model_keyboardh  sš  ø€ àÔ)ˆ	Ý�F‘”ˆÝ˜!˜e iÑ/°!Ñ3¸	ÑAÑBÔBˆÝ�1•c˜$ ¨a¡Ñ0Ô0Ñ1Ô1ˆà�yÑ ˆÝ�%˜)Ñ# UÑ+Ô+ˆØ˜U 3˜YÔ'ˆàˆÝ$ [Ñ1Ô1ð 	ð 	‰KˆAˆxØ˜a‘iˆGØ/2°h¨¨�H—N’N 3Ñ'Ô'¨Ô+Ð+ÀHˆEÝ�5‰zŒz˜BŠˆØ˜c˜r˜cœ
 UÑ*�Ø�NŠNÝ$ U¸/À¸/¸/ÐJÑJÔJñô ð ð ð GÐFÐFÐF­E°!µS¸±\´\À1Ñ,EÔ,EÐFÑFÔFˆð ˜Š?ˆ?ØˆCØ�aŠxˆxØ—
’
Õ/°
ÐJZÐPTÐWXÑPXÐJZÐJZÐ[Ñ[Ô[Ñ\Ô\Ð\Ø�JŠJÕ+¨t°a©xÐ,GÐ,G¸+Ð,GÐ,GÐW`ÐaÑaÔaÑbÔbÐbØ�k A‘oÒ%Ð%Ø—
’
Õ/°
ÐJZÐPTÐWXÑPXÐJZÐJZÐ[Ñ[Ô[Ñ\Ô\Ð\Ø�KŠK˜ÑÔÐà�ŠÝ  ¸4Ð@Ñ@Ô@Ý  ¸TÐBÑBÔBð
ñ 	ô 	ð 	ð
 =HÈ!ºO¸OÐ8˜ ™Ð8Ð8 sÐ8Ð8°Ð8Ð8Ð8Ð8ÐQSˆ	Ý# DÑ)Ô)¨9Ð4Ð4r   Údatac           
   ƒ   ó*  ‡‡K  — | j                              |¦  «        }|s|                     d¬¦  «        ƒ d{V —† dS 	 ddlm} n# t
          $ r d„ }Y nw xY w|                     d¦  «        �rI|dd…         Št          ˆfd	„|d
         D ¦   «         d¦  «        }|s|                     d¬¦  «        ƒ d{V —† dS |                     dg ¦  «        }‰|d<   |                     d‰¦  «        |d<   ||d<   d|d<   |                      |d¦  «        \  }}	|                     d‰¦  «        }
|                     dt          |¦  «        ¦  «        }t          |¦  «        }||k    r	d||z
  › d�nd}| 
                    d|
› d|	› d|› �t          j        |¬¦  «        ƒ d{V —† |                     ¦   «         ƒ d{V —† dS |                     d¦  «        �ri	 t          |dd…         ¦  «        }n-# t          $ r  |                     d¬¦  «        ƒ d{V —† Y dS w xY w|                     dg ¦  «        }||d<   |                      ||¦  «        \  }}	|                     dd¦  «        }
|                     dd¦  «        Št          ˆfd„|d
         D ¦   «         d¦  «        }|r#|                     dt          |¦  «        ¦  «        nt          |¦  «        }t          |¦  «        }||k    r	d||z
  › d�nd}| 
                    d|
› d|	› d|› �t          j        |¬¦  «        ƒ d{V —† |                     ¦   «         ƒ d{V —† dS |                     d¦  «        �rÕ	 t          |dd…         ¦  «        }n-# t          $ r  |                     d¬¦  «        ƒ d{V —† Y dS w xY w|                     dg ¦  «        }|dk     s|t          |¦  «        k    r|                     d¬¦  «        ƒ d{V —† dS ||         }|                     dd¦  «        Š|                     d ¦  «        }|s|                     d!¬¦  «        ƒ d{V —† dS 	  |||‰¦  «        ƒ d{V —†}n7# t          $ r*}t                                d"|¦  «         d#|› �}Y d}~nd}~ww xY w	 | 
                    |t          j        d¬¦  «        ƒ d{V —† n@# t          $ r3 	 | 
                    |dd¬¦  «        ƒ d{V —† n# t          $ r Y nw xY wY nw xY w|                     d$¬¦  «        ƒ d{V —† | j                              |d¦  «         dS |d%k    �rug Š|d
         D ]Ž}|                     dt          |                     dg ¦  «        ¦  «        ¦  «        }|d         › d&|› d'�}|                     d(¦  «        rd)|› �}‰                     t)          |d|d*         › �¬+¦  «        ¦  «         Œ�ˆfd,„t+          dt          ‰¦  «        d-¦  «        D ¦   «         }|                     t)          d.d/¬+¦  «        g¦  «         t-          |¦  «        }	  ||d0         ¦  «        }n# t          $ r |d0         }Y nw xY w| 
                    d1|d2         pd3› d4|› d5�t          j        |¬¦  «        ƒ d{V —† |                     ¦   «         ƒ d{V —† dS |d/k    rT| j                              |d¦  «         | 
                    d6d¬7¦  «        ƒ d{V —† |                     ¦   «         ƒ d{V —† dS |                     ¦   «         ƒ d{V —† dS )8zDHandle model picker inline keyboard callbacks (mp:/mm:/mb:/mx:/mg:).u$   Picker expired â€” use /model again.r<   Nr   r"  c                 ó   — | S r¦   r   r%  s    r   r#  z@TelegramAdapter._handle_model_picker_callback.<locals>.get_label�  r'  r   r-  r  c              3   ó4   •K  — | ]}|d          ‰k    ¯|V — ŒdS ©r&  Nr   ©r–   r<  Úprovider_slugs     €r   rµ   z@TelegramAdapter._handle_model_picker_callback.<locals>.<genexpr>¤  ó1   øè è € ÐMÐM�q°!°F´)¸}Ò2LÐ2L�Ð2LÐ2LÐ2LÐ2LÐMÐMr   r  zProvider not found.r)  Úselected_providerrÇ   Úselected_provider_nameÚ
model_listÚ
model_pager(  z
_u2    more available â€” type `/model <name>` directly_r“   u&   âš™ *Model Configuration*

Provider: *rš   z
Select a model:©r8   r×  r	  rI  zInvalid page.c              3   ó4   •K  — | ]}|d          ‰k    ¯|V — ŒdS r\  r   r]  s     €r   rµ   z@TelegramAdapter._handle_model_picker_callback.<locals>.<genexpr>Ó  r_  r   rG  zInvalid selection.zInvalid model index.r:  zPicker expired.zModel picker switch failed: %szError switching model: zModel switched!rJ  r*  r  r+  r,  r&  r  c                 ó*   •— g | ]}‰||d z   …         ‘ŒS r/  r   r0  s     €r   r‚  zATelegramAdapter._handle_model_picker_callback.<locals>.<listcomp>"  r2  r   r    r3  r4  r   r5  r  r6  r7  r8  zModel selection cancelled.)r8   r	  )rŒ   rŠ   Úanswerr;  r#  rÅ   rS   r  rW  rQ   rþ  r   r
  r¨   rR  rò   rè   r­   ÚpoprT   r
   rž  r   )rŽ   ÚqueryrX  r  Ústater#  Úproviderr)  r  rV  ÚpnamerN  Úshownr‰   rA  Úidxrb  rR  ÚcallbackÚresult_textÚexcr<  r  r=  r>  r?  r1  r^  s                             @@r   Ú_handle_model_picker_callbackz-TelegramAdapter._handle_model_picker_callback‘  s
  øøè è € ð Ô(×,Ò,¨WÑ5Ô5ˆØð 	Ø—,’,Ð$J�,ÑKÔKÐKÐKÐKÐKÐKÐKÐKØˆFð	Ø6Ð6Ð6Ð6Ð6Ð6Ð6øÝð 	ð 	ð 	ðð ð ð ð ð	øøøð �?Š?˜5Ñ!Ô!ñ b	!à    œHˆMÝØMÐMÐMÐM˜E +Ô.ÐMÑMÔMØñô ˆHð ð Ø—l’lÐ(=�lÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ø�à—\’\ (¨BÑ/Ô/ˆFØ)6ˆEÐ%Ñ&Ø.6¯lªl¸6À=Ñ.QÔ.QˆEÐ*Ñ+Ø"(ˆE�,ÑØ"#ˆE�,Ñà"&×"<Ò"<¸VÀQÑ"GÔ"GÑˆH�ià—L’L ¨Ñ7Ô7ˆEØ—L’L µ°V±´Ñ=Ô=ˆEÝ˜‘K”KˆEØ_dÐglÒ_lÐ_lÐ[˜% %™-Ð[Ð[Ð[Ð[ÐrtˆEà×)Ò)ð.Ø"'ð.ð .Ø*3ð.ð .à&+ð.ð .õ %Ô-Ø%ð *ñ ô ð ð ð ð ð ð ð ð —,’,‘.”.Ð Ð Ð Ð Ð Ð Ð Ð Ð à�_Š_˜UÑ#Ô#ñ 	!ðÝ˜4   œ8‘}”}��øÝð ð ð Ø—l’l¨�lÑ8Ô8Ð8Ð8Ð8Ð8Ð8Ð8Ð8Ø��ðøøøð —Y’Y˜|¨RÑ0Ô0ˆFØ"&ˆE�,Ñà"&×"<Ò"<¸VÀTÑ"JÔ"JÑˆH�ià—I’IÐ6¸Ñ;Ô;ˆEØ!ŸIšIÐ&9¸2Ñ>Ô>ˆMÝØMÐMÐMÐM˜E +Ô.ÐMÑMÔMØñô ˆHð BJÐZ�H—L’L µ°V±´Ñ=Ô=Ð=ÍsÐSYÉ{Ì{ˆEÝ˜‘K”KˆEØ_dÐglÒ_lÐ_lÐ[˜% %™-Ð[Ð[Ð[Ð[ÐrtˆEà×)Ò)ð.Ø"'ð.ð .Ø*3ð.ð .à&+ð.ð .õ %Ô-Ø%ð *ñ ô ð ð ð ð ð ð ð ð —,’,‘.”.Ð Ð Ð Ð Ð Ð Ð Ð Ð à�_Š_˜UÑ#Ô#ñ ]	!ðÝ˜$˜q˜r˜rœ(‘m”m��øÝð ð ð Ø—l’lÐ(<�lÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=Ø��ðøøøð Ÿš <°Ñ4Ô4ˆJØ�QŠwˆw˜#¥ Z¡¤Ò0Ð0Ø—l’lÐ(>�lÑ?Ô?Ð?Ð?Ð?Ð?Ð?Ð?Ð?Ø�à! #”ˆHØ!ŸIšIÐ&9¸2Ñ>Ô>ˆMØ—y’yÐ!4Ñ5Ô5ˆHàð Ø—l’lÐ(9�lÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:Ø�ð>Ø$, H¨W°hÀÑ$NÔ$NÐNÐNÐNÐNÐNÐN��øÝð >ð >ð >Ý—’Ð=¸sÑCÔCÐCØ=¸Ð=Ð=������øøøøð>øøøð
Ø×-Ò-Ø$Ý(Ô1Ø!%ð .ñ ô ð ð ð ð ð ð ð ð øõ
 ð 	ð 	ð 	ðØ×1Ò1Ø(Ø#'Ø%)ð 2ñ ô ð ð ð ð ð ð ð ð øõ
 !ð ð ð Ø�Dðøøøøøð	øøøð —,’,Ð$5�,Ñ6Ô6Ð6Ð6Ð6Ð6Ð6Ð6Ð6ð Ô$×(Ò(¨°$Ñ7Ô7Ð7Ð7Ð7à�TŠ\‰\àˆGØ˜;Ô'ð ð �ØŸš˜n­c°!·%²%¸À"Ñ2EÔ2EÑ.FÔ.FÑGÔG�Ø˜Vœ9Ð0Ð0¨Ð0Ð0Ð0�Ø—5’5˜Ñ&Ô&ð +Ø* 5˜N˜N�EØ—’Ý(¨Ð>OÀAÀfÄIÐ>OÐ>OÐPÑPÔPñô ð ð ð KÐJÐJÐJµ°a½¸W¹¼ÀqÑ0IÔ0IÐJÑJÔJˆDØ�KŠKÕ-¨lÈ$ÐOÑOÔOÐPÑQÔQÐQÝ+¨DÑ1Ô1ˆHð;Ø!* ¨5Ð1CÔ+DÑ!EÔ!E��øÝð ;ð ;ð ;Ø!&Ð'9Ô!:���ð;øøøð ×)Ò)ð*Ø',¨_Ô'=Ð'JÀð*ð *à!/ð*ð *ð *õ
 %Ô-Ø%ð *ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð —,’,‘.”.Ð Ð Ð Ð Ð Ð Ð Ð Ð à�TŠ\ˆ\àÔ$×(Ò(¨°$Ñ7Ô7Ð7Ø×)Ò)Ø1Ø!ð *ñ ô ð ð ð ð ð ð ð ð —,’,‘.”.Ð Ð Ð Ð Ð Ð Ð Ð Ð ð —,’,‘.”.Ð Ð Ð Ð Ð Ð Ð Ð Ð s–   Á A ÁAÁAÇG( Ç(&HÈHÍM' Í'&NÎNÐ5Q	 Ñ	
Q=Ñ Q8Ñ8Q=Ò(R* Ò*
S'Ò5SÓS'Ó
S!ÓS'Ó S!Ó!S'Ó&S'Ø"X4 Ø4Y	ÙY	Úupdater   ÚcontextúContextTypes.DEFAULT_TYPEc           	   ƒ   ón  K  — |j         }|r|j        sdS |j        }|                     d¦  «        rC|j        rt	          |j        j        ¦  «        nd}|r|                      |||¦  «        ƒ d{V —† dS |                     d¦  «        �r|                     dd¦  «        }t          |¦  «        dk    �rÖ|d         }	 t          |d         ¦  «        }n4# t          t          f$ r  |                     d¬	¦  «        ƒ d{V —† Y dS w xY wt	          t          |j        d
d¦  «        ¦  «        }	|                      |	¦  «        s|                     d¬	¦  «        ƒ d{V —† dS | j                             |d¦  «        }
|
s|                     d¬	¦  «        ƒ d{V —† dS dddddœ}t          |j        dd¦  «        }|                     |d¦  «        }|                     |¬	¦  «        ƒ d{V —† 	 |                     |› d|› �t(          j        d¬¦  «        ƒ d{V —† n# t,          $ r Y nw xY w	 ddlm}  ||
|¦  «        }t2                               d||
||¦  «         n2# t,          $ r%}t2                               d|¦  «         Y d}~nd}~ww xY wdS |                     d¦  «        sdS |                     dd¦  «        d         }t	          t          |j        d
d¦  «        ¦  «        }	|                      |	¦  «        s|                     d¬	¦  «        ƒ d{V —† dS |                     d|› d�¬	¦  «        ƒ d{V —† |d k    rd!nd"}	 |                     d#|› d$�t(          j        d¬¦  «        ƒ d{V —† n# t,          $ r Y nw xY w	 dd%lm}  |¦   «         }|d&z  }|                     d'¦  «        }|                     |¦  «         |                      |¦  «         t2                               d(|t          |j        d
d)¦  «        ¦  «         dS # t,          $ r&}t2                               d*|¦  «         Y d}~dS d}~ww xY w)+z%Handle inline keyboard button clicks.N)r-  rG  rJ  r4  rI  zea:rG  r    r  rO   zInvalid approval data.r<   Úidr“   u/   â›” You are not authorized to approve commands.z(This approval has already been resolved.u   âœ… Approved onceu   âœ… Approved for sessionu   âœ… Approved permanentlyu
   â�Œ Denied)ÚonceÚsessionÚalwaysÚdenyÚ
first_nameÚUserÚResolvedz by rd  r   )Úresolve_gateway_approvalzKTelegram button resolved %d approval(s) for session %s (choice=%s, user=%s)z;Failed to resolve gateway approval from Telegram button: %szupdate_prompt:u4   â›” You are not authorized to answer update prompts.zSent 'z' to the update process.ÚyÚYesÚNou   âš• Update prompt answered: *rš   r  z.update_responser$  z/Telegram update prompt answered '%s' by user %sr6  z1Failed to write update response from callback: %s)!Úcallback_queryrX  rS   r   r¢   r  rr  rP   rQ   r¨   rR  Ú
IndexErrorrg  rt   Ú	from_userr�   r�   rh  rŠ   rþ  r   r
  rò   Útools.approvalr  rè   rõ   r­   r-  r  Úwith_suffixÚ
write_textr:  )rŽ   rs  rt  ri  rX  r  ÚpartsÚchoicer  Ú	caller_idr  Ú	label_mapÚuser_displayr=  r  r  rq  rg  r  ÚhomeÚresponse_pathÚtmps                         r   r�  z&TelegramAdapter._handle_callback_queryD  s±  è è € ð Ô%ˆØð 	˜EœJð 	ØˆFØŒzˆð �?Š?Ð<Ñ=Ô=ð 	Ø49´MÐK•c˜%œ-Ô/Ñ0Ô0Ð0ÀtˆGØð OØ×8Ò8¸ÀÀgÑNÔNÐNÐNÐNÐNÐNÐNÐNØˆFð �?Š?˜5Ñ!Ô!ñ 5	Ø—J’J˜s AÑ&Ô&ˆEÝ�5‰zŒz˜QŠ‰Ø˜qœ�ðÝ"% e¨A¤h¡-¤-�K�KøÝ"¥JÐ/ð ð ð ØŸ,š,Ð,D˜,ÑEÔEÐEÐEÐEÐEÐEÐEÐEØ�F�Fðøøøõ
  ¥¨¬¸¸rÑ BÔ BÑCÔC�	Ø×8Ò8¸ÑCÔCð ØŸ,š,Ð,]˜,Ñ^Ô^Ð^Ð^Ð^Ð^Ð^Ð^Ð^Ø�Fà"Ô2×6Ò6°{ÀDÑIÔI�Ø"ð ØŸ,š,Ð,V˜,ÑWÔWÐWÐWÐWÐWÐWÐWÐWØ�Fð 0Ø9Ø8Ø(ð	ð �	õ  ' u¤¸ÀfÑMÔM�Ø!Ÿš f¨jÑ9Ô9�à—l’l¨�lÑ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.ðØ×1Ò1Ø %Ð9Ð9¨<Ð9Ð9Ý#,Ô#5Ø%)ð 2ñ ô ð ð ð ð ð ð ð ð øõ
 !ð ð ð Ø�DðøøøðeØGÐGÐGÐGÐGÐGØ4Ð4°[À&ÑIÔI�EÝ—K’KØeØ˜{¨F°Lñô ð ð øõ !ð eð eð eÝ—L’LÐ!^Ð`cÑdÔdÐdÐdÐdÐdÐdÐdøøøøðeøøøàˆFð �ŠÐ/Ñ0Ô0ð 	ØˆFØ—’˜C Ñ#Ô# AÔ&ˆÝ� ¤°°rÑ:Ô:Ñ;Ô;ˆ	Ø×0Ò0°Ñ;Ô;ð 	Ø—,’,Ð$Z�,Ñ[Ô[Ð[Ð[Ð[Ð[Ð[Ð[Ð[ØˆFØ�lŠlÐ I¨Ð IÐ IÐ IˆlÑJÔJÐJÐJÐJÐJÐJÐJÐJà 3š˜��¨Dˆð	Ø×)Ò)Ø=°UÐ=Ð=Ð=Ý$Ô-Ø!ð *ñ ô ð ð ð ð ð ð ð ð øõ
 ð 	ð 	ð 	ØˆDð	øøøð
	SØ8Ð8Ð8Ð8Ð8Ð8Ø"�?Ñ$Ô$ˆDØ Ð#5Ñ5ˆMØ×+Ò+¨FÑ3Ô3ˆCØ�NŠN˜6Ñ"Ô"Ð"Ø�KŠK˜Ñ&Ô&Ð&Ý�KŠKÐIØ¥¨¬¸¸yÑ IÔ IñKô Kð Kð Kð Køåð 	Sð 	Sð 	SÝ�LŠLÐLÈcÑRÔRÐRÐRÐRÐRÐRÐRÐRøøøøð	Søøøsg   Â=C Ã-DÄDÇ(-H È
H#È"H#È'0I É
JÉ"JÊJÍ ,M- Í-
M:Í9M:Í>BP Ð
P4ÐP/Ð/P4r=  r£  c                 óH   — |› d|› �}|                      d¦  «        r|dz  }|S )zßBuild an actionable file-not-found error for gateway MEDIA delivery.

        Paths like /workspace/... or /output/... often only exist inside the
        Docker sandbox, while the gateway process runs on the host.
        z file not found: )z/workspace/z/output/z	/outputs/z‘ (path may only exist inside the Docker sandbox. Bind-mount a host directory and emit the host-visible path in MEDIA: for gateway file delivery.))rS   )rŽ   r=  r£  r­   s       r   Ú_missing_media_path_errorz)TelegramAdapter._missing_media_path_error¬  sB   € ð Ð1Ð1¨4Ð1Ð1ˆØ�?Š?ÐCÑDÔDð 	Øð=ñˆEð
 ˆr   Ú
audio_pathÚcaptionc           
   ‹   ó(  •K  — | j         st          dd¬¦  «        S 	 t          j                             |¦  «        s%t          d|                      d|¦  «        ¬¦  «        S t          |d¦  «        5 }|                     d¦  «        rx|                      |¦  «        }| j          	                    t          |¦  «        ||r
|dd…         nd|rt          |¦  «        nd|                      |¦  «        ¬	¦  «        ƒ d{V —†}	nw|                      |¦  «        }
| j                              t          |¦  «        ||r
|dd…         nd|rt          |¦  «        nd|                      |
¦  «        ¬
¦  «        ƒ d{V —†}	ddd¦  «         n# 1 swxY w Y   t          dt          |	j        ¦  «        ¬¦  «        S # t          $ rW}t                                d| j        |d¬¦  «         t'          ¦   «          	                    ||||¦  «        ƒ d{V —†cY d}~S d}~ww xY w)z<Send audio as a native Telegram voice message or audio file.FrÎ  rÏ  ÚAudioÚrb)ú.oggz.opusNé   )r  Úvoicer”  rØ  r¡   )r  Úaudior”  rØ  r¡   TrÑ  zJ[%s] Failed to send Telegram voice/audio, falling back to base adapter: %sr  )rp   r'   ry   r£  r.  r’  r0  Úendswithr¤   Ú
send_voicer¨   rª   Ú
send_audior¢   rÒ  rò   rè   r­   rÇ   rl   )rŽ   r  r“  r”  rÇ  rž   r  Ú
audio_fileÚ_voice_threadrð  Ú_audio_threadr  r�   s               €r   r�  zTelegramAdapter.send_voice»  s²  øè è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCð!	TÝ”7—>’> *Ñ-Ô-ð lÝ!¨%°t×7UÒ7UÐV]Ð_iÑ7jÔ7jÐkÑkÔkÐkå�j $Ñ'Ô'ð ¨:à×&Ò&Ð'8Ñ9Ô9ð Ø$(×$<Ò$<¸XÑ$FÔ$F�MØ $¤	× 4Ò 4Ý # G¡¤Ø(Ø29Ð C ¨¨¨¤ ¸tØ=EÐ,O­C°©M¬M¨MÈ4Ø*.×*JÒ*JÈ=Ñ*YÔ*Yð !5ñ !ô !ð ð ð ð ð ð �C�Cð %)×$<Ò$<¸XÑ$FÔ$F�MØ $¤	× 4Ò 4Ý # G¡¤Ø(Ø29Ð C ¨¨¨¤ ¸tØ=EÐ,O­C°©M¬M¨MÈ4Ø*.×*JÒ*JÈ=Ñ*YÔ*Yð !5ñ !ô !ð ð ð ð ð ð �Cðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð õ*  dµs¸3¼>Ñ7JÔ7JÐKÑKÔKÐKøÝð 	Tð 	Tð 	TÝ�LŠLØ\Ø”	ØØð	 ñ ô ð õ ™œ×+Ò+¨G°ZÀÈ(ÑSÔSÐSÐSÐSÐSÐSÐSÐSÐSÐSÐSÐSÐSøøøøð	TøøøsJ   �AF0 Á!F0 Á1DFÅ6F0 ÆFÆF0 Æ	FÆ
%F0 Æ0
HÆ:AHÈHÈHÚ
image_pathc           
   ‹   ó  •K  — | j         st          dd¬¦  «        S 	 t          j                             |¦  «        s%t          d|                      d|¦  «        ¬¦  «        S |                      |¦  «        }t          |d¦  «        5 }| j                              t          |¦  «        ||r
|dd…         nd|rt          |¦  «        nd|  
                    |¦  «        ¬¦  «        ƒ d{V —†}	ddd¦  «         n# 1 swxY w Y   t          d	t          |	j        ¦  «        ¬
¦  «        S # t          $ rW}
t                               d| j        |
d	¬¦  «         t#          ¦   «                              ||||¦  «        ƒ d{V —†cY d}
~
S d}
~
ww xY w)z5Send a local image file natively as a Telegram photo.FrÎ  rÏ  ÚImager—  Nr™  ©r  Úphotor”  rØ  r¡   TrÑ  zJ[%s] Failed to send Telegram local image, falling back to base adapter: %sr  )rp   r'   ry   r£  r.  r’  r¤   r0  Ú
send_photor¨   rª   r¢   rÒ  rò   rè   r­   rÇ   rl   Úsend_image_file)rŽ   r  r¢  r”  rÇ  rž   r  Ú_threadÚ
image_filerð  r  r�   s              €r   r¨  zTelegramAdapter.send_image_fileë  s  øè è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCð	YÝ”7—>’> *Ñ-Ô-ð lÝ!¨%°t×7UÒ7UÐV]Ð_iÑ7jÔ7jÐkÑkÔkÐkà×.Ò.¨xÑ8Ô8ˆGÝ�j $Ñ'Ô'ð ¨:Ø œI×0Ò0Ý ™LœLØ$Ø.5Ð?˜G E T EœN˜N¸4Ø9AÐ(K­¨H©¬¨ÀtØ&*×&FÒ&FÀwÑ&OÔ&Oð 1ñ ô ð ð ð ð ð ð �ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð õ  dµs¸3¼>Ñ7JÔ7JÐKÑKÔKÐKøÝð 	Yð 	Yð 	YÝ�LŠLØ\Ø”	ØØð	 ñ ô ð õ ™œ×0Ò0°¸*ÀgÈxÑXÔXÐXÐXÐXÐXÐXÐXÐXÐXÐXÐXÐXÐXøøøøð	YøøøsJ   �AD# Á!%D# ÂA#C5Ã)D# Ã5C9Ã9D# Ã<C9Ã=%D# Ä#
FÄ-AE?Å9FÅ?FÚ	file_pathÚ	file_namec              ‹   óB  •K  — | j         st          dd¬¦  «        S 	 t          j                             |¦  «        s%t          d|                      d|¦  «        ¬¦  «        S |pt          j                             |¦  «        }|                      |¦  «        }	t          |d¦  «        5 }
| j          	                    t          |¦  «        |
||r
|dd…         nd|rt          |¦  «        nd|                      |	¦  «        ¬¦  «        ƒ d{V —†}ddd¦  «         n# 1 swxY w Y   t          d	t          |j        ¦  «        ¬
¦  «        S # t          $ rO}t          d| j        › d|› �¦  «         t#          ¦   «          	                    |||||¦  «        ƒ d{V —†cY d}~S d}~ww xY w)z<Send a document/file natively as a Telegram file attachment.FrÎ  rÏ  ÚFiler—  Nr™  )r  ÚdocumentÚfilenamer”  rØ  r¡   TrÑ  Ú[z] Failed to send document: )rp   r'   ry   r£  r.  r’  Úbasenamer¤   r0  Úsend_documentr¨   rª   r¢   rÒ  rò   ÚprintrÇ   rl   )rŽ   r  r«  r”  r¬  rÇ  rž   r  Údisplay_namer©  r?  rð  r  r�   s                €r   r³  zTelegramAdapter.send_document  s  øè è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCð	aÝ”7—>’> )Ñ,Ô,ð jÝ!¨%°t×7UÒ7UÐV\Ð^gÑ7hÔ7hÐiÑiÔiÐià$ÐC­¬×(8Ò(8¸Ñ(CÔ(CˆLØ×.Ò.¨xÑ8Ô8ˆGå�i Ñ&Ô&ð ¨!Ø œI×3Ò3Ý ™LœLØØ)Ø.5Ð?˜G E T EœN˜N¸4Ø9AÐ(K­¨H©¬¨ÀtØ&*×&FÒ&FÀwÑ&OÔ&Oð 4ñ ô ð ð ð ð ð ð �ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð õ  dµs¸3¼>Ñ7JÔ7JÐKÑKÔKÐKøÝð 	að 	að 	aÝÐ?�d”iÐ?Ð?¸AÐ?Ð?Ñ@Ô@Ð@Ý™œ×.Ò.¨w¸	À7ÈIÐW_Ñ`Ô`Ð`Ð`Ð`Ð`Ð`Ð`Ð`Ð`Ð`Ð`Ð`Ð`øøøøð	aøøøsK   �AE Á!AE Â'A$DÄE ÄDÄE ÄDÄ%E Å
FÅAFÆFÆFÚ
video_pathc           
   ‹   óü  •K  — | j         st          dd¬¦  «        S 	 t          j                             |¦  «        s%t          d|                      d|¦  «        ¬¦  «        S |                      |¦  «        }t          |d¦  «        5 }| j                              t          |¦  «        ||r
|dd…         nd|rt          |¦  «        nd|  
                    |¦  «        ¬¦  «        ƒ d{V —†}	ddd¦  «         n# 1 swxY w Y   t          d	t          |	j        ¦  «        ¬
¦  «        S # t          $ rN}
t          d| j        › d|
› �¦  «         t!          ¦   «                              ||||¦  «        ƒ d{V —†cY d}
~
S d}
~
ww xY w)z2Send a video natively as a Telegram video message.FrÎ  rÏ  ÚVideor—  Nr™  )r  Úvideor”  rØ  r¡   TrÑ  r±  z] Failed to send video: )rp   r'   ry   r£  r.  r’  r¤   r0  Ú
send_videor¨   rª   r¢   rÒ  rò   r´  rÇ   rl   )rŽ   r  r¶  r”  rÇ  rž   r  r©  r?  rð  r  r�   s              €r   rº  zTelegramAdapter.send_video2  sý  øè è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCð	TÝ”7—>’> *Ñ-Ô-ð lÝ!¨%°t×7UÒ7UÐV]Ð_iÑ7jÔ7jÐkÑkÔkÐkà×.Ò.¨xÑ8Ô8ˆGÝ�j $Ñ'Ô'ð ¨1Ø œI×0Ò0Ý ™LœLØØ.5Ð?˜G E T EœN˜N¸4Ø9AÐ(K­¨H©¬¨ÀtØ&*×&FÒ&FÀwÑ&OÔ&Oð 1ñ ô ð ð ð ð ð ð �ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð õ  dµs¸3¼>Ñ7JÔ7JÐKÑKÔKÐKøÝð 	Tð 	Tð 	TÝÐ<�d”iÐ<Ð<¸Ð<Ð<Ñ=Ô=Ð=Ý™œ×+Ò+¨G°ZÀÈ(ÑSÔSÐSÐSÐSÐSÐSÐSÐSÐSÐSÐSÐSÐSøøøøð	TøøøsJ   �AD# Á!%D# ÂA#C5Ã)D# Ã5C9Ã9D# Ã<C9Ã=%D# Ä#
E;Ä-AE6Å0E;Å6E;Ú	image_urlc           
   ƒ   óp  •K  — | j         st          dd¬¦  «        S ddlm}  ||¦  «        sLt                               d| j        ¦  «         t          ¦   «                              |||||¬¦  «        ƒ d{V —†S 	 |  	                    |¦  «        }| j          
                    t          |¦  «        ||r
|dd	…         nd|rt          |¦  «        nd|                      |¦  «        ¬
¦  «        ƒ d{V —†}t          dt          |j        ¦  «        ¬¦  «        S # t          $ �r–}	t                               d| j        |	d¬¦  «         	 ddl}
|
                     d¬¦  «        4 ƒd{V —†}|                     |¦  «        ƒ d{V —†}|                     ¦   «          |j        }ddd¦  «        ƒd{V —† n# 1 ƒd{V —†swxY w Y   | j          
                    t          |¦  «        ||r
|dd	…         nd|rt          |¦  «        nd|                      |¦  «        ¬
¦  «        ƒ d{V —†}t          dt          |j        ¦  «        ¬¦  «        cY d}	~	S # t          $ r\}t                               d| j        |d¬¦  «         t          ¦   «                              ||||¦  «        ƒ d{V —†cY d}~cY d}	~	S d}~ww xY wd}	~	ww xY w)zÎSend an image natively as a Telegram photo.
        
        Tries URL-based send first (fast, works for <5MB images).
        Falls back to downloading and uploading as file (supports up to 10MB).
        FrÎ  rÏ  r   )Úis_safe_urlz/[%s] Blocked unsafe image URL (SSRF protection))rž   Nr™  r¥  TrÑ  z8[%s] URL-based send_photo failed, trying file upload: %sr  g      >@)Útimeoutz+[%s] File upload send_photo also failed: %s)rp   r'   Útools.url_safetyr½  rè   rì   rÇ   rl   Ú
send_imager¤   r§  r¨   rª   r¢   rÒ  rò   ÚhttpxÚAsyncClientrŠ   Úraise_for_statusrÌ  r­   )rŽ   r  r»  r”  rÇ  rž   r½  Ú_photo_threadrð  r  rÁ  ÚclientÚrespÚ
image_dataÚe2r�   s                  €r   rÀ  zTelegramAdapter.send_imageQ  sñ  øè è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCà0Ð0Ð0Ð0Ð0Ð0Øˆ{˜9Ñ%Ô%ð 	fÝ�NŠNÐLÈdÌiÑXÔXÐXÝ™œ×+Ò+¨G°YÀÈÐ\dÐ+ÑeÔeÐeÐeÐeÐeÐeÐeÐeð*	Wà ×4Ò4°XÑ>Ô>ˆMØœ	×,Ò,Ý˜G™œØØ*1Ð;˜   œ˜°tØ5=Ð$G¥C¨¡M¤M MÀ4Ø"&×"BÒ"BÀ=Ñ"QÔ"Qð -ñ ô ð ð ð ð ð ð ˆCõ  dµs¸3¼>Ñ7JÔ7JÐKÑKÔKÐKøÝð 	Wñ 	Wð 	WÝ�NŠNØJØ”	ØØð	 ñ ô ð ðWØ���Ø ×,Ò,°TÐ,Ñ:Ô:ð .ð .ð .ð .ð .ð .ð .¸fØ!'§¢¨IÑ!6Ô!6Ð6Ð6Ð6Ð6Ð6Ð6�DØ×)Ò)Ñ+Ô+Ð+Ø!%¤�Jð.ð .ð .ñ .ô .ð .ð .ð .ð .ð .ð .ð .ð .ð .ð .ð .ð .ð .ð .ð .ð .ð .ð .øøøð .ð .ð .ð .ð
 !œI×0Ò0Ý ™LœLØ$Ø.5Ð?˜G E T EœN˜N¸4Ø9AÐ(K­¨H©¬¨ÀtØ&*×&FÒ&FÀ}Ñ&UÔ&Uð 1ñ ô ð ð ð ð ð ð �õ "¨$½3¸s¼~Ñ;NÔ;NÐOÑOÔOÐOÐOÐOÐOÐOÐOøÝð Wð Wð WÝ—’ØAØ”IØØ!ð	 ñ ô ð õ #™WœW×/Ò/°¸ÀGÈXÑVÔVÐVÐVÐVÐVÐVÐVÐVÐVÐVÐVÐVÐVÐVÐVÐVÐVÐVøøøøðWøøøøøøøð/	Wøøøsu   Á:BD ÄJ5Ä#J0Å IÅ#7F,ÆIÆ,
F6	Æ6IÆ9F6	Æ:BIÉJ5É
J-ÉAJ(ÊJ-ÊJ0Ê"J5Ê(J-Ê-J0Ê0J5Úanimation_urlc           	   ƒ   ó  K  — | j         st          dd¬¦  «        S 	 |                      |¦  «        }| j                              t	          |¦  «        ||r
|dd…         nd|rt	          |¦  «        nd|                      |¦  «        ¬¦  «        ƒ d{V —†}t          dt          |j        ¦  «        ¬¦  «        S # t          $ rK}t           
                    d	| j        |d¬
¦  «         |                      ||||¦  «        ƒ d{V —†cY d}~S d}~ww xY w)zJSend an animated GIF natively as a Telegram animation (auto-plays inline).FrÎ  rÏ  Nr™  )r  Ú	animationr”  rØ  r¡   TrÑ  zA[%s] Failed to send Telegram animation, falling back to photo: %sr  )rp   r'   r¤   Úsend_animationr¨   rª   r¢   rÒ  rò   rè   r­   rÇ   rÀ  )	rŽ   r  rÉ  r”  rÇ  rž   Ú_anim_threadrð  r  s	            r   rÌ  zTelegramAdapter.send_animation’  sb  è è € ð Œyð 	DÝ e°?ÐCÑCÔCÐCð	TØ×3Ò3°HÑ=Ô=ˆLØœ	×0Ò0Ý˜G™œØ'Ø*1Ð;˜   œ˜°tØ5=Ð$G¥C¨¡M¤M MÀ4Ø"&×"BÒ"BÀ<Ñ"PÔ"Pð 1ñ ô ð ð ð ð ð ð ˆCõ  dµs¸3¼>Ñ7JÔ7JÐKÑKÔKÐKøÝð 	Tð 	Tð 	TÝ�LŠLØSØ”	ØØð	 ñ ô ð ð Ÿš¨°-ÀÈ(ÑSÔSÐSÐSÐSÐSÐSÐSÐSÐSÐSÐSÐSÐSøøøøð	Tøøøs   œBB6 Â6
DÃ A DÄ DÄDc              ƒ   ó  K  — | j         rú	 |                      |¦  «        }|                      |¦  «        }	 | j                              t	          |¦  «        d|¬¦  «        ƒ d{V —† dS # t
          $ rT}|�F|                      |¦  «        r1| j                              t	          |¦  «        dd¬¦  «        ƒ d{V —† n‚ Y d}~dS d}~ww xY w# t
          $ r.}t                               d| j	        |d¬¦  «         Y d}~dS d}~ww xY wdS )zSend typing indicator.Útyping)r  Úactionr¡   Nz1[%s] Failed to send Telegram typing indicator: %sTr  )
rp   r¤   r¬   Úsend_chat_actionr¨   rò   r°   rè   ÚdebugrÇ   )rŽ   r  rž   Ú_typing_threadr¡   r  s         r   Úsend_typingzTelegramAdapter.send_typing²  s¸  è è € àŒ9ð 	ðØ!%×!9Ò!9¸(Ñ!CÔ!C�Ø$(×$FÒ$FÀ~Ñ$VÔ$VÐ!ðØœ)×4Ò4Ý # G¡¤Ø'Ø*;ð 5ñ ô ð ð ð ð ð ð ð ð ð øõ
 !ð ð ð Ø(Ð4¸×9XÒ9XÐYZÑ9[Ô9[Ð4Ø"œi×8Ò8Ý$'¨¡L¤LØ#+Ø.2ð 9ñ ô ð ð ð ð ð ð ð ð ð ðð ð ð ð ð øøøøðøøøøõ ð ð ð å—’ØGØ”IØØ!ð	 ñ ô ð ð ð ð ð ð ð øøøøðøøøð'	ð 	s;   ‹*C	 ¶0A( Á(
CÁ2A	CÂ;C	 ÃCÃC	 Ã	
DÃ#C<Ã<Dc              ƒ   ó@  K  — | j         sdddœS 	 | j                              t          |¦  «        ¦  «        ƒ d{V —†}d}|j        t          j        k    rd}n8|j        t          j        k    rd}|j        rd}n|j        t          j        k    rd}|j	        p|j
        pt          |¦  «        ||j        t          |dd	¦  «        d
œS # t          $ rN}t                               d| j        ||d¬¦  «         t          |¦  «        dt          |¦  «        dœcY d}~S d}~ww xY w)z&Get information about a Telegram chat.ÚUnknownÚdm)rÇ   ÚtypeNÚgroupÚforumÚchannelÚis_forumF)rÇ   rØ  ÚusernamerÜ  z0[%s] Failed to get Telegram chat info for %s: %sTr  )rÇ   rØ  r­   )rp   Úget_chatr¨   rØ  r   ÚGROUPÚ
SUPERGROUPrÜ  ÚCHANNELÚtitleÚ	full_namer¢   rÝ  rt   rò   rè   r­   rÇ   )rŽ   r  ÚchatÚ	chat_typer  s        r   Úget_chat_infozTelegramAdapter.get_chat_infoÐ  sc  è è € àŒyð 	5Ø%¨tÐ4Ð4Ð4ð	IØœ×+Ò+­C°©L¬LÑ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9ˆDàˆIØŒy�HœNÒ*Ð*Ø#�	�	Ø”�hÔ1Ò1Ð1Ø#�	Ø”=ð (Ø '�IøØ”�hÔ.Ò.Ð.Ø%�	ð œ
ÐD d¤nÐD½¸G¹¼Ø!Ø œMÝ# D¨*°eÑ<Ô<ð	ð ð øõ ð 	Ið 	Ið 	IÝ�LŠLØBØ”	ØØØð ñ ô ð õ   ™LœL°$ÅÀQÁÄÐHÐHÐHÐHÐHÐHÐHÐHøøøøð	Iøøøs   �B4C Ã
DÃADÄDÄDc                 ó@  ‡‡‡— |s|S i ŠdgŠdt           dt           fˆˆfd„Š|}t          |¦  «        }ˆfd„}t          j        d||¦  «        }t          j        dˆfd„|¦  «        }ˆfd	„}t          j        d
||¦  «        }ˆfd„}t          j        d||t          j        ¬¦  «        }t          j        dˆfd„|¦  «        }t          j        dˆfd„|¦  «        }t          j        dˆfd„|¦  «        }t          j        dˆfd„|¦  «        }ˆfd„}t          j        d||t          j        ¬¦  «        }t          |¦  «        }t          t          ‰                     ¦   «         ¦  «        ¦  «        D ]}| 	                    |‰|         ¦  «        }Œt          j
        d|¦  «        }g }	t          |¦  «        D ]R\  }
}|
dz  dk    r|	                     |¦  «         Œ$|fd„}|	                     t          j        d||¦  «        ¦  «         ŒSd                     |	¦  «        }|S )af  
        Convert standard markdown to Telegram MarkdownV2 format.

        Protected regions (code blocks, inline code) are extracted first so
        their contents are never modified.  Standard markdown constructs
        (headers, bold, italic, links) are translated to MarkdownV2 syntax,
        and all remaining special characters are escaped.
        r   rÔ   r4   c                 óJ   •— d‰d         › d�}‰dxx         dz  cc<   | ‰|<   |S )z@Stash *value* behind a placeholder token that survives escaping.z PHr   ú rO   r   )rÔ   rÉ   ÚcounterÚplaceholderss     €€r   Ú_phz+TelegramAdapter.format_message.<locals>._ph  s;   ø€ à+˜7 1œ:Ð+Ð+Ð+ˆCØ�AˆJˆJŒJ˜!‰OˆJˆJ‰JØ %ˆL˜ÑØˆJr   c                 ó,  •— |                       d¦  «        }d|dd …         v r|                     d¦  «        dz   nd}|d |…         }||d …         }|d d…         }|                     dd¦  «                             dd	¦  «        } ‰||z   d
z   ¦  «        S )Nr   rM   r  rO   éýÿÿÿú\ú\\ú`z\`rN   )rÙ  Úindexr:  )ÚmÚrawÚopen_endÚopeningÚbody_and_closeÚbodyrì  s         €r   Ú_protect_fencedz7TelegramAdapter.format_message.<locals>._protect_fenced  sŸ   ø€ Ø—'’'˜!‘*”*ˆCà.2°c¸!¸"¸"´g¨o¨o�s—y’y ‘”¨Ñ*Ð*À1ˆHØ˜)˜8˜)”nˆGØ    œ^ˆNØ! # 2 #Ô&ˆDØ—<’<  fÑ-Ô-×5Ò5°c¸5ÑAÔAˆDØ�3�w ‘~¨Ñ-Ñ.Ô.Ð.r   z(```(?:[^\n]*\n)?[\s\S]*?```)z	(`[^`]+`)c                 óh   •—  ‰|                       d¦  «                             dd¦  «        ¦  «        S )Nr   rï  rð  )rÙ  r:  ©ró  rì  s    €r   ú<lambda>z0TelegramAdapter.format_message.<locals>.<lambda>&  s+   ø€ �c�c˜!Ÿ'š' !™*œ*×,Ò,¨T°6Ñ:Ô:Ñ;Ô;€ r   c                 óæ   •— t          |                      d¦  «        ¦  «        }|                      d¦  «                             dd¦  «                             dd¦  «        } ‰d|› d|› d�¦  «        S )	NrO   r    rï  rð  r  z\)r±  ú]()r=   rÙ  r:  )ró  ÚdisplayÚurlrì  s      €r   Ú_convert_linkz5TelegramAdapter.format_message.<locals>._convert_link,  sm   ø€ Ý" 1§7¢7¨1¡:¤:Ñ.Ô.ˆGØ—'’'˜!‘*”*×$Ò$ T¨6Ñ2Ô2×:Ò:¸3ÀÑFÔFˆCØ�3Ð,˜7Ð,Ð, cÐ,Ð,Ð,Ñ-Ô-Ð-r   z-\[([^\]]+)\]\(([^()]*(?:\([^()]*\)[^()]*)*)\)c                 ó¶   •— |                       d¦  «                             ¦   «         }t          j        dd|¦  «        } ‰dt	          |¦  «        › d�¦  «        S )NrO   ú\*\*(.+?)\*\*r?   rš   )rÙ  rG   rA   r;   r=   )ró  Úinnerrì  s     €r   Ú_convert_headerz7TelegramAdapter.format_message.<locals>._convert_header4  sV   ø€ Ø—G’G˜A‘J”J×$Ò$Ñ&Ô&ˆEå”FÐ+¨U°EÑ:Ô:ˆEØ�3Ð1�<¨Ñ.Ô.Ð1Ð1Ð1Ñ2Ô2Ð2r   z^#{1,6}\s+(.+)$)Úflagsr  c                 ób   •—  ‰dt          |                      d¦  «        ¦  «        › d�¦  «        S )Nrš   rO   ©r=   rÙ  rû  s    €r   rü  z0TelegramAdapter.format_message.<locals>.<lambda>A  ó/   ø€ �c�cÐ9�l¨1¯7ª7°1©:¬:Ñ6Ô6Ð9Ð9Ð9Ñ:Ô:€ r   z\*([^*\n]+)\*c                 ób   •—  ‰dt          |                      d¦  «        ¦  «        › d�¦  «        S )NÚ_rO   r  rû  s    €r   rü  z0TelegramAdapter.format_message.<locals>.<lambda>J  r	  r   z	~~(.+?)~~c                 ób   •—  ‰dt          |                      d¦  «        ¦  «        › d�¦  «        S )NÚ~rO   r  rû  s    €r   rü  z0TelegramAdapter.format_message.<locals>.<lambda>Q  r	  r   z\|\|(.+?)\|\|c                 ób   •—  ‰dt          |                      d¦  «        ¦  «        › d�¦  «        S )Nú||rO   r  rû  s    €r   rü  z0TelegramAdapter.format_message.<locals>.<lambda>X  s/   ø€ �c�cÐ;�|¨A¯GªG°A©J¬JÑ7Ô7Ð;Ð;Ð;Ñ<Ô<€ r   c           	      ó2  •— |                       d¦  «        }|                       d¦  «        }|                     d¦  «        r;|                     d¦  «        r& ‰|› dt          |d d…         ¦  «        › d�¦  «        S  ‰|› dt          |¦  «        › �¦  «        S )NrO   r    z**r  Ú éþÿÿÿ)rÙ  rS   rœ  r=   )ró  r'  rÌ  rì  s      €r   Ú_convert_blockquotez;TelegramAdapter.format_message.<locals>._convert_blockquote_  s§   ø€ Ø—W’W˜Q‘Z”ZˆFØ—g’g˜a‘j”jˆGð × Ò  Ñ&Ô&ð G¨7×+;Ò+;¸DÑ+AÔ+Að GØ�s˜fÐEÐE¥|°G¸C¸R¸C´LÑ'AÔ'AÐEÐEÐEÑFÔFÐFØ�3˜&Ð:Ð:¥<°Ñ#8Ô#8Ð:Ð:Ñ;Ô;Ð;r   z^((?:\*\*)?>{1,3}) (.+)$z(```[\s\S]*?```|`[^`]+`)r    rO   c                 óÒ  — |                       ¦   «         }|                      d¦  «        }|dk    r||dz
           dk    r|S |dk    r|dk    r||dz
           dk    r|S |dk    r€|d |…         }d|v sd|v rnd}t          |dz
  t          |d	z
  d
¦  «        d
¦  «        D ]F}||         dk    r'|dz  }|dk     r|dk    r||dz
           dk    r|c S  nŒ5||         dk    r|dz  }ŒGd|z   S )Nr   rO   rï  ú(Ú]r  z](httprþ  iÐ  rD  )r   rÙ  rž  rL  )ró  Ú_segÚsÚchÚbeforeÚdepthr^   s          r   Ú	_esc_barez1TelegramAdapter.format_message.<locals>._esc_bare‚  s1  € ØŸš™	œ	�AØŸš ™œ�Bà˜1’u�u  a¨!¡e¤°Ò!4Ð!4Ø!˜	à˜S’y�y Q¨¢U U¨t°A¸±E¬{¸cÒ/AÐ/AØ!˜	à˜S’y�yØ!% b q b¤˜Ø# vÐ-Ð-°¸°°à$%˜EÝ%*¨1¨q©5µ#°a¸$±hÀÑ2CÔ2CÀRÑ%HÔ%Hð /ð / Ø#'¨¤7¨c¢> >Ø$)¨Q¡J EØ',¨q¢y yØ+,¨qª5¨5°T¸!¸a¹%´[ÀCÒ5GÐ5GØ35¨I¨I¨IØ(-¨ð (1ð &*¨!¤W°¢^ ^Ø$)¨Q¡J EøØ "™9Ð$r   z[(){}]r“   )r¢   r_   rA   r;   Ú	MULTILINEr=   Úreversedr¾  Úkeysr:  rP   rå  rT   rX   )rŽ   rÌ  r8   rù  r  r  r  rÉ   Ú_code_splitÚ_safe_partsÚ_idxr  r  rì  rê  rë  s                @@@r   rá  zTelegramAdapter.format_messageò  s  øøø€ ð ð 	ØˆNàˆØ�#ˆð	•sð 	�sð 	ð 	ð 	ð 	ð 	ð 	ð 	ð ˆõ % TÑ*Ô*ˆð	/ð 	/ð 	/ð 	/ð 	/õ ŒvØ,ØØñ
ô 
ˆõ ŒvØØ;Ð;Ð;Ð;Øñ
ô 
ˆð	.ð 	.ð 	.ð 	.ð 	.õ
 ŒvÐFÈÐW[Ñ\Ô\ˆð	3ð 	3ð 	3ð 	3ð 	3õ ŒvØ °½R¼\ð
ñ 
ô 
ˆõ
 ŒvØØ:Ð:Ð:Ð:Øñ
ô 
ˆõ ŒvØØ:Ð:Ð:Ð:Øñ
ô 
ˆõ ŒvØØ:Ð:Ð:Ð:Øñ
ô 
ˆõ ŒvØØ<Ð<Ð<Ð<Øñ
ô 
ˆð	<ð 	<ð 	<ð 	<ð 	<õ ŒvØ'ØØÝ”,ð	
ñ 
ô 
ˆõ ˜DÑ!Ô!ˆõ �D ×!2Ò!2Ñ!4Ô!4Ñ5Ô5Ñ6Ô6ð 	8ð 	8ˆCØ—<’<  \°#Ô%6Ñ7Ô7ˆDˆDõ
 ”hÐ:¸DÑAÔAˆØˆÝ# KÑ0Ô0ð 	Gð 	G‰JˆD�$Ø�a‰x˜1Š}ˆ}à×"Ò" 4Ñ(Ô(Ð(Ð(ð '+ð %ð %ð %ð %ð2 ×"Ò"¥2¤6¨)°YÀÑ#EÔ#EÑFÔFÐFÐFØ�wŠw�{Ñ#Ô#ˆàˆr   c                 ó
  — | j         j                             d¦  «        }|�:t          |t          ¦  «        r|                     ¦   «         dv S t          |¦  «        S t          j        dd¦  «                             ¦   «         dv S )zBReturn whether group chats should require an explicit bot trigger.Úrequire_mentionNrÌ   ÚTELEGRAM_REQUIRE_MENTIONrÐ   )	rc   r‰   rŠ   r¶   r¢   r¯   rH   ry   rz   r·   s     r   Ú_telegram_require_mentionz)TelegramAdapter._telegram_require_mention¢  s   € à”[Ô&×*Ò*Ð+<Ñ=Ô=ˆ
ØÐ!Ý˜*¥cÑ*Ô*ð HØ!×'Ò'Ñ)Ô)Ð-GÐGÐGÝ˜
Ñ#Ô#Ð#ÝŒyÐ3°WÑ=Ô=×CÒCÑEÔEÐIcÐcÐcr   c                 ó  — | j         j                             d¦  «        }|€t          j        dd¦  «        }t          |t          ¦  «        rd„ |D ¦   «         S d„ t          |¦  «                             d¦  «        D ¦   «         S )NÚfree_response_chatsÚTELEGRAM_FREE_RESPONSE_CHATSr“   c                 ó’   — h | ]D}t          |¦  «                             ¦   «         ¯#t          |¦  «                             ¦   «         ’ŒES r   )r¢   rG   ©r–   Úparts     r   r˜   z@TelegramAdapter._telegram_free_response_chats.<locals>.<setcomp>°  s=   € ÐKÐKÐK¨$½¸T¹¼¿ºÑ9JÔ9JÐK•C˜‘I”I—O’OÑ%Ô%ÐKÐKÐKr   c                 ó^   — h | ]*}|                      ¦   «         ¯|                      ¦   «         ’Œ+S r   r•   r+  s     r   r˜   z@TelegramAdapter._telegram_free_response_chats.<locals>.<setcomp>±  s-   € ÐMÐMÐM ÀÇ
Â
ÁÄÐM�—
’
‘”ÐMÐMÐMr   r™   )	rc   r‰   rŠ   ry   rz   r¶   r¾  r¢   rP   )rŽ   rô  s     r   Ú_telegram_free_response_chatsz-TelegramAdapter._telegram_free_response_chats«  s   € ØŒkÔ×#Ò#Ð$9Ñ:Ô:ˆØˆ;Ý”)Ð:¸BÑ?Ô?ˆCÝ�c�4Ñ Ô ð 	LØKÐK°#ÐKÑKÔKÐKØMÐM­¨S©¬¯ª¸Ñ)<Ô)<ÐMÑMÔMÐMr   c                 ó
  — | j         j                             d¦  «        }|€t          j        dd¦  «        }t          |t          ¦  «        r|}n"t          |¦  «                             d¦  «        }t          ¦   «         }|D ]�}t          |¦  «         
                    ¦   «         }|sŒ&	 |                     t          |¦  «        ¦  «         ŒJ# t          t          f$ r$ t                               d| j        |¦  «         Y Œ~w xY w|S )NÚignored_threadsÚTELEGRAM_IGNORED_THREADSr“   r™   z,[%s] Ignoring invalid Telegram thread id: %r)rc   r‰   rŠ   ry   rz   r¶   r¾  r¢   rP   ÚsetrG   rù   r¨   rQ  rR  rè   rì   rÇ   )rŽ   rô  r¿  ÚignoredrÔ   r8   s         r   Ú_telegram_ignored_threadsz)TelegramAdapter._telegram_ignored_threads³  s  € ØŒkÔ×#Ò#Ð$5Ñ6Ô6ˆØˆ;Ý”)Ð6¸Ñ;Ô;ˆCå�c�4Ñ Ô ð 	)ØˆFˆFå˜‘X”X—^’^ CÑ(Ô(ˆFå™EœEˆØð 	að 	aˆEÝ�u‘:”:×#Ò#Ñ%Ô%ˆDØð ØðaØ—’�C ™IœIÑ&Ô&Ð&Ð&øÝ�zÐ*ð að að aÝ—’ÐMÈtÌyÐZ_Ñ`Ô`Ð`Ð`Ð`ðaøøøàˆs   Â("CÃ2D Ã?D c                 óØ  — | j         j                             d¦  «        }|€�t          j        dd¦  «                             ¦   «         }|rg	 t          j        |¦  «        }nO# t          $ rB d„ | 	                    ¦   «         D ¦   «         }|sd„ | 
                    d¦  «        D ¦   «         }Y nw xY w|}|€g S t          |t          ¦  «        r|g}t          |t          ¦  «        s5t                               d| j        t#          |¦  «        j        ¦  «         g S g }|D ]�}t          |t          ¦  «        r|                     ¦   «         sŒ,	 |                     t)          j        |t(          j        ¦  «        ¦  «         Œ`# t(          j        $ r,}t                               d	| j        ||¦  «         Y d}~Œ–d}~ww xY w|r.t                               d
| j        t3          |¦  «        ¦  «         |S )z=Compile optional regex wake-word patterns for group triggers.Úmention_patternsNÚTELEGRAM_MENTION_PATTERNSr“   c                 ó^   — g | ]*}|                      ¦   «         ¯|                      ¦   «         ‘Œ+S r   r•   r+  s     r   r‚  z=TelegramAdapter._compile_mention_patterns.<locals>.<listcomp>Ñ  s-   € ÐXÐXÐX¨tÈ4Ï:Ê:É<Ì<ÐX˜dŸjšj™lœlÐXÐXÐXr   c                 ó^   — g | ]*}|                      ¦   «         ¯|                      ¦   «         ‘Œ+S r   r•   r+  s     r   r‚  z=TelegramAdapter._compile_mention_patterns.<locals>.<listcomp>Ó  s-   € Ð!ZÐ!ZÐ!Z°4ÈTÏZÊZÉ\Ì\Ð!Z $§*¢*¡,¤,Ð!ZÐ!ZÐ!Zr   r™   z?[%s] telegram mention_patterns must be a list or string; got %sz,[%s] Invalid Telegram mention pattern %r: %sz*[%s] Loaded %d Telegram mention pattern(s))rc   r‰   rŠ   ry   rz   rG   ÚjsonÚloadsrò   Ú
splitlinesrP   r¶   r¢   r¾  rè   rì   rÇ   rØ  r   rT   rA   ÚcompileÚ
IGNORECASEr­   rõ   rQ   )rŽ   Úpatternsrô  ÚloadedÚcompiledÚpatternrq  s          r   rr   z)TelegramAdapter._compile_mention_patternsÈ  s  € à”;Ô$×(Ò(Ð);Ñ<Ô<ˆØÐÝ”)Ð7¸Ñ<Ô<×BÒBÑDÔDˆCØð "ð[Ý!œZ¨™_œ_�F�FøÝ ð [ð [ð [ØXÐX°s·~²~Ñ7GÔ7GÐXÑXÔX�FØ!ð [Ø!ZÐ!Z¸3¿9º9ÀS¹>¼>Ð!ZÑ!ZÔ!Z˜øøð[øøøð "�àÐØˆIÝ�h¥Ñ$Ô$ð 	"Ø �zˆHÝ˜(¥DÑ)Ô)ð 	Ý�NŠNØQØ”	Ý�X‘”Ô'ñô ð ð
 ˆIà%'ˆØð 	hð 	hˆGÝ˜g¥sÑ+Ô+ð °7·=²=±?´?ð ØðhØ—’¥¤
¨7µB´MÑ BÔ BÑCÔCÐCÐCøÝ”8ð hð hð hÝ—’ÐMÈtÌyÐZaÐcfÑgÔgÐgÐgÐgÐgÐgÐgøøøøðhøøøàð 	`Ý�KŠKÐDÀdÄiÕQTÐU]ÑQ^ÔQ^Ñ_Ô_Ð_Øˆs+   ÁA! Á!A	B-Â,B-Å	2E<Å<F7Æ"F2Æ2F7r   c                 óÆ   — t          |dd ¦  «        }|sdS t          t          |dd¦  «        ¦  «                             d¦  «        d                              ¦   «         }|dv S )Nrä  FrØ  r“   ú.rD  )rÙ  Ú
supergroup)rt   r¢   rP   r¯   )rŽ   r   rä  rå  s       r   Ú_is_group_chatzTelegramAdapter._is_group_chatî  sd   € Ý�w ¨Ñ-Ô-ˆØð 	Ø�5Ý�  f¨bÑ1Ô1Ñ2Ô2×8Ò8¸Ñ=Ô=¸bÔA×GÒGÑIÔIˆ	ØÐ3Ð3Ð3r   c                 óÒ   — | j         rt          |dd ¦  «        sdS t          |j        dd ¦  «        }t          |o(t          |dd ¦  «        t          | j         dd ¦  «        k    ¦  «        S )NÚreply_to_messageFr…  rw  )rp   rt   rH  rH   )rŽ   r   Ú
reply_users      r   Ú_is_reply_to_botz TelegramAdapter._is_reply_to_botõ  sm   € ØŒyð 	¥¨Ð1CÀTÑ JÔ Jð 	Ø�5Ý˜WÔ5°{ÀDÑIÔIˆ
Ý�JÐd¥7¨:°t¸TÑ#BÔ#BÅgÈdÌiÐY]Ð_cÑFdÔFdÒ#dÑeÔeÐer   c           	      ó  ‡— | j         sdS t          | j         dd ¦  «        pd                     d¦  «                             ¦   «         }t          | j         dd ¦  «        }|rd|› �nd }ˆfd„} |¦   «         D �]\  }}|D �]	}t	          t          |dd¦  «        ¦  «                             d¦  «        d	                              ¦   «         }	|	d
k    r…|rƒt          t          |dd	¦  «        ¦  «        }
t          t          |dd¦  «        ¦  «        }|
dk     s|dk    rŒ�||
|
|z   …                              ¦   «                              ¦   «         |k    r  dS Œ×|	dk    r,t          |dd ¦  «        }|rt          |dd ¦  «        |k    r  dS �Œ�ŒdS )NFrÝ  r“   ú@rw  c               3   ó¬   •K  — t          ‰ dd ¦  «        pdt          ‰ dd ¦  «        pg fV — t          ‰ dd ¦  «        pdt          ‰ dd ¦  «        pg fV — d S )Nr8   r“   Úentitiesr”  Úcaption_entities)rt   )r   s   €r   Ú_iter_sourcesz<TelegramAdapter._message_mentions_bot.<locals>._iter_sources	  sx   øè è € Ý˜' 6¨4Ñ0Ô0Ð6°B½ÀÈÐUYÑ8ZÔ8ZÐ8`Ð^`Ð`Ð`Ð`Ð`Ý˜' 9¨dÑ3Ô3Ð9°r½7À7ÐL^Ð`dÑ;eÔ;eÐ;kÐikÐkÐkÐkÐkÐkÐkr   rØ  rD  rD  ÚmentionÚoffsetÚlengthr   TÚtext_mentionÚuser)rp   rt   rR   r¯   r¢   rP   r¨   rG   )rŽ   r   Úbot_usernameÚbot_idÚexpectedrP  Úsource_textrN  ÚentityÚentity_typerR  rS  rU  s    `           r   Ú_message_mentions_botz%TelegramAdapter._message_mentions_botû  sÖ  ø€ ØŒyð 	Ø�5å ¤	¨:°tÑ<Ô<ÐBÀ×JÒJÈ3ÑOÔO×UÒUÑWÔWˆÝ˜œ D¨$Ñ/Ô/ˆØ)5Ð?Ð%�|Ð%Ð%Ð%¸4ˆð	lð 	lð 	lð 	lð 	lð &3 ]¡_¤_ð 	$ñ 	$Ñ!ˆK˜Ø"ð $ñ $�Ý!¥'¨&°&¸"Ñ"=Ô"=Ñ>Ô>×DÒDÀSÑIÔIÈ"ÔM×SÒSÑUÔU�Ø )Ò+Ð+°Ð+Ý ¥¨°¸2Ñ!>Ô!>Ñ?Ô?�FÝ ¥¨°¸1Ñ!=Ô!=Ñ>Ô>�FØ ’z�z V¨q¢[ [Ø Ø" 6¨&°6©/Ð#9Ô:×@Ò@ÑBÔB×HÒHÑJÔJÈhÒVÐVØ#˜t˜t˜tð Wà  NÒ2Ð2Ý" 6¨6°4Ñ8Ô8�DØð $¥¨¨d°DÑ 9Ô 9¸VÒ CÐ CØ#˜t˜t˜tùñ$ð ˆur   c                 ó®   — | j         sdS t          |dd ¦  «        t          |dd ¦  «        fD ](}|sŒ| j         D ]}|                     |¦  «        r  dS ŒŒ)dS )NFr8   r”  T)rs   rt   Úsearch)rŽ   r   Ú	candidaterB  s       r   Ú!_message_matches_mention_patternsz1TelegramAdapter._message_matches_mention_patterns	  sŠ   € ØÔ%ð 	Ø�5Ý! '¨6°4Ñ8Ô8½'À'È9ÐVZÑ:[Ô:[Ð\ð 	 ð 	 ˆIØð ØØÔ1ð  ð  �Ø—>’> )Ñ,Ô,ð  Ø˜4˜4˜4ð ð ð ˆur   r8   c                 óà   — |r| j         rt          | j         dd ¦  «        s|S t          j        | j         j        ¦  «        }t          j        d|› d�d|¦  «                             ¦   «         }|p|S )NrÝ  z(?i)@z\b[,:\-]*\s*r“   )rp   rt   rA   r  rÝ  r;   rG   )rŽ   r8   rÝ  rB   s       r   Ú_clean_bot_trigger_textz'TelegramAdapter._clean_bot_trigger_text(	  sv   € Øð 	˜4œ9ð 	­G°D´I¸zÈ4Ñ,PÔ,Pð 	ØˆKÝ”9˜TœYÔ/Ñ0Ô0ˆÝ”&Ð8 (Ð8Ð8Ð8¸"¸dÑCÔC×IÒIÑKÔKˆØˆ˜$Ðr   ©Ú
is_commandrd  c          	      óL  — |                       |¦  «        sdS t          |dd¦  «        }|�_	 t          |¦  «        |                      ¦   «         v rdS n8# t          t
          f$ r$ t                               d| j        |¦  «         Y nw xY wt          t          t          |dd¦  «        dd¦  «        ¦  «        |  
                    ¦   «         v rdS |                      ¦   «         sdS |                      |¦  «        rdS |                      |¦  «        rdS |                      |¦  «        S )	u+  Apply Telegram group trigger rules.

        DMs remain unrestricted. Group/supergroup messages are accepted when:
        - the chat is explicitly allowlisted in ``free_response_chats``
        - ``require_mention`` is disabled
        - the message replies to the bot
        - the bot is @mentioned
        - the text/caption matches a configured regex wake-word pattern

        When ``require_mention`` is enabled, slash commands are not given
        special treatment â€” they must pass the same mention/reply checks
        as any other group message.  Users can still trigger commands via
        the Telegram bot menu (``/command@botname``) or by explicitly
        mentioning the bot (``@botname /command``), both of which are
        recognised as mentions by :meth:`_message_mentions_bot`.
        Tr¡   NFz8[%s] Ignoring non-numeric Telegram message_thread_id: %rrä  rw  r“   )rF  rt   r¨   r4  rQ  rR  rè   rì   rÇ   r¢   r.  r&  rJ  r\  r`  )rŽ   r   rd  r    s       r   Ú_should_process_messagez'TelegramAdapter._should_process_message/	  sJ  € ð" ×"Ò" 7Ñ+Ô+ð 	Ø�4Ý˜GÐ%8¸$Ñ?Ô?ˆ	ØÐ ðqÝ�y‘>”> T×%CÒ%CÑ%EÔ%EÐEÐEØ ˜5ð Føå�zÐ*ð qð qð qÝ—’ÐYÐ[_Ô[dÐfoÑpÔpÐpÐpÐpðqøøøå�w•w˜w¨°Ñ5Ô5°t¸RÑ@Ô@ÑAÔAÀT×EgÒEgÑEiÔEiÐiÐiØ�4Ø×-Ò-Ñ/Ô/ð 	Ø�4Ø× Ò  Ñ)Ô)ð 	Ø�4Ø×%Ò% gÑ.Ô.ð 	Ø�4Ø×5Ò5°gÑ>Ô>Ð>s   ¬#A Á2BÂBc              ƒ   ó,  K  — |j         r|j         j        sdS |                      |j         ¦  «        sdS |                      |j         t          j        |j        ¬¦  «        }|                      |j        ¦  «        |_        |                      |¦  «         dS )zýHandle incoming text messages.

        Telegram clients split long messages into multiple updates.  Buffer
        rapid successive text messages from the same user/chat and aggregate
        them into a single MessageEvent before dispatching.
        N©Ú	update_id)	r   r8   rf  Ú_build_message_eventr%   r�  ri  rb  Ú_enqueue_text_event©rŽ   rs  rt  Úevents       r   r‘  z$TelegramAdapter._handle_text_messageS	  s”   è è € ð Œ~ð 	 V¤^Ô%8ð 	ØˆFØ×+Ò+¨F¬NÑ;Ô;ð 	ØˆFà×)Ò)¨&¬.½+Ô:JÐV\ÔVfÐ)ÑgÔgˆØ×1Ò1°%´*Ñ=Ô=ˆŒ
Ø× Ò  Ñ'Ô'Ð'Ð'Ð'r   c              ƒ   óþ   K  — |j         r|j         j        sdS |                      |j         d¬¦  «        sdS |                      |j         t          j        |j        ¬¦  «        }|                      |¦  «        ƒ d{V —† dS )z!Handle incoming command messages.NTrc  rh  )r   r8   rf  rj  r%   r�  ri  Úhandle_messagerl  s       r   r’  zTelegramAdapter._handle_commandc	  s’   è è € àŒ~ð 	 V¤^Ô%8ð 	ØˆFØ×+Ò+¨F¬NÀtÐ+ÑLÔLð 	ØˆFà×)Ò)¨&¬.½+Ô:MÐY_ÔYiÐ)ÑjÔjˆØ×!Ò! %Ñ(Ô(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ð(r   c              ƒ   óR  K  — |j         sdS |                      |j         ¦  «        sdS |j         }t          |dd¦  «        }|rt          |dd¦  «        nt          |dd¦  «        }|sdS t          |dd¦  «        }t          |dd¦  «        }|�|€dS dg}|rVt          |dd¦  «        }	t          |dd¦  «        }
|	r|                     d	|	› �¦  «         |
r|                     d
|
› �¦  «         |                     d|› �¦  «         |                     d|› �¦  «         |                     d|› d|› �¦  «         |                     d¦  «         |                      |t
          j        |j        ¬¦  «        }d                     |¦  «        |_	        |  
                    |¦  «        ƒ d{V —† dS )z,Handle incoming location/venue pin messages.NÚvenueÚlocationÚlatitudeÚ	longitudez![The user shared a location pin.]râ  ÚaddresszVenue: z	Address: z
latitude: zlongitude: z5Map: https://www.google.com/maps/search/?api=1&query=r™   zSAsk what they'd like to find nearby (restaurants, cafes, etc.) and any preferences.rh  rM   )r   rf  rt   rT   rj  r%   r“  ri  rX   r8   ro  )rŽ   rs  rt  rð  rq  rr  ÚlatÚlonr‰  râ  ru  rm  s               r   r”  z(TelegramAdapter._handle_location_messagem	  sõ  è è € àŒ~ð 	ØˆFØ×+Ò+¨F¬NÑ;Ô;ð 	ØˆFàŒnˆÝ˜˜W dÑ+Ô+ˆØ7<Ð`•7˜5 *¨dÑ3Ô3Ð3Å'È#ÈzÐ[_ÑB`ÔB`ˆàð 	ØˆFå�h 
¨DÑ1Ô1ˆÝ�h ¨TÑ2Ô2ˆØˆ;˜#˜+ØˆFð 5Ð5ˆØð 	4Ý˜E 7¨DÑ1Ô1ˆEÝ˜e Y°Ñ5Ô5ˆGØð 0Ø—’Ð. uÐ.Ð.Ñ/Ô/Ð/Øð 4Ø—’Ð2¨Ð2Ð2Ñ3Ô3Ð3Ø�ŠÐ' #Ð'Ð'Ñ(Ô(Ð(Ø�ŠÐ( 3Ð(Ð(Ñ)Ô)Ð)Ø�ŠÐXÈSÐXÐXÐSVÐXÐXÑYÔYÐYØ�ŠÐjÑkÔkÐkà×)Ò)¨#­{Ô/CÈvÔO_Ð)Ñ`Ô`ˆØ—Y’Y˜uÑ%Ô%ˆŒ
Ø×!Ò! %Ñ(Ô(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ð(r   rm  c                 ó¬   — ddl m}  ||j        | j        j                             dd¦  «        | j        j                             dd¦  «        ¬¦  «        S )z-Session-scoped key for text message batching.r   ©Úbuild_session_keyÚgroup_sessions_per_userTÚthread_sessions_per_userF©r{  r|  )Úgateway.sessionrz  Úsourcerc   r‰   rŠ   )rŽ   rm  rz  s      r   Ú_text_batch_keyzTelegramAdapter._text_batch_key–	  sg   € à5Ð5Ð5Ð5Ð5Ð5Ø Ð ØŒLØ$(¤KÔ$5×$9Ò$9Ð:SÐUYÑ$ZÔ$ZØ%)¤[Ô%6×%:Ò%:Ð;UÐW\Ñ%]Ô%]ð
ñ 
ô 
ð 	
r   c                 óŒ  — |                       |¦  «        }| j                             |¦  «        }t          |j        pd¦  «        }|€||_        || j        |<   nw|j        r$|j        r|j        › d|j        › �n|j        |_        ||_        |j        r>|j                             |j        ¦  «         |j                             |j        ¦  «         | j	                             |¦  «        }|r(| 
                    ¦   «         s|                     ¦   «          t          j        |                      |¦  «        ¦  «        | j	        |<   dS )a2  Buffer a text event and reset the flush timer.

        When Telegram splits a long user message into multiple updates,
        they arrive within a few hundred milliseconds.  This method
        concatenates them and waits for a short quiet period before
        dispatching the combined message.
        r“   NrM   )r€  r‚   rŠ   rQ   r8   Ú_last_chunk_lenÚ
media_urlsrW   Úmedia_typesrƒ   rx  rÀ  rí   ry  Ú_flush_text_batch)rŽ   rm  rÉ   ÚexistingÚ	chunk_lenÚ
prior_tasks         r   rk  z#TelegramAdapter._enqueue_text_eventŸ	  sP  € ð ×"Ò" 5Ñ)Ô)ˆØÔ-×1Ò1°#Ñ6Ô6ˆÝ˜œ
Ð( bÑ)Ô)ˆ	ØÐØ$-ˆEÔ!Ø.3ˆDÔ& sÑ+Ð+ð Œzð bØDLÄMÐ a 8¤=Ð @Ð @°E´JÐ @Ð @Ð @ÐW\ÔWa�”Ø'0ˆHÔ$àÔð ?ØÔ#×*Ò*¨5Ô+;Ñ<Ô<Ð<ØÔ$×+Ò+¨EÔ,=Ñ>Ô>Ð>ð Ô3×7Ò7¸Ñ<Ô<ˆ
Øð 	 ˜jŸošoÑ/Ô/ð 	 Ø×ÒÑÔÐÝ.5Ô.AØ×"Ò" 3Ñ'Ô'ñ/
ô /
ˆÔ& sÑ+Ð+Ð+r   c              ƒ   ó,  K  — t          j        ¦   «         }	 | j                             |¦  «        }|rt	          |dd¦  «        nd}|| j        k    r| j        }n| j        }t          j        |¦  «        ƒ d{V —† | j         	                    |d¦  «        }|s<	 | j
                             |¦  «        |u r| j
         	                    |d¦  «         dS dS t                               d|t          |j        pd¦  «        ¦  «         |                      |¦  «        ƒ d{V —† | j
                             |¦  «        |u r| j
         	                    |d¦  «         dS dS # | j
                             |¦  «        |u r| j
         	                    |d¦  «         w w xY w)zØWait for the quiet period then dispatch the aggregated text.

        Uses a longer delay when the latest chunk is near Telegram's 4096-char
        split point, since a continuation chunk is almost certain.
        r‚  r   Nz,[Telegram] Flushing text batch %s (%d chars)r“   )rí   Úcurrent_taskr‚   rŠ   rt   Ú_SPLIT_THRESHOLDr�   r€   rî   rh  rƒ   rè   rõ   rQ   r8   ro  )rŽ   rÉ   rŠ  ÚpendingÚlast_lenr  rm  s          r   r…  z!TelegramAdapter._flush_text_batch¿	  sÖ  è è € õ Ô+Ñ-Ô-ˆð	>ð Ô0×4Ò4°SÑ9Ô9ˆGØAHÐO•w˜wÐ(9¸1Ñ=Ô=Ð=ÈaˆHØ˜4Ô0Ò0Ð0ØÔ<��àÔ6�Ý”- Ñ&Ô&Ð&Ð&Ð&Ð&Ð&Ð&Ð&ØÔ.×2Ò2°3¸Ñ=Ô=ˆEØð Øð Ô-×1Ò1°#Ñ6Ô6¸,ÐFÐFØÔ.×2Ò2°3¸Ñ=Ô=Ð=Ð=Ð=ð GÐFõ �KŠKØ>Ø•S˜œÐ) rÑ*Ô*ñô ð ð ×%Ò% eÑ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,àÔ-×1Ò1°#Ñ6Ô6¸,ÐFÐFØÔ.×2Ò2°3¸Ñ=Ô=Ð=Ð=Ð=ð GÐFøˆtÔ-×1Ò1°#Ñ6Ô6¸,ÐFÐFØÔ.×2Ò2°3¸Ñ=Ô=Ð=Ð=ð Gøøøs   —B E ÃAE Å:Frð  c                 óê   — ddl m}  ||j        | j        j                             dd¦  «        | j        j                             dd¦  «        ¬¦  «        }t          |dd	¦  «        }|r|› d
|› �S |› d�S )z1Return a batching key for Telegram photos/albums.r   ry  r{  Tr|  Fr}  Úmedia_group_idNz:album:z:photo-burst)r~  rz  r  rc   r‰   rŠ   rt   )rŽ   rm  rð  rz  r  r�  s         r   Ú_photo_batch_keyz TelegramAdapter._photo_batch_keyà	  s£   € à5Ð5Ð5Ð5Ð5Ð5Ø'Ð'ØŒLØ$(¤KÔ$5×$9Ò$9Ð:SÐUYÑ$ZÔ$ZØ%)¤[Ô%6×%:Ò%:Ð;UÐW\Ñ%]Ô%]ð
ñ 
ô 
ˆõ
 ! Ð&6¸Ñ=Ô=ˆØð 	;Ø!Ð:Ð:¨.Ð:Ð:Ð:ØÐ+Ð+Ð+Ð+r   Ú	batch_keyc              ƒ   ó   K  — t          j        ¦   «         }	 t          j        | j        ¦  «        ƒ d{V —† | j                             |d¦  «        }|s<	 | j                             |¦  «        |u r| j                             |d¦  «         dS dS t           	                    d|t          |j        ¦  «        ¦  «         |                      |¦  «        ƒ d{V —† | j                             |¦  «        |u r| j                             |d¦  «         dS dS # | j                             |¦  «        |u r| j                             |d¦  «         w w xY w)z;Send a buffered photo burst/album as a single MessageEvent.Nz3[Telegram] Flushing photo batch %s with %d image(s))rí   rŠ  rî   r{   r|   rh  r}   rŠ   rè   rõ   rQ   rƒ  ro  )rŽ   r‘  rŠ  rm  s       r   Ú_flush_photo_batchz"TelegramAdapter._flush_photo_batchí	  sy  è è € åÔ+Ñ-Ô-ˆð		EÝ”- Ô ?Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@Ð@ØÔ/×3Ò3°I¸tÑDÔDˆEØð Øð Ô.×2Ò2°9Ñ=Ô=ÀÐMÐMØÔ/×3Ò3°I¸tÑDÔDÐDÐDÐDð NÐMõ �KŠKÐMÈyÕZ]Ð^cÔ^nÑZoÔZoÑpÔpÐpØ×%Ò% eÑ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,àÔ.×2Ò2°9Ñ=Ô=ÀÐMÐMØÔ/×3Ò3°I¸tÑDÔDÐDÐDÐDð NÐMøˆtÔ.×2Ò2°9Ñ=Ô=ÀÐMÐMØÔ/×3Ò3°I¸tÑDÔDÐDÐDð Nøøøs   —<D ÂA	D Ä:Ec                 ó  — | j                              |¦  «        }|€|| j         |<   nj|j                             |j        ¦  «         |j                             |j        ¦  «         |j        r%|                      |j        |j        ¦  «        |_        | j                             |¦  «        }|r(|                     ¦   «         s| 	                    ¦   «          t          j        |                      |¦  «        ¦  «        | j        |<   dS )z;Merge photo events into a pending batch and schedule flush.N)r|   rŠ   rƒ  rW   r„  r8   Ú_merge_captionr}   rx  rÀ  rí   ry  r“  )rŽ   r‘  rm  r†  rˆ  s        r   Ú_enqueue_photo_eventz$TelegramAdapter._enqueue_photo_eventû	  sö   € àÔ.×2Ò2°9Ñ=Ô=ˆØÐØ5:ˆDÔ'¨	Ñ2Ð2àÔ×&Ò& uÔ'7Ñ8Ô8Ð8ØÔ ×'Ò'¨Ô(9Ñ:Ô:Ð:ØŒzð OØ $× 3Ò 3°H´MÀ5Ä:Ñ NÔ N�”àÔ4×8Ò8¸ÑCÔCˆ
Øð 	 ˜jŸošoÑ/Ô/ð 	 Ø×ÒÑÔÐå5<Ô5HÈ×I`ÒI`ÐajÑIkÔIkÑ5lÔ5lˆÔ'¨	Ñ2Ð2Ð2r   c              ƒ   ó$  K  — |j         sdS |                      |j         ¦  «        sdS |j         }|j        rt          j        }np|j        rt          j        }n\|j        rt          j        }nH|j	        rt          j
        }n4|j        rt          j        }n |j        rt          j        }nt          j        }|                      |||j        ¬¦  «        }|j        r|                      |j        ¦  «        |_        |j        r9|                      ||¦  «        ƒ d{V —† |                      |¦  «        ƒ d{V —† dS |j        �r~	 |j        d         }|                     ¦   «         ƒ d{V —†}|                     ¦   «         ƒ d{V —†}d}	|j        r5dD ]2}
|j                             ¦   «                              |
¦  «        r|
}	 nŒ3t7          t9          |¦  «        |	¬¦  «        }|g|_        d|	                     d¦  «        › �g|_        t@           !                    d	|¦  «         tE          |d
d¦  «        }|r*|  #                    tI          |¦  «        |¦  «        ƒ d{V —† n,|  %                    ||¦  «        }|  &                    ||¦  «         dS # tN          $ r'}t@           (                    d|d¬¦  «         Y d}~nd}~ww xY w|j        rº	 |j                             ¦   «         ƒ d{V —†}|                     ¦   «         ƒ d{V —†}tS          t9          |¦  «        d¬¦  «        }|g|_        dg|_        t@           !                    d|¦  «         �nï# tN          $ r(}t@           (                    d|d¬¦  «         Y d}~�nÂd}~ww xY w|j	        rº	 |j	                             ¦   «         ƒ d{V —†}|                     ¦   «         ƒ d{V —†}tS          t9          |¦  «        d¬¦  «        }|g|_        dg|_        t@           !                    d|¦  «         �n.# tN          $ r(}t@           (                    d|d¬¦  «         Y d}~�nd}~ww xY w|j        �r	 |j                             ¦   «         ƒ d{V —†}|                     ¦   «         ƒ d{V —†}d}	tE          |dd¦  «        r:tT          D ]2}
|j                             ¦   «                              |
¦  «        r|
}	 nŒ3tW          t9          |¦  «        |	¬¦  «        }|g|_        tU          j,        |	d¦  «        g|_        t@           !                    d|¦  «         �n# tN          $ r(}t@           (                    d|d¬¦  «         Y d}~�nßd}~ww xY w|j        �rÏ|j        }	 d}	|j-        pd}|r6t\          j/         0                    |¦  «        \  }}	|	                     ¦   «         }	|	s?|j1        r8d„ te          j3        ¦   «         D ¦   «         }| ,                    |j1        d¦  «        }	|	s?|j1        r8d„ tU          j3        ¦   «         D ¦   «         }| ,                    |j1        d¦  «        }	|	tT          v r¶|                     ¦   «         ƒ d{V —†}|                     ¦   «         ƒ d{V —†}tW          t9          |¦  «        |	¬¦  «        }|g|_        tT          |	         g|_        t          j        |_4        t@           !                    d|¦  «         |                      |¦  «        ƒ d{V —† dS |	td          vr|d 5                    tm          te          j7        ¦   «         ¦  «        ¦  «        }d |	pd!› d"|› �|_        t@           !                    d#|	pd!¦  «         |                      |¦  «        ƒ d{V —† dS d$}|j8        r|j8        |k    rDd%|_        t@           !                    d&|j8        ¦  «         |                      |¦  «        ƒ d{V —† dS |                     ¦   «         ƒ d{V —†}|                     ¦   «         ƒ d{V —†}t9          |¦  «        }ts          ||pd'|	› �¦  «        }td          |	         }|g|_        |g|_        t@           !                    d(|¦  «         d)}|	d*v r›tu          |¦  «        |k    rˆ	 | ;                    d+¦  «        }|pd'|	› �}ty          j=        d,d-|¦  «        }d.|› d/|› �}|j        r|› d0|j        › �|_        n||_        n,# t|          $ r t@           (                    d1d¬¦  «         Y nw xY wn4# tN          $ r'}t@           (                    d2|d¬¦  «         Y d}~nd}~ww xY wtE          |d
d¦  «        }|r+|  #                    tI          |¦  «        |¦  «        ƒ d{V —† dS |                      |¦  «        ƒ d{V —† dS )3zBHandle incoming media messages, downloading images to local cache.Nrh  rD  ú.jpg)z.pngú.webpz.gifz.jpegr˜  ©Úextzimage/rD  z"[Telegram] Cached user photo at %sr�  z$[Telegram] Failed to cache photo: %sTr  r˜  z	audio/oggz"[Telegram] Cached user voice at %sz$[Telegram] Failed to cache voice: %sz.mp3z	audio/mp3z"[Telegram] Cached user audio at %sz$[Telegram] Failed to cache audio: %sz.mp4r«  z	video/mp4z"[Telegram] Cached user video at %sz$[Telegram] Failed to cache video: %sr“   c                 ó   — i | ]\  }}||“Œ	S r   r   ©r–   Úkr´   s      r   ú
<dictcomp>z9TelegramAdapter._handle_media_message.<locals>.<dictcomp>…
  s   € Ð"UÐ"UÐ"U©D¨A¨q 1 aÐ"UÐ"UÐ"Ur   c                 ó   — i | ]\  }}||“Œ	S r   r   r�  s      r   rŸ  z9TelegramAdapter._handle_media_message.<locals>.<dictcomp>‰
  s   € Ð(XÐ(XÐ(X±$°!°Q¨¨AÐ(XÐ(XÐ(Xr   z+[Telegram] Cached user video document at %src  zUnsupported document type 'r6  z'. Supported types: z([Telegram] Unsupported document type: %si  @zLThe document is too large or its size could not be verified. Maximum: 20 MB.z'[Telegram] Document too large: %s bytesr¯  z%[Telegram] Cached user document at %si � )z.mdz.txtr)  z	[^\w.\- ]r  z[Content of z]:
z

zJ[Telegram] Could not decode text file as UTF-8, skipping content injectionz'[Telegram] Failed to cache document: %s)?r   rf  Ústickerr%   ÚSTICKERr¦  r•  r¹  r–  r›  r—  rš  r˜  r¯  ÚDOCUMENTrj  ri  r”  rb  r8   Ú_handle_stickerro  Úget_fileÚdownload_as_bytearrayr«  r¯   rœ  r(   Úbytesrƒ  rR   r„  rè   rõ   rt   Ú_queue_media_group_eventr¢   r�  r–  rò   rì   r)   r-   r*   rŠ   r¬  ry   r£  ÚsplitextÚ	mime_typer.   ÚitemsÚmessage_typerX   Úsortedr  Ú	file_sizer+   rQ   ÚdecoderA   r;   ÚUnicodeDecodeError)rŽ   rs  rt  rð  Úmsg_typerm  r¦  Úfile_objÚimage_bytesr›  r_  Úcached_pathr�  r‘  r  Úaudio_bytesÚvideo_bytesÚdocÚoriginal_filenamer  Úmime_to_extÚvideo_mime_to_extÚsupported_listÚMAX_DOC_BYTESÚ	doc_bytesÚ	raw_bytesrª  ÚMAX_TEXT_INJECT_BYTESÚtext_contentrµ  Ú	injections                                  r   rœ  z%TelegramAdapter._handle_media_message
  s…  è è € àŒ~ð 	ØˆFØ×+Ò+¨F¬NÑ;Ô;ð 	ØˆFàŒnˆð Œ;ð 	,Ý"Ô*ˆHˆHØŒYð 	,Ý"Ô(ˆHˆHØŒYð 		,Ý"Ô(ˆHˆHØŒYð 	,Ý"Ô(ˆHˆHØŒYð 	,Ý"Ô(ˆHˆHØŒ\ð 	,Ý"Ô+ˆHˆHå"Ô+ˆHà×)Ò)¨#¨xÀ6ÔCSÐ)ÑTÔTˆð Œ;ð 	CØ×5Ò5°c´kÑBÔBˆEŒJð Œ;ð 	Ø×&Ò& s¨EÑ2Ô2Ð2Ð2Ð2Ð2Ð2Ð2Ð2Ø×%Ò% eÑ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,ØˆFð Œ9ñ 	YðYàœ	 "œ�Ø!&§¢Ñ!1Ô!1Ð1Ð1Ð1Ð1Ð1Ð1�à$,×$BÒ$BÑ$DÔ$DÐDÐDÐDÐDÐDÐD�à�ØÔ%ð "Ø%Oð "ð "˜	Ø#Ô-×3Ò3Ñ5Ô5×>Ò>¸yÑIÔIð "Ø"+˜CØ!˜Eð"õ 5µU¸;Ñ5GÔ5GÈSÐQÑQÔQ�Ø$/ =�Ô Ø%?¨c¯jªj¸©o¬oÐ%?Ð%?Ð$A�Ô!Ý—’Ð@À+ÑNÔNÐNÝ!(¨Ð.>ÀÑ!EÔ!E�Ø!ð @Ø×7Ò7½¸NÑ8KÔ8KÈUÑSÔSÐSÐSÐSÐSÐSÐSÐSÐSà $× 5Ò 5°e¸SÑ AÔ A�IØ×-Ò-¨i¸Ñ?Ô?Ð?Ø�øåð Yð Yð YÝ—’ÐEÀqÐSW�ÑXÔXÐXÐXÐXÐXÐXÐXøøøøðYøøøð Œ9ð x	\ðYØ!$¤×!3Ò!3Ñ!5Ô!5Ð5Ð5Ð5Ð5Ð5Ð5�Ø$,×$BÒ$BÑ$DÔ$DÐDÐDÐDÐDÐDÐD�Ý4µU¸;Ñ5GÔ5GÈVÐTÑTÔT�Ø$/ =�Ô Ø%0 M�Ô!Ý—’Ð@À+ÑNÔNÐNÑNøÝð Yð Yð YÝ—’ÐEÀqÐSW�ÑXÔXÐXÐXÐXÐXÐXÑXøøøøðYøøøàŒYð n	\ðYØ!$¤×!3Ò!3Ñ!5Ô!5Ð5Ð5Ð5Ð5Ð5Ð5�Ø$,×$BÒ$BÑ$DÔ$DÐDÐDÐDÐDÐDÐD�Ý4µU¸;Ñ5GÔ5GÈVÐTÑTÔT�Ø$/ =�Ô Ø%0 M�Ô!Ý—’Ð@À+ÑNÔNÐNÑNøÝð Yð Yð YÝ—’ÐEÀqÐSW�ÑXÔXÐXÐXÐXÐXÐXÑXøøøøðYøøøð ŒYñ c	\ðYØ!$¤×!3Ò!3Ñ!5Ô!5Ð5Ð5Ð5Ð5Ð5Ð5�Ø$,×$BÒ$BÑ$DÔ$DÐDÐDÐDÐDÐDÐD�Ø�Ý˜8 [°$Ñ7Ô7ð "Ý%:ð "ð "˜	Ø#Ô-×3Ò3Ñ5Ô5×>Ò>¸yÑIÔIð "Ø"+˜CØ!˜Eð"õ 5µU¸;Ñ5GÔ5GÈSÐQÑQÔQ�Ø$/ =�Ô Ý%:Ô%>¸sÀKÑ%PÔ%PÐ$Q�Ô!Ý—’Ð@À+ÑNÔNÐNÑNøÝð Yð Yð YÝ—’ÐEÀqÐSW�ÑXÔXÐXÐXÐXÐXÐXÑXøøøøðYøøøð Œ\ñ Q	\Ø”,ˆCðO\à�Ø$'¤MÐ$7°RÐ!Ø$ð &ÝœW×-Ò-Ð.?Ñ@Ô@‘F�A�sØŸ)š)™+œ+�Cð ð =˜sœ}ð =Ø"UÐ"UÕ4LÔ4RÑ4TÔ4TÐ"UÑ"UÔ"U�KØ%Ÿ/š/¨#¬-¸Ñ<Ô<�Càð C˜sœ}ð CØ(XÐ(XÕ:OÔ:UÑ:WÔ:WÐ(XÑ(XÔ(XÐ%Ø+×/Ò/°´¸rÑBÔB�CàÕ/Ð/Ð/Ø%(§\¢\¡^¤^Ð3Ð3Ð3Ð3Ð3Ð3�HØ(0×(FÒ(FÑ(HÔ(HÐ"HÐ"HÐ"HÐ"HÐ"HÐ"H�KÝ"8½¸{Ñ9KÔ9KÐQTÐ"UÑ"UÔ"U�KØ(3 }�EÔ$Ý)>¸sÔ)CÐ(D�EÔ%Ý)4Ô):�EÔ&Ý—K’KÐ MÈ{Ñ[Ô[Ð[Ø×-Ò-¨eÑ4Ô4Ð4Ð4Ð4Ð4Ð4Ð4Ð4Ø�Fð Õ6Ð6Ð6Ø%)§Y¢Y­vÕ6NÔ6SÑ6UÔ6UÑ/VÔ/VÑ%WÔ%W�Nð=°cÐ6F¸Yð =ð =Ø,:ð=ð =ð ”Jõ —K’KÐ JÈCÐL\ÐS\Ñ]Ô]Ð]Ø×-Ò-¨eÑ4Ô4Ð4Ð4Ð4Ð4Ð4Ð4Ð4Ø�Fð !1�Ø”}ð ¨¬¸Ò(EÐ(Eð*ð ”Jõ —K’KÐ IÈ3Ì=ÑYÔYÐYØ×-Ò-¨eÑ4Ô4Ð4Ð4Ð4Ð4Ð4Ð4Ð4Ø�Fð "%§¢¡¤Ð/Ð/Ð/Ð/Ð/Ð/�Ø"*×"@Ò"@Ñ"BÔ"BÐBÐBÐBÐBÐBÐB�	Ý! )Ñ,Ô,�	Ý7¸	ÐCTÐChÐXhÐcfÐXhÐXhÑiÔi�Ý4°SÔ9�	Ø$/ =�Ô Ø%. K�Ô!Ý—’ÐCÀ[ÑQÔQÐQð )3Ð%Ø˜/Ð)Ð)­c°)©n¬nÐ@UÒ.UÐ.UðØ'0×'7Ò'7¸Ñ'@Ô'@˜Ø'8Ð'LÐ<LÀsÐ<LÐ<L˜Ý')¤v¨l¸CÀÑ'NÔ'N˜Ø$S°<Ð$SÐ$SÀ\Ð$SÐ$S˜	Ø œ:ð 3Ø,5Ð)GÐ)G¸5¼:Ð)GÐ)G˜EœJ˜Jà)2˜EœJøøÝ-ð ð ð ÝŸšØhØ%)ð 'ñ ô ð ð ð ðøøøøøõ ð \ð \ð \Ý—’ÐHÈ!ÐVZ�Ñ[Ô[Ð[Ð[Ð[Ð[Ð[Ð[øøøøð\øøøõ ! Ð&6¸Ñ=Ô=ˆØð 	Ø×/Ò/µ°NÑ0CÔ0CÀUÑKÔKÐKÐKÐKÐKÐKÐKÐKØˆFà×!Ò! %Ñ(Ô(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ð(s·   Ä?EJ Ê
J9ÊJ4Ê4J9ËBM Í
M:ÍM5Í5M:ÎBP	 Ð	
P;ÐP6Ð6P;ÑC"T+ Ô+
UÔ5UÕUÕ0Fd Û4Bd Ý9Ad ßB)d á;Ac ãd ã&c?ã<d ã>c?ã?d ä
d4äd/ä/d4r�  c              ƒ   óê  K  — | j                              |¦  «        }|€|| j         |<   nj|j                             |j        ¦  «         |j                             |j        ¦  «         |j        r%|                      |j        |j        ¦  «        |_        | j                             |¦  «        }|r|                     ¦   «          t          j
        |                      |¦  «        ¦  «        | j        |<   dS )a€  Buffer Telegram media-group items so albums arrive as one logical event.

        Telegram delivers albums as multiple updates with a shared media_group_id.
        If we forward each item immediately, the gateway thinks the second image is a
        new user message and interrupts the first. We debounce briefly and merge the
        attachments into a single MessageEvent.
        N)r~   rŠ   rƒ  rW   r„  r8   r•  r   rÀ  rí   ry  Ú_flush_media_group_event)rŽ   r�  rm  r†  rˆ  s        r   r¨  z(TelegramAdapter._queue_media_group_eventÓ
  sï   è è € ð Ô+×/Ò/°Ñ?Ô?ˆØÐØ7<ˆDÔ$ ^Ñ4Ð4àÔ×&Ò& uÔ'7Ñ8Ô8Ð8ØÔ ×'Ò'¨Ô(9Ñ:Ô:Ð:ØŒzð OØ $× 3Ò 3°H´MÀ5Ä:Ñ NÔ N�”àÔ,×0Ò0°Ñ@Ô@ˆ
Øð 	 Ø×ÒÑÔÐå29Ô2EØ×)Ò)¨.Ñ9Ô9ñ3
ô 3
ˆÔ Ñ/Ð/Ð/r   c              ƒ   ó”  K  — 	 t          j        | j        ¦  «        ƒ d {V —† | j                             |d ¦  «        }|�|                      |¦  «        ƒ d {V —† n1# t           j        $ r Y | j                             |d ¦  «         d S w xY w| j                             |d ¦  «         d S # | j                             |d ¦  «         w xY wr¦   )rí   rî   ÚMEDIA_GROUP_WAIT_SECONDSr~   rh  ro  ÚCancelledErrorr   )rŽ   r�  rm  s      r   rÃ  z(TelegramAdapter._flush_media_group_eventì
  sõ   è è € ð	>Ý”- Ô =Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>ØÔ,×0Ò0°ÀÑFÔFˆEØÐ Ø×)Ò)¨%Ñ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0Ð0øøÝÔ%ð 	ð 	ð 	ØàÔ#×'Ò'¨¸Ñ=Ô=Ð=Ð=Ð=ð	øøøð Ô#×'Ò'¨¸Ñ=Ô=Ð=Ð=Ð=øˆDÔ#×'Ò'¨¸Ñ=Ô=Ð=Ð=øøøs*   „AA ÁB* ÁB
Á+B* Â	B
Â
B* Â*Cr$   c              ƒ   ó(  K  — ddl m}m}m}m}m} |j        }|j        pd}	|j        pd}
|j	        s|j
        r ||	¦  «        |_        dS  ||j        ¦  «        }|rb ||d         |                     d|	¦  «        |                     d|
¦  «        ¦  «        |_        t                               d|j        ¦  «         dS 	 |                     ¦   «         ƒ d{V —†}|                     ¦   «         ƒ d{V —†}t%          t'          |¦  «        d	¬
¦  «        }t                               d|¦  «         ddlm}  |||¬¦  «        ƒ d{V —†}t-          j        |¦  «        }|                     d¦  «        r=|                     dd¦  «        } ||j        ||	|
¦  «          |||	|
¦  «        |_        dS  ||	rd|	› �nd|	|
¦  «        |_        dS # t0          $ rA}t                               d|d¬¦  «          ||	rd|	› �nd|	|
¦  «        |_        Y d}~dS d}~ww xY w)a  
        Describe a Telegram sticker via vision analysis, with caching.

        For static stickers (WEBP), we download, analyze with vision, and cache
        the description by file_unique_id. For animated/video stickers, we inject
        a placeholder noting the emoji.
        r   )Úget_cached_descriptionÚcache_sticker_descriptionÚbuild_sticker_injectionÚ build_animated_sticker_injectionÚSTICKER_VISION_PROMPTr“   Nr  ÚemojiÚset_namez [Telegram] Sticker cache hit: %sr™  rš  z"[Telegram] Analyzing sticker at %s)Úvision_analyze_tool)r»  Úuser_promptrÐ  Úanalysisz	a stickerza sticker with emoji z%[Telegram] Sticker analysis error: %sTr  )Úgateway.sticker_cacherÈ  rÉ  rÊ  rË  rÌ  r¡  rÍ  rÎ  Úis_animatedÚis_videor8   Úfile_unique_idrŠ   rè   rõ   r¥  r¦  r(   r§  Útools.vision_toolsrÏ  r:  r;  rò   rì   )rŽ   rð  rm  rÈ  rÉ  rÊ  rË  rÌ  r¡  rÍ  rÎ  Úcachedr²  r³  r´  rÏ  Úresult_jsonÚresultr  r  s                       r   r¤  zTelegramAdapter._handle_sticker÷
  sô  è è € ð	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð ”+ˆØ”Ð# ˆØÔ#Ð) rˆð Ôð 	 'Ô"2ð 	Ø9Ð9¸%Ñ@Ô@ˆEŒJØˆFð (Ð'¨Ô(>Ñ?Ô?ˆØð 	Ø0Ð0Ø�}Ô% v§z¢z°'¸5Ñ'AÔ'AÀ6Ç:Â:ÈjÐZbÑCcÔCcñô ˆEŒJõ �KŠKÐ:¸GÔ<RÑSÔSÐSØˆFð	Ø$×-Ò-Ñ/Ô/Ð/Ð/Ð/Ð/Ð/Ð/ˆHØ (× >Ò >Ñ @Ô @Ð@Ð@Ð@Ð@Ð@Ð@ˆKÝ0µ°{Ñ1CÔ1CÈÐQÑQÔQˆKÝ�KŠKÐ<¸kÑJÔJÐJà>Ð>Ð>Ð>Ð>Ð>Ø 3Ð 3Ø%Ø1ð!ñ !ô !ð ð ð ð ð ð ˆKõ ”Z Ñ,Ô,ˆFà�zŠz˜)Ñ$Ô$ð 	Ø$Ÿjšj¨°[ÑAÔA�Ø)Ð)¨'Ô*@À+ÈuÐV^Ñ_Ô_Ð_Ø4Ð4°[À%ÈÑRÔR�”
�
�
ð 5Ð4Ø7<ÐMÐ3¨EÐ3Ð3Ð3À+Ø˜8ñô �”
�
�
øõ ð 	ð 	ð 	Ý�NŠNÐBÀAÐPTˆNÑUÔUÐUØ0Ð0Ø38ÐIÐ/¨Ð/Ð/Ð/¸kØ�xñô ˆEŒJˆJˆJˆJˆJˆJˆJøøøøð	øøøs   Â?C*G Æ+G Ç
HÇ6HÈHc                 óf  — 	 ddl m}  |¦   «         dz  }|                     ¦   «         sdS ddl}t	          |d¦  «        5 }|                     |¦  «        pi }ddd¦  «         n# 1 swxY w Y   |                     di ¦  «                             di ¦  «                             di ¦  «                             d	g ¦  «        }|sdS || _        |D ]ª}|                     d
¦  «        }|sŒ|                     dg ¦  «        D ]y}	|	                     d¦  «        }
|	                     d¦  «        }|
rK|rI|› d|› �}|| j        vr9t          |
¦  «        | j        |<   t                               d| j        ||
¦  «         ŒzŒ«dS # t          $ r,}t                               d| j        |¦  «         Y d}~dS d}~ww xY w)zÒRe-read dm_topics from config.yaml and load any new thread_ids into cache.

        This allows topics created externally (e.g. by the agent via API) to be
        recognized without a gateway restart.
        r   r  r  Nr   r!  r"  r‰   rk   r  r#  r    rÇ   rG  z8[%s] Hot-loaded DM topic from config: %s -> thread_id=%sz/[%s] Failed to reload dm_topics from config: %s)r-  r  r.  r/  r0  r1  rŠ   r‹   rˆ   r¨   rè   rõ   rÇ   rò   rÒ  )rŽ   r  r=  r>  r?  rc   rk   rA  ÚcidrB  ÚtidrÇ   rI  r  s                 r   Ú_reload_dm_topics_from_configz-TelegramAdapter._reload_dm_topics_from_config8  sO  € ð%	ZØ8Ð8Ð8Ð8Ð8Ð8Ø)˜/Ñ+Ô+¨mÑ;ˆKØ×%Ò%Ñ'Ô'ð Ø�à Ð Ð Ð Ý�k 3Ñ'Ô'ð 2¨1ØŸš¨Ñ+Ô+Ð1¨r�ð2ð 2ð 2ñ 2ô 2ð 2ð 2ð 2ð 2ð 2ð 2øøøð 2ð 2ð 2ð 2ð —
’
˜;¨Ñ+Ô+ß’�Z Ñ$Ô$ß’�W˜bÑ!Ô!ß’�[ "Ñ%Ô%ð	 ð ð Ø�ð &/ˆDÔ"Ø'ð ð �
Ø —n’n YÑ/Ô/�Øð ØØ#Ÿš¨°"Ñ5Ô5ð 
ð 
�AØŸ%š% Ñ,Ô,�CØŸ5š5 ™=œ=�DØð ˜tð Ø'* O O¨T O O˜	Ø$¨D¬OÐ;Ð;Ý9<¸S¹¼˜DœO¨IÑ6Ý"ŸKšKØ ZØ $¤	¨9°cñô ð øð
ð	ð øõ ð 	Zð 	Zð 	ZÝ�LŠLÐJÈDÌIÐWXÑYÔYÐYÐYÐYÐYÐYÐYÐYøøøøð	ZøøøsG   ‚'E: «E: ¿A#ÁE: Á#A'Á'E: Á*A'Á+AE: ÃB4E: Å:
F0Æ!F+Æ+F0c                 óx  — |sdS t          |¦  «        }| j                             ¦   «         D ]¯\  }}||k    r¤|                     |› d�¦  «        rŒ|                     dd¦  «        d         }| j        D ]b}t          |                     d¦  «        ¦  «        |k    r:|                     dg ¦  «        D ]#}|                     d¦  «        |k    r|c c c S Œ$Œcd|ic S Œ°|                      ¦   «          | j                             ¦   «         D ]¯\  }}||k    r¤|                     |› d�¦  «        rŒ|                     dd¦  «        d         }| j        D ]b}t          |                     d¦  «        ¦  «        |k    r:|                     dg ¦  «        D ]#}|                     d¦  «        |k    r|c c c S Œ$Œcd|ic S Œ°dS )z²Look up DM topic config by chat_id and thread_id.

        Returns the topic config dict (name, skill, etc.) if this thread_id
        matches a known DM topic, or None.
        NrG  rO   r  r#  rÇ   )	r¨   rˆ   r«  rS   rP   r‹   r¢   rŠ   rÝ  )	rŽ   r  r    Úthread_id_intrÉ   Ú
cached_tidr  rA  rB  s	            r   Ú_get_dm_topic_infoz"TelegramAdapter._get_dm_topic_infoe  s  € ð ð 	Ø�4å˜I™œˆð  $œ×4Ò4Ñ6Ô6ð 		,ð 		,‰OˆC�Ø˜]Ò*Ð*¨s¯~ª~À¸m¸m¸mÑ/LÔ/LÐ*Ø ŸYšY s¨AÑ.Ô.¨qÔ1�
à"&Ô"8ð )ð )�JÝ˜:Ÿ>š>¨)Ñ4Ô4Ñ5Ô5¸Ò@Ð@Ø!+§¢°¸"Ñ!=Ô!=ð )ð )˜AØ Ÿušu V™}œ}°
Ò:Ð:Ø'(       ð  ;øà 
Ð+Ð+Ð+Ð+øð 	×*Ò*Ñ,Ô,Ð,ð  $œ×4Ò4Ñ6Ô6ð 	,ð 	,‰OˆC�Ø˜]Ò*Ð*¨s¯~ª~À¸m¸m¸mÑ/LÔ/LÐ*Ø ŸYšY s¨AÑ.Ô.¨qÔ1�
Ø"&Ô"8ð )ð )�JÝ˜:Ÿ>š>¨)Ñ4Ô4Ñ5Ô5¸Ò@Ð@Ø!+§¢°¸"Ñ!=Ô!=ð )ð )˜AØ Ÿušu V™}œ}°
Ò:Ð:Ø'(       ð  ;øà 
Ð+Ð+Ð+Ð+øàˆtr   c                 óœ   — |› d|› �}|| j         vr;t          |¦  «        | j         |<   t                               d| j        ||¦  «         dS dS )zLCache a thread_id -> topic_name mapping discovered from an incoming message.rG  z5[%s] Cached DM topic from message: %s -> thread_id=%sN)rˆ   r¨   rè   rõ   rÇ   )rŽ   r  r    r  rI  s        r   Ú_cache_dm_topic_from_messagez,TelegramAdapter._cache_dm_topic_from_messageŒ  sh   € àÐ-Ð- Ð-Ð-ˆ	Ø˜DœOÐ+Ð+Ý),¨Y©¬ˆDŒO˜IÑ&Ý�KŠKØGØ”	˜9 iñô ð ð ð ð ,Ð+r   r±  ri  c                 óº  — |j         }|j        }d}|j        t          j        t          j        fv rd}n|j        t          j        k    rd}|j        }|�t          |¦  «        nd}|dk    r|€t          |dd¦  «        r| j
        }d}	d}
|dk    r©|r§|                      t          |j        ¦  «        |¦  «        }|r*|                     d¦  «        }	|                     d¦  «        }
t          |d	¦  «        rB|j        r;|j        j        }|r-|                      t          |j        ¦  «        ||¦  «         |	s|}	n×|dk    rÑ|rÏ| j        j                             d
g ¦  «        }|D ]¬}t          |                     dd¦  «        ¦  «        t          |j        ¦  «        k    rq|                     dg ¦  «        D ]X}|                     d¦  «        }|�?t          |¦  «        |k    r,|                     d¦  «        }	|                     d¦  «        }
 nŒY nŒ­|                      t          |j        ¦  «        |j        pt          |d¦  «        r|j        nd||rt          |j        ¦  «        n|dk    rt          |j        ¦  «        nd|r|j        nt          |d¦  «        r|dk    r|j        nd||	¬¦  «        }d}d}|j        r3t          |j        j        ¦  «        }|j        j        p|j        j        pd}ddlm} t          |j        ¦  «        } || j        j        |p||r|nd¦  «        }t;          |j        pd|||t          |j        ¦  «        ||||
||j        ¬¦  «        S )aO  Build a MessageEvent from a Telegram message.

        ``update_id`` is the ``Update.update_id`` from PTB; passing it through
        lets ``/restart`` record the triggering offset so the new gateway
        process can advance past it (prevents ``/restart`` being re-delivered
        when PTB's graceful-shutdown ACK fails).
        r×  rÙ  rÛ  NrÜ  FrÇ   ÚskillÚforum_topic_createdÚgroup_topicsr  r“   r#  r    rã  )r  Ú	chat_namerå  r�   Ú	user_namer    Ú
chat_topicr   )Úresolve_channel_prompt)r8   r¬  r  Úraw_messagerÒ  Úplatform_update_idrØ  Úreply_to_textÚ
auto_skillÚchannel_promptÚ	timestamp)rä  r…  rØ  r   rß  rà  rá  r¡   r¢   rt   r§   rá  rw  rŠ   r  ræ  rÇ   rã  rc   r‰   Úbuild_sourcerâ  rã  rH  rÒ  r8   r”  Úgateway.platforms.baserë  r$   Údate)rŽ   r   r±  ri  rä  rU  rå  Úthread_id_rawÚthread_id_strrê  Útopic_skillÚ
topic_infoÚcreated_nameÚgroup_topics_configrA  r  rÜ  r  rî  rî  rë  Ú_chat_id_strÚ_channel_prompts                          r   rj  z$TelegramAdapter._build_message_event–  sÇ  € ð Œ|ˆØÔ ˆð ˆ	ØŒ9�œ­Ô)<Ð=Ð=Ð=ØˆIˆIØŒY�(Ô*Ò*Ð*Ø!ˆIð  Ô1ˆØ.;Ð.G�˜MÑ*Ô*Ð*ÈTˆØ˜ÒÐ MÐ$9½gÀdÈJÐX]Ñ>^Ô>^Ð$9Ø Ô9ˆMØˆ
Øˆà˜ÒÐ ÐØ×0Ò0µ°T´W±´¸}ÑMÔMˆJØð 6Ø'Ÿ^š^¨FÑ3Ô3�
Ø(Ÿnšn¨WÑ5Ô5�õ �wÐ 5Ñ6Ô6ð 2¸7Ô;Vð 2Ø&Ô:Ô?�Øð 2Ø×5Ò5µc¸$¼'±l´lÀMÐS_Ñ`Ô`Ð`Ø%ð 2Ø%1˜
øà˜'Ò!Ð! mÐ!à(,¬Ô(9×(=Ò(=¸nÈbÑ(QÔ(QÐØ1ð ð �
Ý�z—~’~ i°Ñ4Ô4Ñ5Ô5½¸T¼W¹¼ÒEÐEØ!+§¢°¸"Ñ!=Ô!=ð "ð "˜Ø#Ÿiši¨Ñ4Ô4˜Ø˜?­s°3©x¬x¸=Ò/HÐ/HØ).¯ª°6Ñ):Ô):˜JØ*/¯)ª)°GÑ*<Ô*<˜KØ!˜EøØ�Eð Fð ×"Ò"Ý˜œ‘L”LØ”jÐ\µw¸tÀ[Ñ7QÔ7QÐ%[ T¤^ ^ÐW[ØØ$(Ð[•C˜œ‘L”L�L¸yÈDÒ?PÐ?P­s°4´7©|¬|¨|ÐVZØ(,ð  A�d”n�nÅWÈTÐS^ÑE_ÔE_Ð3ÐdmÐquÒduÐdu°4´>°>Ð{Ø#Ø!ð #ñ 
ô 
ˆð ˆØˆØÔ#ð 	fÝ˜gÔ6ÔAÑBÔBˆKØ#Ô4Ô9Ðe¸WÔ=UÔ=]ÐeÐaeˆMð 	BÐAÐAÐAÐAÐAÝ˜4œ7‘|”|ˆØ0Ð0ØŒKÔØÐ)˜\Ø)Ð3ˆLˆL¨tñ
ô 
ˆõ Ø”Ð# Ø!ØØÝ˜7Ô-Ñ.Ô.Ø(Ø +Ø'Ø"Ø*Ø”lð
ñ 
ô 
ð 	
r   c                 óT   — t          j        dd¦  «                             ¦   «         dvS )z6Check if message reactions are enabled via config/env.ÚTELEGRAM_REACTIONSrÐ   )rÐ   rÑ   rÒ   )ry   rz   r¯   rÚ   s    r   Ú_reactions_enabledz"TelegramAdapter._reactions_enabledû  s'   € åŒyÐ-¨wÑ7Ô7×=Ò=Ñ?Ô?ÐG[Ð[Ð[r   rÍ  c              ƒ   ó  K  — | j         sdS 	 | j                              t          |¦  «        t          |¦  «        |¬¦  «        ƒ d{V —† dS # t          $ r-}t                               d| j        ||¦  «         Y d}~dS d}~ww xY w)z2Set a single emoji reaction on a Telegram message.F)r  rÒ  ÚreactionNTz)[%s] set_message_reaction failed (%s): %s)rp   Úset_message_reactionr¨   rò   rè   rÒ  rÇ   )rŽ   r  rÒ  rÍ  r  s        r   Ú_set_reactionzTelegramAdapter._set_reactionÿ  s¼   è è € àŒyð 	Ø�5ð		Ø”)×0Ò0Ý˜G™œÝ˜z™?œ?Øð 1ñ ô ð ð ð ð ð ð ð ð
 �4øÝð 	ð 	ð 	Ý�LŠLÐDÀdÄiÐQVÐXYÑZÔZÐZØ�5�5�5�5�5øøøøð	øøøs   �=A Á
BÁ"A>Á>Bc              ƒ   óÎ   K  — |                       ¦   «         sdS t          |j        dd¦  «        }t          |dd¦  «        }|r!|r!|                      ||d¦  «        ƒ d{V —† dS dS dS )z;Add an in-progress reaction when message processing begins.Nr  rÒ  u   ðŸ‘€)rÿ  rt   r  r  )rŽ   rm  r  rÒ  s       r   Úon_processing_startz#TelegramAdapter.on_processing_start  sœ   è è € à×&Ò&Ñ(Ô(ð 	ØˆFÝ˜%œ,¨	°4Ñ8Ô8ˆÝ˜U L°$Ñ7Ô7ˆ
Øð 	H�zð 	HØ×$Ò$ W¨j¸,ÑGÔGÐGÐGÐGÐGÐGÐGÐGÐGÐGð	Hð 	Hð 	Hð 	Hr   Úoutcomec              ƒ   ó  K  — |                       ¦   «         sdS t          |j        dd¦  «        }t          |dd¦  «        }|rC|rC|t          j        k    r5|                      |||t          j        k    rdnd¦  «        ƒ d{V —† dS dS dS dS )ué   Swap the in-progress reaction for a final success/failure reaction.

        Unlike Discord (additive reactions), Telegram's set_message_reaction
        replaces all existing reactions in one call â€” no remove step needed.
        Nr  rÒ  u   ðŸ‘�u   ðŸ‘Ž)rÿ  rt   r  r&   Ú	CANCELLEDr  ÚSUCCESS)rŽ   rm  r  r  rÒ  s        r   Úon_processing_completez&TelegramAdapter.on_processing_complete  s×   è è € ð ×&Ò&Ñ(Ô(ð 	ØˆFÝ˜%œ,¨	°4Ñ8Ô8ˆÝ˜U L°$Ñ7Ô7ˆ
Øð 	�zð 	 gÕ1BÔ1LÒ&LÐ&LØ×$Ò$ØØØ 'Õ+<Ô+DÒ DÐ D��È,ñô ð ð ð ð ð ð ð ð ð ð	ð 	ð 	ð 	Ð&LÐ&Lr   )F)NN)r4   N)r“   r“   )r  Nr¦   )rs  r   rt  ru  r4   N)NNN)NNNN)fr   r   r   Ú__doc__rã  r‹  rÅ  r§   r"   rm   Ústaticmethodr¢   rH   r�   Úclassmethodr   r   r   r¤   r¨   rª   r¬   rò   r°   r¾  r¹   r¼   rÈ   rv   rÛ   r÷   r  r  rE  rL  r»  rÆ  rË  r'   rù  r  r  r  r@  rK  ÚtuplerW  rr  r�  r’  r�  r¨  r³  rº  rÀ  rÌ  rÔ  ræ  rá  r&  r2  r.  r4  r   rA   ÚPatternrr   r	   rF  rJ  r\  r`  rb  rf  r   r   r   r‘  r’  r”  r$   r€  rk  r…  r�  r“  r–  rœ  r¨  rÃ  r¤  rÝ  rá  rã  r%   rj  rÿ  r  r  r&   r
  Ú__classcell__)r�   s   @r   ra   ra   Ê   s|  ø€ € € € € ðð ð Ðð ÐØ"ÐØ"Ðð 2˜~ð  2ð  2ð  2ð  2ð  2ð  2ðD ð<¨cð <°dð <ð <ð <ñ „\ð<ð ðA¨8°D¸¸c¸´NÔ+Cð AÈÐQTÌð Að Að Añ „[ðAð ð°H¸S´Mð ÀhÈsÄmð ð ð ñ „[ðð
 ð°h¸s´mð ÈÐQTÌð ð ð ñ „[ðð
 ð8¨)ð 8¸ð 8ð 8ð 8ñ „\ð8ðc˜t Cœyð cð cð cð cð ð
¨Ið 
¸$ð 
ð 
ð 
ñ „\ð
ð ð*¨ð *°tð *ð *ð *ñ „\ð*ðð  cð °Dð ÀTð ð ð ð ð2 d¨3°¨8¤nð 2ð 2ð 2ð 2ðAG¸ð AGÀtð AGð AGð AGð AGðF8)°Ið 8)À$ð 8)ð 8)ð 8)ð 8)ð| %)Ø.2ð1ð 1àð1ð ð1ð ˜S”Mð	1ð
 ' sœmð1ð 
�#Œð1ð 1ð 1ð 1ðf8j°3ð 8jÀCð 8jÐTWð 8jÐ\`ð 8jð 8jð 8jð 8jðtDZð DZð DZð DZðLR˜tð Rð Rð Rð RðhBð Bð Bð BðB$¨X°c¬]ð $Èð $ÐQUð $ð $ð $ð $ð0 #'Ø-1ðYUð YUàðYUð ðYUð ˜3”-ð	YUð
 ˜4  S œ>Ô*ðYUð 
ðYUð YUð YUð YUðB ðU;ð U;ð U;àðU;ð ðU;ð ð	U;ð ðU;ð 
ðU;ð U;ð U;ð U;ðp 9;Øð;ð ;Øð;Ø$'ð;Ø25ð;àð;ð 
ð;ð ;ð ;ð ;ðD /Ø-1ð>;ð >;Øð>;Ø%(ð>;Ø7:ð>;àð>;ð ˜4  S œ>Ô*ð>;ð 
ð	>;ð >;ð >;ð >;ðP .2ðH;ð H;àðH;ð ðH;ð ð	H;ð
 ðH;ð ðH;ð ˜4  S œ>Ô*ðH;ð 
ðH;ð H;ð H;ð H;ðT Ðð'5¨Dð '5¸ð '5Àð '5ð '5ð '5ð '5ðRq!Øðq!Ø),ðq!à	ðq!ð q!ð q!ð q!ðffSØðfSØ)DðfSà	ðfSð fSð fSð fSðP¨sð ¸#ð À#ð ð ð ð ð& "&Ø"&Ø-1ð.Tð .Tàð.Tð ð.Tð ˜#”ð	.Tð
 ˜3”-ð.Tð ˜4  S œ>Ô*ð.Tð 
ð.Tð .Tð .Tð .Tð .Tð .Tðh "&Ø"&Ø-1ð"Yð "Yàð"Yð ð"Yð ˜#”ð	"Yð
 ˜3”-ð"Yð ˜4  S œ>Ô*ð"Yð 
ð"Yð "Yð "Yð "Yð "Yð "YðP "&Ø#'Ø"&Ø-1ð!að !aàð!að ð!að ˜#”ð	!að
 ˜C”=ð!að ˜3”-ð!að ˜4  S œ>Ô*ð!að 
ð!að !að !að !að !að !aðN "&Ø"&Ø-1ðTð TàðTð ðTð ˜#”ð	Tð
 ˜3”-ðTð ˜4  S œ>Ô*ðTð 
ðTð Tð Tð Tð Tð TðF "&Ø"&Ø-1ð?Wð ?Wàð?Wð ð?Wð ˜#”ð	?Wð
 ˜3”-ð?Wð ˜4  S œ>Ô*ð?Wð 
ð?Wð ?Wð ?Wð ?Wð ?Wð ?WðJ "&Ø"&Ø-1ðTð TàðTð ðTð ˜#”ð	Tð
 ˜3”-ðTð ˜4  S œ>Ô*ðTð 
ðTð Tð Tð Tð@ð ¨ð ¸ÀÀcÈ3ÀhÄÔ8Pð Ð\`ð ð ð ð ð< I¨3ð  I°4¸¸S¸´>ð  Ið  Ið  Ið  IðDl cð l¨cð lð lð lð lð`d¨4ð dð dð dð dðN¨s°3¬xð Nð Nð Nð Nð¨3¨s¬8ð ð ð ð ð*$¨4°´
Ô+;ð $ð $ð $ð $ðL4 gð 4°$ð 4ð 4ð 4ð 4ðf¨ð f°Dð fð fð fð fð ¨Wð  ¸ð  ð  ð  ð  ðD	¸ð 	ÀTð 	ð 	ð 	ð 	ð¨H°S¬Mð ¸hÀs¼mð ð ð ð ð OTð "?ð "?ð "?¨wð "?Àtð "?ÐX\ð "?ð "?ð "?ð "?ðH(°ð (À,ÔB[ð (Ð`dð (ð (ð (ð (ð )¨Fð )¸\Ô=Vð )Ð[_ð )ð )ð )ð )ð#)°Vð #)ÀlÔF_ð #)Ðdhð #)ð #)ð #)ð #)ðR
 \ð 
°cð 
ð 
ð 
ð 
ð
¨ð 
¸$ð 
ð 
ð 
ð 
ð@>¨3ð >°4ð >ð >ð >ð >ðB, lð ,¸ð ,ÀSð ,ð ,ð ,ð ,ðE°#ð E¸$ð Eð Eð Eð Eðm¨cð m¸,ð mÈ4ð mð mð mð mð"E)°&ð E)À<ÔC\ð E)Ðaeð E)ð E)ð E)ð E)ðN
¸Sð 
Èð 
ÐZ^ð 
ð 
ð 
ð 
ð2	>¸Sð 	>ÀTð 	>ð 	>ð 	>ð 	>ð?¨ð ?¸ð ?ÈDð ?ð ?ð ?ð ?ðB+Zð +Zð +Zð +ZðZ%¨#ð %¸(À3¼-ð %ÈHÐUYÐZ]Ð_bÐZbÔUcÔLdð %ð %ð %ð %ðN°Cð ÀCð ÐUXð Ð]að ð ð ð ð $(ð	a
ð a
àða
ð ða
ð ˜C”=ð	a
ð
 
ða
ð a
ð a
ð a
ðJ\ Dð \ð \ð \ð \ð¨3ð ¸Cð Èð ÐPTð ð ð ð ðH¨|ð HÀð Hð Hð Hð Hð°,ð ÐIZð Ð_cð ð ð ð ð ð ð ð r   ra   )Rr  rí   r:  Úloggingry   r2  Úhtmlr  rA   rÏ  r   r   r   r   Ú	getLoggerr   rè   r"  r   r   r	   r
   r   r   rÅ   Útelegram.extr   r   r   r   rŽ  r   r   Útelegram.constantsr   r   Útelegram.requestr   r6   r   ÚsysÚpathlibr   Ú_Pathr£  Úinsertr¢   Ú__file__ÚresolveÚparentsÚgateway.configr!   r"   ró  r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   Ú"gateway.platforms.telegram_networkr1   r2   r3   rH   r7   r=  r:   r=   rC   rU   rJ   r_   ra   r   r   r   ú<module>r      so  ððð ð €€€Ø €€€Ø €€€Ø 	€	€	€	Ø €€€Ø Ð Ð Ð Ø 	€	€	€	Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,à	ˆÔ	˜8Ñ	$Ô	$€ð&%ØYÐYÐYÐYÐYÐYÐYÐYÐYÐYÐYÐYÐYÐYð"Ø/Ð/Ð/Ð/Ð/Ð/Ð/øØð "ð "ð "Ø!ÐÐÐð"øøøðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð 7Ð6Ð6Ð6Ð6Ð6Ð6Ð6Ø-Ð-Ð-Ð-Ð-Ð-ØÐÐøØð %ð %ð %ØÐØ€FØ
€CØ€GØÐØÐØÐØ€KØ€NØÐØ ÐØ€LØ€GØ€IØ€Hðð ð ð ð ñ ô ð à$€L€L€Lð+%øøøð. €
€
€
Ø !Ð !Ð !Ð !Ð !Ð !Ø „‡‚��3�3�u�u˜X‘”×.Ò.Ñ0Ô0Ô8¸Ô;Ñ<Ô<Ñ =Ô =Ð =à 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð Tð ð ð ð ð �"”*Ð<Ñ=Ô=€ð.�sð .˜sð .ð .ð .ð .ð
�cð ˜cð ð ð ð ð@ !�b”jØ7ñô Ð ð
.˜ð . ð .ð .ð .ð .ð4 ð 4¨ð 4ð 4ð 4ð 4ðn\-ð \-ð \-ð \-ð \-Ð)ñ \-ô \-ð \-ð \-ð \-s5   ¼B  ÁA ÁB  ÁAÁB  ÁAÁ#B  Â 2B5Â4B5