+
    jHàj±J  ã                  óæ   € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHtH	t	H
t
Ht ^ RIHtHt ^ RIHt ]P"                  ! R4      tRR R lltRtR	]! 4        R
]! R4       R2tRtRt ! R R4      tR# )zATelegram DM topic-mode mixin for :class:`hermes_state.SessionDB`.)ÚannotationsN)ÚAnyÚDictÚListÚOptional)Ú_sql_preview_rawÚ_sql_session_last_active)ÚStateDbReplacedErrorÚhermes_statec               ó    € V ^8„  d   QhRRRR/# )é   Úprofile_namezOptional[str]ÚreturnÚstr© )Úformats   "Ú:/home/ubuntu/.hermes/hermes-agent/hermes_state_telegram.pyÚ__annotate__r      s   € ÷ 'ñ '¸ð 'ÐRUñ 'ó    c                ó`   € \        T ;'       g    R4      P                  4       pV'       d   V# R# )uÂ   Empty/missing â†’ ``"default"`` (single namespace for non-multiplexed gateways).
Multiplexed callers must pass the *routed* profile (``source.profile``), never the
process-global active profile.Ú Údefault)r   Ústrip)r   Únames   & r   Ú&_normalize_telegram_topic_profile_namer      s,   € ô ˆ|×!Ð!˜rÓ"×(Ñ(Ó*€Dßˆ4Ð&˜YÐ&r   z®
                    SELECT s.*,
                        COALESCE(sp.prompt, s.system_prompt)
                            AS _system_prompt_resolved,
                        z,
                        Úszô AS last_active
                    FROM sessions s
                    LEFT JOIN system_prompts sp
                      ON sp.hash = s.system_prompt_hash
                    WHERE s.source = 'telegram'
                      AND s.user_id = ?
zq                    ORDER BY last_active DESC, s.started_at DESC
                    LIMIT ?
                    a                        AND COALESCE(NULLIF(TRIM(s.profile_name), ''), 'default') = ?
                      AND NOT EXISTS (
                          SELECT 1 FROM telegram_dm_topic_bindings b
                          WHERE b.session_id = s.id
                      )
c                  ó  € ] tR t^\tRtR tR R ltR R ltR R ltR	R
RRRR/R R llt	R	R
RR/R R llt
R	R
/R R lltR	R
/R R lltR	R
/R R lltR R ltR	R
/R R lltRRR	R
/R  R! lltR" R# ltR	R
R$^
/R% R& lltR'tR# )(ÚSessionTelegramTopicsMixinzÞTelegram DM topic-mode tables, bindings and lookups. Read paths tolerate absent
tables (nobody ran ``/topic``) by returning their empty value and never create them;
pre-v3 tables left by an upgrade are self-healed on read.c                ó(  €  V! 4       #   \         P                   d"   pR\        T4      9  d   Tu Rp?#  Rp?MRp?ii ; i T P                  4        T! 4       #   \         P                  \
        3 d    \        P                  RRR7       Tu # i ; i)u   Run ``read()``; an absent table reads as ``empty``. A pre-v3 table left by an upgrade
(#103363) raises ``no such column: profile_name`` â€” heal it and retry, otherwise the
write-only migration is never reached and topic mode silently reads as off forever.zno such column: profile_nameNzFtelegram topic tables are pre-v3 and the heal failed; reading as emptyT)Úexc_info)Úsqlite3ÚOperationalErrorr   Úapply_telegram_topic_migrationÚErrorr	   ÚloggerÚwarning)ÚselfÚreadÚemptyÚexcs   &&& r   Ú_topic_readÚ&SessionTelegramTopicsMixin._topic_reada   s†   € ð	Ù“6ˆMøÜ×'Ñ'ô 	Ø-´S¸³XÔ=Ø•ô >ûð	úð	Ø×/Ñ/Ô1ñ ‹vˆøô —‘Ô3Ð4ô 	Ü�N‰NÐcÐnrˆNÔsØŠLð	ús&   ‚	 ‰?ž:¯?º?ÁA Á4BÂBc               ó   € V ^8„  d   QhRR/# ©r   Úsqlr   r   )r   s   "r   r   Ú'SessionTelegramTopicsMixin.__annotate__q   s   € ÷ Kñ K 3ñ Kr   c                	ó8   a aa€ S P                  VV V3R  lR4      # )c                 ó(   <€ SP                  SS 4      # ©N)Ú	_read_one©Úparamsr&   r.   s   €€€r   Ú<lambda>Ú<SessionTelegramTopicsMixin._topic_read_one.<locals>.<lambda>r   ó   ø€ ¨¯©°s¸FÔ(Cr   N©r*   ©r&   r.   r5   s   fffr   Ú_topic_read_oneÚ*SessionTelegramTopicsMixin._topic_read_oneq   s   ú€ Ø×ÑÖ CÀTÓJÐJr   c               ó   € V ^8„  d   QhRR/# r-   r   )r   s   "r   r   r/   t   s   € ÷ Iñ I 3ñ Ir   c                	ó8   a aa€ S P                  VV V3R  l. 4      # )c                 ó(   <€ SP                  SS 4      # r2   )Ú	_read_allr4   s   €€€r   r6   Ú<SessionTelegramTopicsMixin._topic_read_all.<locals>.<lambda>u   r8   r   r9   r:   s   fffr   Ú_topic_read_allÚ*SessionTelegramTopicsMixin._topic_read_allt   s   ú€ Ø×ÑÖ CÀRÓHÐHr   c               ó   € V ^8„  d   QhRR/# )r   r   ÚNoner   )r   s   "r   r   r/   w   s   € ÷ +!ñ +!°ñ +!r   c                ó6   a € V 3R lpS P                  V4       R# )añ  Create Telegram DM topic-mode tables on explicit /topic opt-in. Deliberately NOT
part of startup reconciliation: operators can upgrade and keep the old bot
behavior until a user runs /topic. Also invoked by ``_topic_read`` to heal a
pre-v3 table an upgrade left behind (#103363). Schema versions: v1 initial; v2 session_id FK
ON DELETE CASCADE (pruning clears bindings); v3 ``profile_name`` on both tables so
multiplexed gateways sharing one state.db isolate topic state per profile.

See #76423.
c                ó  <€ \          F¿  w  rpV P                  R V RV R24       V P                  RV R24       Uu0 uF  qD^,          kK  	  ppRV9   d   KQ  VP                  RR^4      pRV9   d   R	MRpV P                  R
V R24       SP                  V P	                  4       W R2RV RV R2RV RV RV RV RV 2
4       KÁ  	  V P                  R4       V P                  R4       V P                  RR4       R# u upi )zCREATE TABLE IF NOT EXISTS z (Ú)zPRAGMA table_info('z')r   zprofile_name, r   Ú
session_idz@ WHERE EXISTS (SELECT 1 FROM sessions s WHERE s.id = session_id)zDROP TABLE IF EXISTS Ú_newÚ_legacyzCREATE TABLE zINSERT INTO z) SELECT 'default', z FROM zrCREATE UNIQUE INDEX IF NOT EXISTS idx_telegram_dm_topic_bindings_session ON telegram_dm_topic_bindings(session_id)z|CREATE INDEX IF NOT EXISTS idx_telegram_dm_topic_bindings_user ON telegram_dm_topic_bindings(profile_name, user_id, chat_id)zgINSERT INTO state_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.valueN)Ú telegram_dm_topic_schema_versionÚ3)Ú_TOPIC_TABLESÚexecuteÚreplaceÚ_rebuild_tableÚcursor)	ÚconnÚtableÚcolumnsÚddlÚrowÚhaveÚlegacy_columnsÚliver&   s	   &       €r   Ú_doÚFSessionTelegramTopicsMixin.apply_telegram_topic_migration.<locals>._do�   sF  ø€ ß'4Ñ#� Ø—‘Ð:¸5¸'ÀÀCÀ5ÈÐJÔKØ*.¯,©,Ð9LÈUÈGÐSUÐ7VÔ*WÓXÑ*W 3˜AŸ˜Ñ*W�ÐXØ! TÔ)Ùð ")§¡Ð1AÀ2ÀqÓ!I�Ø]iÐmtÔ]tÑYÐz|�Ø—‘Ð4°U°G¸4Ð@ÔAØ×#Ñ#Ø—K‘K“M 5¨G°7Ð*;¸}ÈUÈGÐSUÐVYÐUZÐZ[Ð=\Ø" 5 '¨¨G¨9Ð4HÈÐHXÐX^Ð_dÐ^eÐelÐmqÐlrÐsöñ (5ð& �L‰Lð<ôð �L‰LðPôð �L‰LðHà9öùò3 Ys   ½DN)Ú_execute_write)r&   r[   s   f r   r"   Ú9SessionTelegramTopicsMixin.apply_telegram_topic_migrationw   s   ø€ õ 	ðB 	×Ñ˜CÖ r   r   r   Úhas_topics_enabledNÚallows_users_to_create_topicsc               ó0   € V ^8„  d   QhRRRRRRRRRRRR	/# )
r   Úchat_idr   Úuser_idr   r_   úOptional[bool]r`   r   rE   r   )r   s   "r   r   r/   ¤   sF   € ÷  ]ñ  ]Øð ]Ø(+ð ]Ø;>ð ]Ø^lð ]à'5ð ]ð 
ñ ]r   c               óà   € V P                  4        \        P                  ! 4       p\        V4      pR R lpV P                  RV\	        V4      \	        V4      WfV! V4      V! V4      V34       R# )af  Enable Telegram DM topic mode for one private chat/user. Owns the explicit topic
migration; SessionDB startup must not create these tables.

``profile_name`` namespaces rows under a shared multiplex ``state.db`` (issue #76423). Callers
handling a multiplexed event must pass the routed profile from ``source.profile``, not the
process-global active profile.
c               ó    € V ^8„  d   QhRRRR/# )r   Úvaluerd   r   zOptional[int]r   )r   s   "r   r   ÚKSessionTelegramTopicsMixin.enable_telegram_topic_mode.<locals>.__annotate__³   s   € ÷ 	Bñ 	B˜>ð 	B¨mñ 	Br   c                ó&   € V f   R # V '       d   ^# ^ # r2   r   )rg   s   &r   Ú_to_intÚFSessionTelegramTopicsMixin.enable_telegram_topic_mode.<locals>._to_int³   s   € Ø š=�4ÐA·E¨qÐA¸qÐAr   aÄ  
            INSERT INTO telegram_dm_topic_mode (
                profile_name, chat_id, user_id, enabled, activated_at, updated_at,
                has_topics_enabled, allows_users_to_create_topics,
                capability_checked_at
            ) VALUES (?, ?, ?, 1, ?, ?, ?, ?, ?)
            ON CONFLICT(profile_name, chat_id) DO UPDATE SET
                user_id = excluded.user_id,
                enabled = 1,
                updated_at = excluded.updated_at,
                has_topics_enabled = excluded.has_topics_enabled,
                allows_users_to_create_topics = excluded.allows_users_to_create_topics,
                capability_checked_at = excluded.capability_checked_at
            N)r"   Útimer   Ú
_write_sqlr   )r&   rb   rc   r   r_   r`   Únowrj   s   &$$$$$  r   Úenable_telegram_topic_modeÚ5SessionTelegramTopicsMixin.enable_telegram_topic_mode¤   sl   € ð 	×+Ñ+Ô-Ü�iŠi‹kˆÜ=¸lÓKˆõ	Bð 	�‰ð ð ¤ G£¬c°'«l¸CÙÐ,Ó-©wÐ7TÓ/UÐWZð\ö	]r   Úclear_bindingsTc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rb   r   r   rq   Úboolr   rE   r   )r   s   "r   r   r/   Æ   s,   € ÷ !ñ !Øð!Ø-0ð!ØNRð!à	ñ!r   c               óT   aaa€ \        S4      oVVV3R lpV P                  V4       R# )z¾Disable Telegram DM topic mode for one private chat. ``clear_bindings`` also drops
the chat's bindings so a later re-enable starts clean. Never creates the tables;
absent tables are a no-op.c           
     óF  <€ \         P                  ! \        P                  4      ;_uu_ 4        V P	                  R \
        P
                  ! 4       S\        S4      34       S'       d   V P	                  RS\        S4      34       RRR4       R#   + '       g   i     R# ; i)údUPDATE telegram_dm_topic_mode SET enabled = 0, updated_at = ? WHERE profile_name = ? AND chat_id = ?zMDELETE FROM telegram_dm_topic_bindings WHERE profile_name = ? AND chat_id = ?N)Ú
contextlibÚsuppressr    r!   rO   rl   r   )rS   rb   rq   r   s   &€€€r   r[   ÚCSessionTelegramTopicsMixin.disable_telegram_topic_mode.<locals>._doÎ   sn   ø€ Ü×$Ò$¤W×%=Ñ%=×>Õ>Ø—‘ð=ä—Y’Y“[ ,´°G³Ð=ô÷
 "Ø—L‘LØgØ%¤s¨7£|Ð4ô÷ ?×>×>Ò>ús   ®ABÂB 	N)r   r]   )r&   rb   r   rq   r[   s   &ddd r   Údisable_telegram_topic_modeÚ6SessionTelegramTopicsMixin.disable_telegram_topic_modeÆ   s$   ú€ ô >¸lÓKˆ÷	ð 	×Ñ˜CÖ r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rb   r   rc   r   r   rs   r   )r   s   "r   r   r/   Ü   s*   € ÷ :ñ :¸ð :Àsð :ÐZ]ð :Ðnrñ :r   c               ó–   € \        V4      pV P                  RV\        V4      \        V4      34      pVe   \        V^ ,          4      # R# )zDReturn whether Telegram DM topic mode is enabled for this chat/user.zŸ
                    SELECT enabled FROM telegram_dm_topic_mode
                    WHERE profile_name = ? AND chat_id = ? AND user_id = ?
                    F)r   r;   r   rs   )r&   rb   rc   r   rW   s   &$$$ r   Úis_telegram_topic_mode_enabledÚ9SessionTelegramTopicsMixin.is_telegram_topic_mode_enabledÜ   sO   € ä=¸lÓKˆØ×"Ñ"ð $ð '¬¨G«´c¸'³lÐCóEˆð  #šŒt�C˜•F‹|Ð9°EÐ9r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rb   r   Ú	thread_idr   r   úOptional[dict[str, Any]]r   )r   s   "r   r   r/   å   s,   € ÷ 	*ñ 	*Øð	*Ø*-ð	*Ø=@ð	*à	!ñ	*r   c               ó�   € \        V4      pV P                  RV\        V4      \        V4      34      pV'       d   \        V4      # R# )z?Return the session binding for a Telegram DM topic, if present.zŸ
                    SELECT * FROM telegram_dm_topic_bindings
                    WHERE profile_name = ? AND chat_id = ? AND thread_id = ?
                    N)r   r;   r   Údict)r&   rb   r�   r   rW   s   &$$$ r   Úget_telegram_topic_bindingÚ5SessionTelegramTopicsMixin.get_telegram_topic_bindingå   sK   € ô >¸lÓKˆØ×"Ñ"ð $ð '¬¨G«´c¸)³nÐEóGˆ÷  Œt�C‹yÐ) TÐ)r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rb   r   r   r   úlist[dict[str, Any]]r   )r   s   "r   r   r/   ð   s$   € ÷ 	+ñ 	+Øð	+Ø-0ð	+à	ñ	+r   c               ó’   € \        V4      pV P                  RV\        V4      34      pV Uu. uF  p\        V4      NK  	  up# u upi )zFAll bindings for one chat, newest first ([] when the table is absent).zhSELECT * FROM telegram_dm_topic_bindings WHERE profile_name = ? AND chat_id = ? ORDER BY updated_at DESC)r   rB   r   r„   )r&   rb   r   ÚrowsrW   s   &$$  r   Ú%list_telegram_topic_bindings_for_chatÚ@SessionTelegramTopicsMixin.list_telegram_topic_bindings_for_chatð   sK   € ô >¸lÓKˆØ×#Ñ#ØvØœ3˜w›<Ð(ó
ˆñ &*Ó*¡T˜c”�S–	¡TÑ*Ð*ùÒ*s   ­Ac               ó    € V ^8„  d   QhRRRR/# )r   rI   r   r   r‚   r   )r   s   "r   r   r/   û   s   € ÷ *ñ *À3ð *ÐKcñ *r   c               ód   € V P                  R\        V4      34      pV'       d   \        V4      # R# )zEReverse lookup via the UNIQUE INDEX on session_id; None when unbound.z{
                    SELECT * FROM telegram_dm_topic_bindings
                    WHERE session_id = ?
                    N)r;   r   r„   ©r&   rI   rW   s   &$ r   Ú%get_telegram_topic_binding_by_sessionÚ@SessionTelegramTopicsMixin.get_telegram_topic_binding_by_sessionû   s6   € à×"Ñ"ð $ô ˜j›/Ð+ó-ˆ÷  Œt�C‹yÐ) TÐ)r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rb   r   r�   r   r   Úintr   )r   s   "r   r   r/     s*   € ÷ +(ñ +(¸ð +(Èð +(Ð[^ð +(Ðorñ +(r   c               ó„   aaa€ \        S4      \        S4      uoo\        S4      oR VVV3R llpV P                  V4      # )a³  Remove the binding row for one (chat, thread) pair. Called when the Bot API confirms
a topic was deleted externally (``Thread not found`` after the same-thread retry
failed); otherwise ``gateway.run._recover_telegram_topic_thread_id`` keeps
redirecting inbound messages to the dead topic. If this removes the chat's *last*
binding, ``telegram_dm_topic_mode`` is flipped to ``enabled = 0`` in the same
transaction, or a user who disabled topics in the Telegram client (not via
``/topic off``) stays stuck. Returns the number of rows deleted; absent binding or
unmigrated tables are silent no-ops (never raise from a cleanup hot path).

Without this prune, the stale row keeps living in ``telegram_dm_topic_bindings`` and the recovery
logic in ``gateway.run._recover_telegram_topic_thread_id`` cheerfully redirects future inbound
messages to the deleted topic, causing tool progress, approvals, and replies to land in the wrong
place. Issue #31501.
c               ó   € V ^8„  d   QhRR/# )r   r   r“   r   )r   s   "r   r   ÚNSessionTelegramTopicsMixin.delete_telegram_topic_binding.<locals>.__annotate__  s   € ÷ 	ñ 	˜ñ 	r   c                óÖ  <€  V P                  R SSS34      P                  ;'       g    ^ pT'       g   ^ # \        P
                  ! \        P                  4      ;_uu_ 4        T P                  RSS34      P                  4       pTf)   T P                  R\        P                  ! 4       SS34       RRR4       T#   \        P                   d     ^ # i ; i  + '       g   i     T# ; i)z�
                    DELETE FROM telegram_dm_topic_bindings
                    WHERE profile_name = ? AND chat_id = ? AND thread_id = ?
                    z•
                    SELECT 1 FROM telegram_dm_topic_bindings
                    WHERE profile_name = ? AND chat_id = ? LIMIT 1
                    Nrv   )rO   Úrowcountr    r!   rw   rx   Úfetchonerl   )rS   ÚdeletedÚ	remainingrb   r   r�   s   &  €€€r   r[   ÚESessionTelegramTopicsMixin.delete_telegram_topic_binding.<locals>._do  sï   ø€ ðØŸ,™,ð (ð '¨°Ð;ó=÷ >F¹X÷Kð Kð JKð ÷ Ùô ×$Ò$¤W×%=Ñ%=×>Õ>Ø ŸL™Lð *ð '¨Ð0ó2÷ 3;±(³*ð ð Ò$Ø—L‘LðAäŸš› l°GÐ<ô÷ ?ð ˆNøô# ×+Ñ+ô Úðú÷ ?Ö>ð ˆNús#   ƒ%B; ©B; Á"ACÂ;CÃCÃC(	)r   r   r]   )r&   rb   r�   r   r[   s   &ddd r   Údelete_telegram_topic_bindingÚ8SessionTelegramTopicsMixin.delete_telegram_topic_binding  s@   ú€ ô ! ›\¬3¨y«>Ðˆ�Ü=¸lÓKˆ÷	ò 	ð2 ×"Ñ" 3Ó'Ð'r   Úmanaged_modeÚautoc               ó8   € V ^8„  d   QhRRRRRRRRRRRRRRR	R
/# )r   rb   r   r�   rc   Úsession_keyrI   rŸ   r   r   rE   r   )r   s   "r   r   r/   0  sN   € ÷ #!ñ #!Øð#!Ø*-ð#!Ø8;ð#!ØJMð#!àð#!à'*ð#!àCFð#!ð 
ñ#!r   c               ó$  aaaaaaaa	€ V P                  4        \        P                  ! 4       o	\        S4      \        S4      \        S4      uooo\        S4      \        S4      uoo\        S4      oVVV	VVVVV3R lpV P	                  V4       R# )zÆBind one Telegram DM topic thread to one Hermes session. A session may be linked to
only one topic: rebinding the same pair is idempotent; linking the session to a
different topic raises ValueError.c                óø   <€ V P                  R S	34      P                  4       pVe9   Vw  r#p\        V4      \        V4      \        V4      3SSS38w  d   \        R4      hV P                  RSSSSS
S	SSS3	4       R# )zž
                SELECT profile_name, chat_id, thread_id
                FROM telegram_dm_topic_bindings
                WHERE session_id = ?
                Nz3session is already linked to another Telegram topicah  
                INSERT INTO telegram_dm_topic_bindings (
                    profile_name, chat_id, thread_id, user_id, session_key, session_id,
                    managed_mode, linked_at, updated_at
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
                ON CONFLICT(profile_name, chat_id, thread_id) DO UPDATE SET
                    user_id = excluded.user_id,
                    session_key = excluded.session_key,
                    session_id = excluded.session_id,
                    managed_mode = excluded.managed_mode,
                    updated_at = excluded.updated_at
                )rO   r™   r   Ú
ValueError)rS   Úexisting_sessionÚlinked_profileÚlinked_chatÚlinked_threadrb   rŸ   rn   r   rI   r¢   r�   rc   s   &    €€€€€€€€r   r[   Ú;SessionTelegramTopicsMixin.bind_telegram_topic.<locals>._do=  sœ   ø€ Ø#Ÿ|™|ð -ð !�]ó	 $÷ %-¡H£Jð	 ð
  Ò+Ø=MÑ:�¨]Ü˜Ó'¬¨[Ó)9¼3¸}Ó;MÐNÐS_ÐahÐjsÐRtÔtÜ$Ð%ZÓ[Ð[Ø�L‰Lð ð # G¨Y¸ÀÈjÐZfÐhkÐmpÐqösr   N)r"   rl   r   r   r]   )
r&   rb   r�   rc   r¢   rI   rŸ   r   r[   rn   s
   &ddddddd @r   Úbind_telegram_topicÚ.SessionTelegramTopicsMixin.bind_telegram_topic0  ss   ÿ€ ð 	×+Ñ+Ô-Ü�iŠi‹kˆÜ&)¨'£l´C¸	³NÄCÈÃLÐ#ˆ�˜GÜ"% kÓ"2´C¸
³OÐˆ�ZÜ=¸lÓKˆ÷	sô 	sð, 	×Ñ˜CÖ r   c               ó    € V ^8„  d   QhRRRR/# )r   rI   r   r   rs   r   )r   s   "r   r   r/   U  s   € ÷ ñ Àð Èñ r   c               óB   € V P                  R\        V4      34      pVRJ# )uP   True if the session is bound to any Telegram DM topic (absent tables â†’ False).z—
                    SELECT 1 FROM telegram_dm_topic_bindings
                    WHERE session_id = ?
                    LIMIT 1
                    N)r;   r   r�   s   &$ r   Ú#is_telegram_session_linked_to_topicÚ>SessionTelegramTopicsMixin.is_telegram_session_linked_to_topicU  s/   € à×"Ñ"ð $ô ˜j›/Ð+ó	-ˆð
 ˜$ˆÐr   Úlimitc          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   rb   r   rc   r   r±   r“   r   rˆ   r   )r   s   "r   r   r/   ^  s4   € ÷ 5ñ 5Øð5Ø(+ð5Ø;>ð5ØSVð5à	ñ5r   c          
     ó&  € \        V4      pV P                  4       ;_uu_ 4       p VP                  \        \        ,           \
        ,           \        V4      V\        V4      34      P                  4       pRRR4       X Uu. uF  qpP                  V4      NK  	  up#   \        P                   dG    TP                  \        \
        ,           \        T4      \        T4      34      P                  4       p L‚i ; i  + '       g   i     LŽ; iu upi )zýThis user's Telegram sessions not bound to a topic. Read-only: if the bindings table
is absent, every session is unlinked and the profile-unscoped query is used.
Scoped by ``profile_name`` so multiplexed profiles do not surface each other.

See #76423.
N)r   Ú	_read_ctxrO   Ú_UNLINKED_SELECT_HEADÚ_UNLINKED_SCOPE_CLAUSESÚ_UNLINKED_SELECT_TAILr   r“   Úfetchallr    r!   Ú	_rich_row)r&   rb   rc   r   r±   rS   rŠ   rW   s   &$$$$   r   Ú(list_unlinked_telegram_sessions_for_userÚCSessionTelegramTopicsMixin.list_unlinked_telegram_sessions_for_user^  s×   € ô >¸lÓKˆØ�^‰^×Ô ðØ—|‘|Ü)Ô,CÕCÔF[Õ[Ü˜“\ <´°U³Ð<ó÷ ‘(“*ð ÷ ñ 04Ó4©t¨—‘˜sÖ#©tÑ4Ð4øô	 ×+Ñ+ô Ø—|‘|Ü)Ô,AÕAÄCÈÃLÔRUÐV[ÓR\ÐC]óç‘(“*ò ðú÷ ×üò 5s0   ¤C;¦ABÂDÂAC8Ã5C;Ã7C8Ã8C;Ã;D	r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r*   r;   rB   r"   ro   rz   r~   r…   r‹   r�   r�   r«   r¯   rº   Ú__static_attributes__r   r   r   r   r   \   sÅ   † ñAòõ KõIõ+!ðZ ]Ø?Hð ]Ømqð ]à6:÷ ]ðD!Ø3<ð!ØUY÷!ð,:Ð`i÷ :ð	*ØCL÷	*ð	+Ø3<÷	+õ*ð+(Ðaj÷ +(ðZ#!à-3ð#!àIR÷#!õJð5ØAJð5ØY[÷5ó 5r   r   r2   ))Útelegram_dm_topic_modez°profile_name, chat_id, user_id, enabled, activated_at, updated_at, has_topics_enabled, allows_users_to_create_topics, capability_checked_at, intro_message_id, pinned_message_idai  
                    profile_name TEXT NOT NULL DEFAULT 'default',
                    chat_id TEXT NOT NULL,
                    user_id TEXT NOT NULL,
                    enabled INTEGER NOT NULL DEFAULT 1,
                    activated_at REAL NOT NULL,
                    updated_at REAL NOT NULL,
                    has_topics_enabled INTEGER,
                    allows_users_to_create_topics INTEGER,
                    capability_checked_at REAL,
                    intro_message_id TEXT,
                    pinned_message_id TEXT,
                    PRIMARY KEY (profile_name, chat_id)
                )Útelegram_dm_topic_bindingszgprofile_name, chat_id, thread_id, user_id, session_key, session_id, managed_mode, linked_at, updated_ata:  
                    profile_name TEXT NOT NULL DEFAULT 'default',
                    chat_id TEXT NOT NULL,
                    thread_id TEXT NOT NULL,
                    user_id TEXT NOT NULL,
                    session_key TEXT NOT NULL,
                    session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
                    managed_mode TEXT NOT NULL DEFAULT 'auto',
                    linked_at REAL NOT NULL,
                    updated_at REAL NOT NULL,
                    PRIMARY KEY (profile_name, chat_id, thread_id)
                )rÀ   Ú
__future__r   rw   Úloggingr    rl   Útypingr   r   r   r   Úhermes_state_commonr   r   Úhermes_state_errorsr	   Ú	getLoggerr$   r   rN   rµ   r·   r¶   r   r   r   r   Ú<module>rÊ      s‹   ðÙ Gå "ã Û Û Û ß ,Ó ,ç JÝ 4ð 
×	Ò	˜>Ó	*€÷'ð$€ðPñ *Ó+Ð,ð -Ù1°#Ó6Ð7ð 8ðÐ ðÐ ðÐ ÷V5ó V5r   