§
    øžyjå¨ ã                   ó‚/  — U d Z 	 ddlZn# e$ r Y nw xY w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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ZddlmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$ ddl%m&Z&m'Z' dd	l(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 dd
l1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z; ddl<m=Z= dZ>dZ?dZ@dZAdZBdZCdZD ejE        d¦  «        ZFdZG ejE        dejH        ejI        z  ¦  «        ZJdZKdZLdeMdeNdeNfd„ZOdeMddfd„ZPd eQd!eQd"eQd#eRd$eRd%eRd&eRdeQfd'„ZS	 �dëd(eMd)eNd*eeM         ddfd+„ZTd,eMdeMfd-„ZU ejE        d. V                    d/„ e)e/e0e.e-e+e,e*fD ¦   «         ¦  «        ejH        ¦  «        ZWdeQfd0„ZX eYh d1£¦  «        ZZd2e deQfd3„Z[ ejE        d4ejH        ¦  «        Z\ ejE        d5ejH        ¦  «        Z] ejE        d6ejH        ¦  «        Z^ ejE        d7ejH        ¦  «        Z_ ejE        d8¦  «         ejE        d9¦  «         ejE        d:¦  «         ejE        d;¦  «         ejE        d<¦  «         ejE        d=¦  «         ejE        d>¦  «        fZ`�dìd?„Zad2e deMfd@„Zb	 �dëddAœdBeeeMe f                  d2e deeeMe f                  fdC„ZcdDe dEeeeMe f                  deQfdF„ZddGeedeQfdH„ZfdIdJdKeeMe f         ddfdL„ZgdMeMdeMfdN„ZhdOdPdeMfdQ„ZidRdRdSdTœdUeMdVeMdWeMdXeQdYeQdZeQdeMfd[„ZjdMeMdeMfd\„Zk ejE        d]ejH        ¦  «        ZldMeMdeQfd^„Zmd2e dMeMdeMfd_„Znd2e d`eMdaeMdeeM         fdb„ZodeMfdc„Zpdd„ ZqdRdeœd2e dfe dge dheQdeeM         f
di„ZrdjesdkeMdleMdeQfdm„ZtdSdddnœdjesdkeMdleMdoeQd2e dpeue          dz  deQfdq„ZvdMeMd2e deMfdr„ZwdsZxdZydte deeN         fdu„ZzdeNfdv„Z{deNfdw„Z|dxe dee"eMeMf                  fdy„Z}dzeMdoeNdeNfd{„Z~dDe d|eMd}d~deMddf
d€„Zddd�œdte d‚eeN         dƒeeN         deQfd„„Z€	 �dídRd†œd‡eeM         daeMdˆeQdeMfd‰„Z�dŠZ‚eƒeMd‹f         e„dŒ<   	 �dîd�eMdŽe d�eeMe f         d�eQdeeMe f         f
d‘„Z…d’Z†d“Z‡d”Zˆd•eeM         deQfd–„Z‰d—e deueM         fd˜„ZŠd™e deueM         fdš„Z‹d›e deMfdœ„ZŒd™e d›e deQfd�„Z�djees         deQfdž„ZŽddSdŸœd e!eeMe f                  d•eeM         d¡eQdeƒe!eeMe f                  eeM         f         fd¢„Z�d£e!eeMe f                  d¤e de!eeMe f                  fd¥„Z�dae d¦eeM         de fd§„Z‘d ee!eeMe f                           de fd¨„Z’h d©£Z“ddªl”m•Z•m–Z–m—Z— d«Z˜d¬Z™dŽe deQfd­„ZšdŽe de fd®„Z›d¯Zœ ejE        d°ejH        ¦  «        Z�	 	 �dïd±e!eeMe f                  d²eRd³eeu         deƒe!eM         eQf         fd´„Zždµe!eeMe f                  deufd¶„ZŸ�dìd·„Z d¸eMdeMfd¹„Z¡d¸eMdeMfdº„Z¢deQfd»„Z£defd¼„Z¤deQfd½„Z¥�dìd¾„Z¦d¿ej§        dÀ<    e ¦   «          ej¨         ©                    d eM eeª¦  «        j«        j«        ¦  «        ¦  «         ddÁl¬m­Z­m®Z® ddÂl¯m°Z°m±Z±  e­¦   «         Z²ddÃl³m´Z´ ddÄlµm¶Z¶ e²dÅz  Z· e¶e² eeª¦  «         ¸                    ¦   «         j¹        dÆ         dÅz  ¬Ç¦  «         �dìdÈ„Zº�dðdË„Z»deRfdÌ„Z¼ddÍl½m¾Z¿ ddÎlÀmÁZÂmÃZÄ  G dÏ„ dÐeÅ¦  «        ZÆ G dÑ„ dÒeÆ¦  «        ZÇe¿�dñdÔ„¦   «         ZÈ�dòdÖ„ZÉd2d×dØdÙdeQfdÚ„ZÊ ejE        dÛ¦  «        ZËdÜdÝhZÌddÞlÍmÎZÏ  eMeÏdD         dß         ¦  «        ej§        dà<   e²dáz  ZÐeÐ Ñ                    ¦   «         �r©	 ddâl9mÒZÒmÓZÓ  eÓeÐ¦  «        ZÔ eÒeÔ¦  «        ZÔ eÕeÔes¦  «        si ZÔ	 ddãlÖm×Z×  e×jØ        eÔ¦  «        ZÔn# eÙ$ r Y nw xY weÔ Ú                    ¦   «         D ]1\  ZÛZÜ eÕeÜeMeReNeQf¦  «        reÛej§        vr eMeÜ¦  «        ej§        eÛ<   Œ2eÔ Ý                    däi ¦  «        ZÞeÞ�r† eÕeÞes¦  «        �ry eMeÞ Ý                    då¦  «        pej§         Ý                    dæ¦  «        pd…¦  «         ß                    ¦   «          à                    ¦   «         Zái dådæ“dçdè“dédê“dëdì“dídî“dïdð“dñdò“dódô“dõdö“d÷dø“dùdú“dûdü“dýdþ“dÿ�d “�d�d“�d�d“�d�d“�d�d�d	�d
�d�d�d�d�d�d�d�d�d�d�dœ¥Zâeâ Ú                    ¦   «         D ]ª\  ZãZäeãeÞv r¡eÞeã         ZÜeãdék    r eMeÜ¦  «        �dv rŒ&eãdék    rD eÕeÜeM¦  «        r8 e:eáeÜ ß                    ¦   «         ¦  «        sej¨         å                    eÜ¦  «        ZÜ eÕeÜeæesf¦  «        r e	jç        eÜ¦  «        ej§        eä<   Œ— eMeÜ¦  «        ej§        eä<   Œ«eÔ Ý                    �di ¦  «        Zèeè�r¤ eÕeèes¦  «        �r—h �d£Zé	 d�dlêmëZë  eë¦   «         D ]Zìeé í                    eì�d         ¦  «         Œn# eÙ$ r Y nw xY weéD �]QZîeè Ý                    eîi ¦  «        Zï eÕeïes¦  «        sŒ& eMeï Ý                    �dd…¦  «        ¦  «         ß                    ¦   «         Zð eMeï Ý                    �dd…¦  «        ¦  «         ß                    ¦   «         Zñ eMeï Ý                    �dd…¦  «        ¦  «         ß                    ¦   «         Zò eMeï Ý                    �dd…¦  «        ¦  «         ß                    ¦   «         Zóeî ô                    ¦   «         Zõeðreð�dk    reðej§        �d eõ› �d!�<   eñreñej§        �d eõ› �d"�<   eòreòej§        �d eõ› �d#�<   eóreóej§        �d eõ› �d$�<   �ŒSeÔ Ý                    dDi ¦  «        Zöeö�r* eÕeöes¦  «        �r�d%eöv r eMeö�d%         ¦  «        ej§        �d&<   �d'eöv r eMeö�d'         ¦  «        ej§        �d(<   dßeöv r eMeödß         ¦  «        ej§        dà<   �d)eöv r eMeö�d)         ¦  «        ej§        �d*<   �d+eöv r eMeö�d+         ¦  «        ej§        �d,<   �d-eöv r eMeö�d-         ¦  «        ej§        �d.<   �d/eöv r eMeö�d/         ¦  «        ej§        �d0<   �d1eöv r eMeö�d1         ¦  «        ej§        �d2<   �d3eöv r eMeö�d3         ¦  «        ej§        �d4<   eÔ Ý                    �d5i ¦  «        Z÷e÷rL eÕe÷es¦  «        r@�d6e÷v r eMe÷�d6         ¦  «        ej§        �d7<   �d8e÷v r eMe÷�d8         ¦  «        ej§        �d9<   eÔ Ý                    �d:i ¦  «        Zøeør– eÕeøes¦  «        rŠ�d;eøv r eMeø�d;         ¦  «        ej§        �d<<   �d=eøv r eMeø�d=         ¦  «        ej§        �d><   �d?eøv r eMeø�d?         ¦  «        ej§        �d@<   �dAeøv r%�dBej§        vr eMeø�dA         ¦  «        ej§        �dB<   eÔ Ý                    �dCd…¦  «        Zùeùr) eÕeùeM¦  «        reù ß                    ¦   «         ej§        �dD<   eÔ Ý                    �dEi ¦  «        Zú eÕeúes¦  «        r>eú Ý                    �dF¦  «        Zûeû�& eMeû¦  «         à                    ¦   «         ej§        �dG<   eÔ Ý                    �dHi ¦  «        Zü eÕeües¦  «        �r;eü Ý                    �dI¦  «        Zýeý�eýrd¿n�dJej§        �dK<   eü Ý                    �dL¦  «        ZþeþrS eÕeþeM¦  «        reþZÿn7 eÕeþeæeƒf¦  «        r'e�j          V                    �dM„ eþD ¦   «         ¦  «        Zÿnd…Zÿeÿreÿej§        �dN<   eü Ý                    �dO¦  «        �Z�e��erd¿n�dJej§        �dP<   eü Ý                    �dQ¦  «        �Z�e� eM�e¦  «        ej§        �dR<   �dSeüv rIej§         Ý                    �dTd…¦  «         ß                    ¦   «         s eMeü�dS         ¦  «        ej§        �dT<   n\# eÙ$ rT�Z �e�dU �e�e¦  «        �j        › �dV�e› �e�j        �¬W¦  «          �e�dXe�j        �¬W¦  «         Y d�Z�[n
d�Z�[ww xY w	 d�dYl¬�m�Z �dZ �e	¦   «         v reÔni  Ý                    �d[i ¦  «        �Z
 eÕ�e
es¦  «        r%�e
 Ý                    �d\¦  «        r �edR�¬]¦  «         n1# eÙ$ r)�Z �e�d^�e› �e�j        �¬W¦  «         Y d�Z�[n
d�Z�[ww xY w	 d�d_l9�m�Z  �e¦   «          n1# eÙ$ r)�Z �e�d`�e› �e�j        �¬W¦  «         Y d�Z�[n
d�Z�[ww xY w	 d�dal9�m�Z  �e¦   «          n1# eÙ$ r)�Z �e�db�e› �e�j        �¬W¦  «         Y d�Z�[n
d�Z�[ww xY wd¿ej§        �dc<   d¿ej§        �dd<   d�de�l�m�Z�m�Z ej§         Ý                    dêd…¦  «        �Z�er�e�ev r¦ �e�eej§         Ý                    dæd…¦  «         e�j        �df¦  «         e�j        �d�dg¦  «         à                    ¦   «         �dhv  eM e�j        ¦   «         ¦  «        �¬i¦  «        �Z�e€ej§        �                     dêd¦  «         n�eej§        dê<   d�djlÀ�m�Z�m�Z�m�Z�m�Z�m�Z�m�Z�m�Z d�dk�l�m�Z�m�Z�m �Z �m!�Z!�m"�Z"�m#�Z#�m$�Z$�m%�Z%�m&�Z&�m'�Z'�m(�Z( d�dl�l)�m*�Z*�m+�Z+�m,�Z, d�dm�l-�m.�Z.�m/�Z/�m0�Z0 d�dn�l1�m2�Z3�m4�Z4�m5�Z5�m6�Z6 d�do�l7�m8�Z8 d�dp�l9�m:�Z: d�dq�l;�m<�Z< d�dr�l=�m>�Z> d�ds�l?�m@�Z@�mA�ZA�mB�ZB�mC�ZC�mD�ZD�mE�ZE�mF�ZF�mG�ZG�mH�ZH d�dt�lI�mJ�ZJ�mK�ZK�mL�ZL�mM�ZM�mN�ZN�mO�ZO d�du�lP�mQ�ZQ�mR�ZR�mS�ZS�mT�ZT�mU�ZU�mV�ZV d�dv�lW�mX�ZY�mZ�Z[�m\�Z]  e
�j^        �e¦  «        �Z_�e�j`        �dw�e�ja        �dx�e�jb        �dy�e�jc        �dz�e�jd        �d{i�ZedeeM         f�d|„�Zf �eg¦   «         �Zh�d}�Zieƒe„�d~<    �eg¦   «         �Zjdesf�d„�Zk�deMdesf�d€„�Zl�deeM         f�d�„�Zmdesdz  f�d‚„�Zn�dƒeRdeMf�d„„�Zo�dƒeRdeQf�d…„�Zp�dƒeRdeQf�d†„�Zq�dƒeRdeQf�d‡„�Zr�dƒeRdeQf�dˆ„�ZsdeMf�d‰„�Zt�dŠeM�d‹eM�dŒeMdeMf�d�„�Zu�dŽeNdeMf�d�„�Zv�d�eMdeeM         f�d‘„�ZwdeMd�eBdz  f�d’„�Zx�d“�Zy�d”�Zz�d•�Z{�d–�Z|�d—�Z}�d˜�Z~d�d™œ�dšeM�d›eM�dœeeg eQf                  deRf�d�„�Zd�d™œ�dšeM�dže�j€        �dŸe�j€        �d e�j�        �dœeeg eQf                  deQf�d¡„�Z‚dd�d¢œ�dšeMdëeN�dže�j€        �dŸe�j€        �d e�j�        �d£eN�dœeeg eQf                  ddf�d¤„�Zƒ eY�ey à                    ¦   «         �ez à                    ¦   «         �e{ à                    ¦   «         �e| à                    ¦   «         �e} à                    ¦   «         �e~ à                    ¦   «         h¦  «        �Z„daeeM         deQf�d¥„�Z…�d¦eMdeMf�d§„�Z†�d¨edeƒeMdz  eMdz  f         f�d©„�Z‡�dªeMdeMdz  f�d«„�Zˆd2d×deMf�d¬„�Z‰deQf�d­„�ZŠdef�d®„�Z‹desf�d¯„�ZŒd™esdz  desf�d°„�Z�desf�d±„�ZŽ�dëd™esdz  deMf�d²„�Z�dd�d³œd›eM�d´eeM         �dµeeM         deæeM         f�d¶„�Z�dd�d³œd™�ed2�ed›eM�d´eeM         �dµeeM         de�e         f�d·„�Z‘deeæeM                  f�d¸„�Z’deMd�d¹f�dº„�Z“�d»esddPf�d¼„�Z”�dó�d¾„�Z•dd�l–�Z—�d¿„ �a˜�e—�j™        e„�dÀ<   d�dÁœ�dÂes�d¦eM�dÃeRdeMf�dÄ„�Zš�dÂesdeQf�dÅ„�Z›�dÂesdeQf�dÆ„�Zœ�dÇes�dÈesdesf�dÉ„�Z��dô�dÌ„�Zž�dÍ�ZŸ�dÎeRdeRf�dÏ„�Z  G �dÐ„ �dÑ¦  «        �Z¡ G �dÒ„ �dÓ�e8�e:�e<¦  «        �Z¢�dÔ�dÕœ�dÖe�j€        dIe�j£        �d£eNddf�d×„�Z¤�dõ�dÖe�j€        �dÙeRf�dÚ„�Z¥�dõ�dÖe�j€        �dÙeRf�dÛ„�Z¦�dÜ�Z§�dÝ�Z¨	 �dö�dßee�j©                 dëeN�dàeNdeQf�dá„�Zª�dâe ddf�dã„�Z«�d÷d™e�e         �däeQ�dåeeR         deQf�dæ„�Z¬�dç„ �Z­�dèeRddf�dé„�Z®�e�dêk    r �e­¦   «          dS dS (ø  a<  
Gateway runner - entry point for messaging platform integrations.

This module provides:
- start_gateway(): Start all configured platform adapters
- GatewayRunner: Main class managing the gateway lifecycle

Usage:
    # Start the gateway
    python -m gateway.run
    
    # Or from CLI
    python cli.py --gateway
é    N)ÚOrderedDict)Úcopy_context©ÚPath)Údatetime)	Ú	AwaitableÚCallableÚDictÚOptionalÚAnyÚListÚTupleÚUnionÚcast)Úconsume_detached_task_resultÚsafe_schedule_threadsafe)ÚCOMPACTION_STATUSÚ1COMPRESSION_RETRY_CONTEXT_REDUCED_STATUS_TEMPLATEÚ*COMPRESSION_RETRY_MESSAGES_STATUS_TEMPLATEÚ(COMPRESSION_RETRY_TOKENS_STATUS_TEMPLATEÚ+COMPRESSION_RETRY_TOO_LARGE_STATUS_TEMPLATEÚIDLE_COMPACTION_STATUS_TEMPLATEÚ#PRE_API_COMPRESSION_STATUS_TEMPLATEÚ%PREFLIGHT_COMPRESSION_STATUS_TEMPLATE)Ú"INTERRUPT_WAITING_FOR_MODEL_PREFIX)Út)Úrequest_hard_interrupt©Úcompression_made_progress)Ú_is_ssh_remote_tilde_cwdÚcfg_get)Úget_fallback_chainé€   ç      ¬@ç      >@g     €f@ç      @g      .@i   z'(?<![\w:/])/([A-Za-z0-9][A-Za-z0-9_-]*)Úgateway_hygieneuC  (auxiliary\s+.+\s+failed|compression\s+summary\s+failed|fallback\s+context\s+marker|configured\s+compression\s+model\s+.+\s+failed|no\s+auxiliary\s+llm\s+provider\s+configured|auto-lowered\s+compression\s+threshold|auto-lowered\s+(?:this\s+)?session'?s?\s+threshold|configured\s+auxiliary\s+compression\s+provider\s+.+\s+unavailable|skipping\s+concurrent\s+compression|compacting\s+context\s+[â€”-]\s+summarizing\s+earlier\s+conversation|resumed\s+after\s+\d+s\s+idle\s+[â€”-]\s+compacting|preflight\s+compression|pre[- ]api\s+compression|context\s+too\s+large\s+\(~[\d,]+\s+tokens\)\s+[â€”-]+\s+compressing|compressed\s+\d[\d,]*\s+(?:â†’|->)\s+\d[\d,]*\s+messages,\s+retrying|compressed\s+~[\d,]+\s+(?:â†’|->)\s+~[\d,]+\s+tokens,\s+retrying|context\s+reduced\s+to\s+[\d,]+\s+tokens\s+\(was\s+[\d,]+\),\s+retrying|session\s+compressed\s+\d+\s+times|rate\s+limited\.\s+waiting\s+\d|retrying\s+in\s+\d|max\s+retries\s+\(\d+\).*(?:trying\s+fallback|exhausted|invalid\s+responses)|stream\s+(?:drop|drop\s+mid\s+tool-call).+retry\s+\d|stale\s+connections\s+from\s+a\s+previous\s+provider\s+issue))é   é   é	   Úsession_keyÚbase_cooldown_secondsÚreturnc                 ó`  — d}	 |                       |¦  «        j        }|xj        dz  c_        |j        }n2# t          $ r%}t                               d|¦  «         Y d}~nd}~ww xY wt          t          |t          t          ¦  «        ¦  «        dz
           }t          ||z  t          ¦  «        S )uí  Bump the hygiene failure streak and return the escalated cooldown.

    This is a MULTIPLIER ladder (x1, x3, x9) over the operator's configured
    ``hygiene_failure_cooldown_seconds``, clamped to
    ``_HYGIENE_COOLDOWN_MAX_SECONDS``, so a tuned base is preserved as rung 1.

    It exists because the in-agent equivalent is unreachable from here:
    ``ContextCompressor.record_timeout_failure`` escalates on an absolute
    60 -> 300 -> 900s ladder driven by the in-memory
    ``_consecutive_timeout_failures`` counter, which ``bind_session_state``
    zeroes.  Session hygiene constructs a FRESH ``AIAgent`` per run and re-binds
    state every time, so from the gateway that streak is structurally always 0
    and only the flat ``hygiene_failure_cooldown_seconds`` could ever be
    recorded â€” a session whose summary model always times out retried on that
    same fixed interval forever (#79624).  Keeping the streak on
    ``PersistentState`` outlives the per-run agent, so failures climb.
    r(   z(hygiene failure streak update failed: %sN)
Ú_session_stateÚ
persistentÚhygiene_failure_streakÚ	ExceptionÚloggerÚdebugÚ$_HYGIENE_COOLDOWN_LADDER_MULTIPLIERSÚminÚlenÚ_HYGIENE_COOLDOWN_MAX_SECONDS)Úgatewayr+   r,   ÚstreakÚstateÚexcÚ
multipliers          ú1/home/ragecks/.hermes/hermes-agent/gateway/run.pyÚ_hygiene_cooldown_for_failurer?   �   sÌ   € ð, €FðFØ×&Ò& {Ñ3Ô3Ô>ˆØÐ$Ô$¨Ñ)Ð$Ô$ØÔ-ˆˆøÝð Fð Fð Fõ 	�ŠÐ?ÀÑEÔEÐEÐEÐEÐEÐEÐEøøøøð	Føøøõ
 6ÝˆF•CÕ<Ñ=Ô=Ñ>Ô>ÀÑBô€Jõ Ð$ zÑ1Õ3PÑQÔQÐQs   „16 ¶
A%Á A Á A%c                 ó¸   — 	 |                       |¦  «        }|�d|j        _        dS dS # t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w)zÞClear the hygiene failure streak after a compression that reduced context.

    Peeks rather than get-or-creates: writing a 0 that is already 0 must not
    materialise a ``_sessions`` entry (those are never evicted).
    Nr   z'hygiene failure streak reset failed: %s)Ú_peek_session_stater0   r1   r2   r3   r4   )r9   r+   r;   r<   s       r>   Ú_reset_hygiene_failure_streakrB   ³   s„   € ðEØ×+Ò+¨KÑ8Ô8ˆØÐØ67ˆEÔÔ3Ð3Ð3ð Ðøåð Eð Eð EÝ�ŠÐ>ÀÑDÔDÐDÐDÐDÐDÐDÐDÐDøøøøðEøøøs   ‚#) ©
A³AÁAÚabortedÚrotatedÚin_placeÚ	msg_countÚ	new_countÚapprox_tokensÚ
new_tokensc                 ó:   — | rdS |s|sdS t          ||||¦  «        S )u  True when a hygiene run actually recovered the session.

    Extracted from ``_handle_message_with_agent`` so the decision is unit
    testable: it previously lived inline in a ~2000-line async method, and the
    only way to pin it was a source-reading test â€” which AGENTS.md bans
    outright, naming this file.

    "Recovered" requires all three:

    * the compressor did not abort (no summary produced at all);
    * the transcript was actually rewritten â€” either rotated into a new session
      or compacted in place.  The degenerate "did not rotate or compact in
      place" path (#21301) reuses the pre-compression counts, so relying on the
      numbers alone would read a no-op as success;
    * the request materially shrank, per the canonical
      :func:`compression_made_progress` (#39548) â€” a row-count drop counts even
      when the summary keeps the token estimate flat, and a sub-5% token wobble
      does not count at all.

    The token arguments are deliberately compared through that shared predicate
    rather than with a bare ``<``: ``approx_tokens`` can be provider-reported
    while ``new_tokens`` is always a rough estimate (documented to run 30-50%
    high on code-heavy sessions), so a bare comparison both misses real wins and
    counts noise as one.
    Fr   ©rC   rD   rE   rF   rG   rH   rI   s          r>   Úhygiene_compaction_recoveredrL   Á   sA   € ðF ð ØˆuØð �xð ØˆuÝ$Ø�9˜m¨Zñô ð ó    Ú
session_idÚcooldown_secondsÚerrorc                 ó0  — ddl }t          | dd¦  «        }|€dS t          |d|¦  «        }t          |dd¦  «        }|€dS 	  |||                      ¦   «         |z   |¦  «         dS # t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w)u·  Persist a session-hygiene compression-failure cooldown to the state DB.

    Uses the same ``compression_failure_cooldown_until`` column and
    ``record_compression_failure_cooldown`` method that the in-conversation
    compression path (``agent/context_compressor.py``) already uses, so the
    cooldown survives gateway restarts (#74136).

    ``error`` is forwarded because the recorder writes
    ``compression_failure_error`` UNCONDITIONALLY â€” omitting it clobbers to NULL
    any reason the in-conversation path recorded, and readers surface that
    reason to the user (falling back to "unknown error"). That matters more now
    that an escalated cooldown can last up to an hour.
    r   NÚ_session_dbÚ_dbÚ#record_compression_failure_cooldownz+session hygiene cooldown persist failed: %s)ÚtimeÚgetattrr2   r3   r4   )r9   rN   rO   rP   Ú_timeÚ
session_dbÚrecorderr<   s           r>   Ú_record_hygiene_cooldownrZ   í   sÒ   € ð& ÐÐÐÝ˜ -°Ñ6Ô6€JØÐØˆÝ˜ U¨JÑ7Ô7€JÝ�zÐ#HÈ$ÑOÔO€HØÐØˆðIØˆ�˜UŸZšZ™\œ\Ð,<Ñ<¸eÑDÔDÐDÐDÐDøÝð Ið Ið IÝ�ŠÐBÀCÑHÔHÐHÐHÐHÐHÐHÐHÐHøøøøðIøøøs   Á"A% Á%
BÁ/BÂBÚtemplatec                 ój   — t          j        d| ¦  «        }d                     d„ |D ¦   «         ¦  «        S )u¦  Compile a compression status template constant into a regex source.

    Literal text is escaped verbatim (so wording drift in
    agent/conversation_compression.py cannot silently diverge from this
    matcher â€” the constants ARE the wording) and each ``{field}`` format
    placeholder is replaced with a numeric-ish pattern covering every value
    the emit sites format in (ints, ``{:,}`` thousands separators).
    z
\{[^{}]*\}z[\d,]+c              3   ó>   K  — | ]}t          j        |¦  «        V — Œd S ©N)ÚreÚescape©Ú.0Úparts     r>   ú	<genexpr>z,_status_template_to_regex.<locals>.<genexpr>  s*   è è € Ð<Ð<¨d�"œ) D™/œ/Ð<Ð<Ð<Ð<Ð<Ð<rM   )r_   ÚsplitÚjoin)r[   Úpartss     r>   Ú_status_template_to_regexrh     s6   € õ ŒH�] HÑ-Ô-€EØ�>Š>Ð<Ð<°eÐ<Ñ<Ô<Ñ<Ô<Ð<rM   Ú|c              #   ó4   K  — | ]}t          |¦  «        V — Œd S r^   )rh   )rb   Ú	_templates     r>   rd   rd   %  s>   è è € ð ð àõ 	" )Ñ,Ô,ðð ð ð ð ð rM   c                  óZ  — 	 t          ¦   «         } t          | t          ¦  «        r|                      d¦  «        nd}t          |t          ¦  «        rIt	          |                     dd¦  «        ¦  «                             ¦   «                              ¦   «         dv S n# t          $ r Y nw xY wdS )u¸  True when the user opted into routine compression progress notices.

    Reads ``compression.progress_notices`` from the gateway's raw YAML config
    (#52995). Default False â€” routine compression stays silent-by-design on
    chat platforms unless explicitly enabled. Read live (mtime-cached) so a
    config edit on a running gateway takes effect on the next status.
    Fail-closed: any config read error keeps the silent default.
    ÚcompressionNÚprogress_noticesF>   Ú1ÚonÚyesÚtrue)Ú_load_gateway_configÚ
isinstanceÚdictÚgetÚstrÚstripÚlowerr2   )ÚconfigÚcompression_cfgs     r>   Ú-_gateway_compression_progress_notices_enabledr|   6  sº   € ðÝ%Ñ'Ô'ˆÝ7AÀ&Í$Ñ7OÔ7OÐY˜&Ÿ*š* ]Ñ3Ô3Ð3ÐUYˆÝ�o¥tÑ,Ô,ð 	Ý�×*Ò*Ð+=¸uÑEÔEÑFÔF×LÒLÑNÔN×TÒTÑVÔVð [ð ð ð	øõ ð ð ð Øˆðøøøàˆ5s   ‚BB Â
B(Â'B(>   ÚlocalÚwebhookÚ
api_serverÚmsgraph_webhookÚplatformc                 ó.   — t          | ¦  «        t          v S )zBTrue only for programmatic/local surfaces that must keep raw text.)Ú_gateway_platform_valueÚ_GATEWAY_RAW_TEXT_PLATFORMS©r�   s    r>   Ú _gateway_surface_passes_raw_textr†   X  s   € å" 8Ñ,Ô,Õ0KÐKÐKrM   zÆ(api\s+(?:call\s+)?failed|provider\s+authentication\s+failed|non-retryable\s+error|rate\s+limited\s+after\s+\d+\s+retries|error\s+code\s*:|\bhttp\s*\d{3}\b|incorrect\s+api\s+key|invalid\s+api\s+key)zÀ(cybersecurity\s+risk|security\s+policy|safety\s+policy|policy\s+violation|violat(?:e|es|ed|ion)|blocked\s+(?:because|by|under)|request\s+(?:was\s+)?(?:blocked|rejected)|disallowed|moderation)zV(provider\s+authentication\s+failed|incorrect\s+api\s+key|invalid\s+api\s+key|\b401\b)z7(rate\s+limit|rate-limited|\b429\b|quota|usage\s+limit)z%\bsk-[A-Za-z0-9][A-Za-z0-9_\-]{12,}\bz\bgh[pousr]_[A-Za-z0-9_]{20,}\bz\bxapp-\d+-[A-Za-z0-9\-]{20,}\bz!\bxox[baprs]-[A-Za-z0-9\-]{20,}\bz\bhf_[A-Za-z0-9]{20,}\bz\bglpat-[A-Za-z0-9_\-]{20,}\bz'(?i)\b(Bearer\s+)[A-Za-z0-9._\-]{20,}\bc                  ó‚  — t           j        dk    rdS t          t          ¦  «                             ¦   «         j        j        } g }t          j                             d¦  «        r2| 	                    t          t          j        d         ¦  «        ¦  «         | 	                    | dz  ¦  «         t          ¦   «         }|D �]ÿ}	 |                     ¦   «         }n# t          $ r |}Y nw xY wt          |¦  «                             ¦   «         }||v rŒQ|                     |¦  «         |dz  dz  }|                     ¦   «         sŒƒt          | ¦  «        }t          |¦  «        }|t           j        vr t           j                             d|¦  «         t%          j        |¦  «         |t           j        v rt           j                             |¦  «         t           j        rt           j        d         |k    rdnd}	t           j                             |	|¦  «         t          |¦  «        t          j        d<   ||g}
t          j                             d	¦  «        r%|
 	                    t          j        d	         ¦  «         t          j                             t.                               |
¦  «        ¦  «        t          j        d	<    dS dS )
a  Make detached Windows gateway runs see the Hermes venv packages.

    Some Windows restart paths run the gateway under uv's base ``pythonw.exe``
    to avoid the venv launcher respawning a visible console interpreter.  That
    mode can import the source tree via cwd/PYTHONPATH but still miss optional
    packages installed only in ``venv/Lib/site-packages`` (notably the MCP SDK).
    Patch the live process before MCP discovery so tool injection does not
    depend on every launcher preserving PYTHONPATH perfectly.
    Úwin32NÚVIRTUAL_ENVÚvenvÚLibúsite-packagesr   r(   Ú
PYTHONPATH)Úsysr�   r   Ú__file__ÚresolveÚparentÚosÚenvironrv   ÚappendÚsetÚOSErrorrw   ry   ÚaddÚexistsÚpathÚinsertÚsiteÚ
addsitedirÚremoveÚpathseprf   ru   Úfromkeys)Úproject_rootÚ
candidatesÚseenÚvenv_dirÚresolved_venvÚvenv_keyÚsite_packagesÚproject_entryÚ
site_entryÚ	insert_atÚ
pythonpaths              r>   Ú$_ensure_windows_gateway_venv_importsr«   �  si  € õ „|�wÒÐØˆå�‘>”>×)Ò)Ñ+Ô+Ô2Ô9€LØ€JÝ	„z‡~‚~�mÑ$Ô$ð ;Ø×Ò�$�rœz¨-Ô8Ñ9Ô9Ñ:Ô:Ð:Ø×Ò�l VÑ+Ñ,Ô,Ð,å‘U”U€DØð ñ ˆð	%Ø$×,Ò,Ñ.Ô.ˆMˆMøÝð 	%ð 	%ð 	%Ø$ˆMˆMˆMð	%øøøå�}Ñ%Ô%×+Ò+Ñ-Ô-ˆØ�tÐÐØØ�Š�ÑÔÐà%¨Ñ-°Ñ?ˆØ×#Ò#Ñ%Ô%ð 	Øå˜LÑ)Ô)ˆÝ˜Ñ'Ô'ˆ
Ø¥¤Ð(Ð(ÝŒH�OŠO˜A˜}Ñ-Ô-Ð-õ 	Œ˜
Ñ#Ô#Ð#Ø�œÐ!Ð!ÝŒH�OŠO˜JÑ'Ô'Ð'ÝœÐI¥c¤h¨q¤k°]Ò&BÐ&B�A�AÈˆ	ÝŒ�Š˜	 :Ñ.Ô.Ð.å$'¨Ñ$6Ô$6�Œ
�=Ñ!Ø# ZÐ0ˆ
ÝŒ:�>Š>˜,Ñ'Ô'ð 	8Ø×Ò�bœj¨Ô6Ñ7Ô7Ð7Ý#%¤:§?¢?µ4·=²=ÀÑ3LÔ3LÑ#MÔ#M�Œ
�<Ñ Øˆˆð?ð s   ÃCÃC&Ã%C&c                 óŠ   — t          t          | d| ¦  «        pd¦  «                             ¦   «                              ¦   «         S )zDReturn a normalized gateway platform value for enums or raw strings.ÚvalueÚ )rw   rV   rx   ry   r…   s    r>   rƒ   rƒ   Å  s9   € å�w�x ¨(Ñ3Ô3Ð9°rÑ:Ô:×@Ò@ÑBÔB×HÒHÑJÔJÐJrM   r…   Úmetadatac                ó\   — t          |¦  «        dk    r| S t          | pi ¦  «        }d|d<   |S )zEMark Discord lifecycle/status sends without changing other platforms.ÚdiscordTÚnon_conversational)rƒ   ru   )r¯   r�   Úmergeds      r>   Ú_non_conversational_metadatar´   Ê  s=   € õ ˜xÑ(Ô(¨IÒ5Ð5ØˆÝ�(�.˜bÑ!Ô!€FØ#'€FÐÑ Ø€MrM   ÚagentÚsession_rowc                 óÜ   — d}t          |t          ¦  «        r@|                     d¦  «        }t          |t          ¦  «        r|                     ¦   «         r|}|| _        t          |¦  «        S )a]  Keep gateway hygiene from rebuilding a live session's system prompt.

    The hygiene helper intentionally skips memory-provider initialization.
    Compression is allowed to persist a system prompt, so letting that helper
    rebuild one would strip external provider blocks from the live session.
    Seed the exact persisted prompt instead.  When no usable prompt can be
    restored, seed an empty cache entry.  Compression either preserves that
    unusable value or rebuilds with the hygiene-only platform marker; the real
    turn will rebuild either form with its fully initialized providers.
    r®   Úsystem_prompt)rt   ru   rv   rw   rx   Ú_cached_system_promptÚbool)rµ   r¶   Ústored_promptÚ
raw_prompts       r>   Ú_seed_hygiene_system_promptr½   ×  sl   € ð €MÝ�+�tÑ$Ô$ð 'Ø —_’_ _Ñ5Ô5ˆ
Ý�j¥#Ñ&Ô&ð 	'¨:×+;Ò+;Ñ+=Ô+=ð 	'Ø&ˆMà"/€EÔÝ�ÑÔÐrM   r<   c                 óþ   — t          ¦   «         }| }d}h d£}|�d|dk     r^t          |¦  «        }||v rnJ|                     |¦  «         |dz  }t          |¦  «        j        }||v rdS |j        p|j        }|�|dk     °^dS )uh  Return True for transient network errors safe to log + swallow.

    The crash class targeted by #31066 / #31110: an unhandled Telegram
    ``TimedOut`` (or peer ``NetworkError`` / ``httpx`` connection error)
    propagating to the event loop and killing the entire gateway
    process. These are by definition transient â€” the next poll cycle or
    user action recovers â€” so they must never crash the process.

    Walk the exception cause chain so wrapped errors (e.g. PTB's
    ``NetworkError`` wrapping ``httpx.ConnectError``) are still
    classified. The chain is bounded to avoid pathological cycles.
    r   >   ÚTimedOutÚ	ReadErrorÚ
WriteErrorÚPoolTimeoutÚReadTimeoutÚConnectErrorÚNetworkErrorÚWriteTimeoutÚClientOSErrorÚConnectTimeoutÚRemoteProtocolErrorÚClientConnectorErrorÚServerDisconnectedErrorNé   r(   TF)r•   Úidr—   ÚtypeÚ__name__Ú	__cause__Ú__context__)r<   r¢   ÚcurÚdepthÚtransient_class_namesÚidentÚnames          r>   Ú_is_transient_network_errorr×   ï  sª   € õ ‘U”U€DØ#&€CØ€Eðð ð Ðð ˆ/˜e bšj˜jÝ�3‘”ˆØ�Dˆ=ˆ=ØØ�Š�‰ŒˆØ�‰
ˆÝ�C‰yŒyÔ!ˆØÐ(Ð(Ð(Ø�4ØŒmÐ.˜sœˆð ˆ/˜e bšj˜jð ˆ5rM   Úloopzasyncio.AbstractEventLoopÚcontextc           	      ó  — |                      d¦  «        }|�Ût          |¦  «        rÌ|                      d¦  «        p|                      d¦  «        }d}|�T	 t          |d¦  «        r|                     ¦   «         nt	          |¦  «        }n# t
          $ r t	          |¦  «        }Y nw xY wt                               d|pdt          |¦  «        j	        |t          |¦  «        ||j
        f¬	¦  «         dS |                      |¦  «         dS )
aË  Loop-level safety net for transient network errors.

    Installed once during :func:`start_gateway`. Catches the
    ``telegram.error.TimedOut`` crash class (issues #31066 / #31110)
    and any peer transient network error before it can kill the
    gateway process. Logs at WARNING with full traceback so the
    originating call site stays diagnosable; non-transient errors
    are forwarded to the default loop handler so real bugs still
    surface.
    Ú	exceptionNÚfutureÚtaskr®   Úget_namez9Gateway swallowed transient network error from %s: %s: %sz<unknown task>©Úexc_info)rv   r×   ÚhasattrrÞ   Úreprr2   r3   ÚwarningrÎ   rÏ   Ú__traceback__Údefault_exception_handler)rØ   rÙ   r<   rÝ   Ú	task_names        r>   Ú_gateway_loop_exception_handlerrç     s  € ð �+Š+�kÑ
"Ô
"€CØ
€Õ6°sÑ;Ô;€Ø�{Š{˜8Ñ$Ô$Ð;¨¯ª°FÑ(;Ô(;ˆØˆ	ØÐð'Ý/6°t¸ZÑ/HÔ/HÐX˜DŸMšM™OœO˜OÍdÐSWÉjÌj�	�	øÝð 'ð 'ð 'Ý  ™JœJ�	�	�	ð'øøøå�ŠØGØÐ)Ð)Ý�‰IŒIÔØÝ˜3‘i”i  cÔ&7Ð8ð 	ñ 	
ô 	
ð 	
ð 	ˆà×"Ò" 7Ñ+Ô+Ð+Ð+Ð+s   Á3B
 Â
B&Â%B&Útextc                 ó´   — t          | pd¦  «        }	 ddlm}  ||d¬¦  «        }n# t          $ r Y nw xY wt          D ]}|                     d„ |¦  «        }Œ|S )u  Secret redaction before text can leave the gateway.

    Delegates to the authoritative ``agent.redact.redact_sensitive_text`` â€” the
    same Tirith-grade redactor already applied to logs, tool output, and
    approval-command prompts â€” so the outbound chat path masks the full
    credential set the startup banner promises ("chat responses are scrubbed
    before delivery"), not a divergent subset. ``force=True`` honors redaction
    even when ``security.redact_secrets`` is off, matching the
    ``_redact_approval_command`` reasoning (#23810).

    The narrow ``_GATEWAY_SECRET_PATTERNS`` set runs as a belt-and-suspenders
    second pass so nothing the gateway historically caught can regress, and so
    redaction still degrades gracefully if the import ever fails.
    r®   r   ©Úredact_sensitive_textT©Úforcec                 óD   — | j         r|                      d¦  «        nddz   S )Nr(   r®   z
[REDACTED])Ú	lastindexÚgroup)Úms    r>   ú<lambda>z5_redact_gateway_user_facing_secrets.<locals>.<lambda>V  s    € ¸¼Ð*K¨!¯'ª'°!©*¬*¨*ÈÈ|Ñ)[€ rM   )rw   Úagent.redactrë   r2   Ú_GATEWAY_SECRET_PATTERNSÚsub)rè   Úredactedrë   Úpatterns       r>   Ú#_redact_gateway_user_facing_secretsrø   =  s•   € õ �4�:˜2‰Œ€HðØ6Ð6Ð6Ð6Ð6Ð6à(Ð(¨¸Ð>Ñ>Ô>ˆˆøÝð ð ð ð 	ˆðøøøõ ,ð gð gˆØ—;’;Ð[Ð[Ð]eÑfÔfˆˆØ€Os   “' §
4³4Úcmdz
str | Nonec                 óF   — ddl m}  |t          | pd¦  «        d¬¦  «        S )ug  Redact credentials from a command before it goes into an approval prompt.

    Tirith's *findings* are already redacted, but the gateway approval prompt
    is built from the raw command string, so a credential-shaped value Tirith
    flagged would otherwise be echoed verbatim to the chat platform (#48456).
    Uses ``redact_sensitive_text(force=True)`` â€” the same Tirith-grade redactor
    â€” so the prompt honors redaction even when ``security.redact_secrets`` is
    off. Module-level so the wiring is unit-testable (the call site is a deeply
    nested gateway closure that cannot be driven directly).
    r   rê   r®   Trì   )ró   rë   rw   )rù   rë   s     r>   Ú_redact_approval_commandrû   Z  s6   € ð 3Ð2Ð2Ð2Ð2Ð2à Ð ¥ S Y¨B¡¤°tÐ<Ñ<Ô<Ð<rM   TF©Úallow_permanentÚallow_sessionÚsmart_deniedÚcommandÚdescriptionÚcommand_prefixrý   rþ   rÿ   c                ón  — t          | ¦  «        dk    r| dd…         dz   n| }d}|rd}d|› d�g}|s6|r4|                     d|› d	�¦  «         |r|                     d|› d
�¦  «         |                     d|› d�¦  «         |› d|› d|› d�d                     |dd…         ¦  «        z   d|d         › d�z   S )zHRender the text fallback from approval capabilities, not platform names.éÈ   Nú...u/   âš ï¸� **Dangerous command requires approval:**u;   âš ï¸� **Smart DENY â€” owner override for one operation:**zReply `z&approve` to execute this one operationú`z8approve session` to approve this pattern for the sessionz&approve always` to approve permanentlyzdeny` to cancelz
```
z
```
Reason: ú

ú, éÿÿÿÿz, or ú.)r7   r”   rf   )	r   r  r  rý   rþ   rÿ   Úcmd_previewÚheadingÚchoicess	            r>   Ú_format_exec_approval_fallbackr  j  s!  € õ ,/¨w©<¬<¸#Ò+=Ð+=�'˜$˜3˜$”- %Ñ'Ð'À7€KØ?€GØð PØOˆàO˜ÐOÐOÐOÐP€GØð W˜Mð WØ�ŠØX�ÐXÐXÐXñ	
ô 	
ð 	
ð ð 	WØ�NŠNÐU˜~ÐUÐUÐUÑVÔVÐVØ‡N‚NÐ6�~Ð6Ð6Ð6Ñ7Ô7Ð7àÐHÐH˜;ÐHÐH°{ÐHÐHÐHØ
�)Š)�G˜C˜R˜C”LÑ
!Ô
!ñ	"Ø$:¨G°B¬KÐ$:Ð$:Ð$:ñ	;ðrM   c                 ó´   — t                                | ¦  «        r	 dS t                               | ¦  «        r	 dS t                               | ¦  «        rdS 	 dS )z@Map raw provider/API errors to a short user-safe Telegram reply.uv   âš ï¸� Provider authentication failed. Check the configured credentials; raw provider details are in the gateway logs.uŒ   âš ï¸� The model provider rejected the request. I kept the raw provider error out of chat; check gateway logs for details or try rephrasing.uX   â�±ï¸� The model provider is rate-limiting requests. Please wait a moment and try again.u|   âš ï¸� The model provider failed after retries. I kept raw provider details out of chat; check gateway logs for diagnostics.)Ú_GATEWAY_AUTH_ERROR_REÚsearchÚ_GATEWAY_PROVIDER_POLICY_REÚ_GATEWAY_RATE_LIMIT_RE©rè   s    r>   Ú_gateway_provider_error_replyr  ‡  s}   € å×$Ò$ TÑ*Ô*ð 
ð<ð	
ð 	
õ #×)Ò)¨$Ñ/Ô/ð 
ðSð	
ð 	
õ ×$Ò$ TÑ*Ô*ð jØiÐið	;ðð rM   zÑ^\s*(\W*\s*)?(api\s+(?:call\s+)?failed|provider\s+authentication\s+failed|non-retryable\s+error|rate\s+limited\s+after\s+\d+\s+retries|error\s+code\s*:|http\s*\d{3}\b|incorrect\s+api\s+key|invalid\s+api\s+key)c                 óö   — | sdS t          | ¦  «                             ¦   «         }t          |¦  «        dk    s|                     d¦  «        dk    rdS t	          t
                               |¦  «        ¦  «        S )uI  True when text is infrastructure/provider failure, not normal content.

    Two heuristics combined so the rewrite only fires on actual provider
    error envelopes, not on assistant prose that happens to mention an
    HTTP status code:

    1. The text is short â€” real provider errors are 1â€“3 lines of envelope
       text; assistant answers are usually longer.
    2. AND the error marker appears at the start of the message (optionally
       behind a punctuation/symbol prefix), not buried mid-paragraph in an
       explanation like "HTTP 404 means 'not found' â€” ...".
    Fé�  Ú
é   )rw   rx   r7   Úcountrº   Ú _GATEWAY_PROVIDER_ERROR_SHAPE_REr  )rè   Úbodys     r>   Ú"_looks_like_gateway_provider_errorr  ª  so   € ð ð ØˆuÝˆt‰9Œ9�?Š?ÑÔ€Dõ ˆ4�y„y�3‚€˜$Ÿ*š* TÑ*Ô*¨QÒ.Ð.ØˆuÝÕ0×7Ò7¸Ñ=Ô=Ñ>Ô>Ð>rM   c                 óV  — |s|S t          | ¦  «        r|S ddlm}  |t          |¦  «        ¦  «        }t          |¦  «                             ¦   «                              t          ¦  «        rdS t          t          |¦  «        ¦  «        }t          |¦  «        rt          |¦  «        S |S )a  Sanitize final gateway replies before sending them to chat surfaces.

    Every human-facing chat surface (Telegram, WhatsApp, Discord, Slack,
    Signal, Matrix, plugin platforms, etc.) should receive concise, safe
    provider failure categories with secrets redacted instead of raw HTTP
    bodies, request IDs, leaked credentials, or policy text. Only programmatic
    surfaces in ``_GATEWAY_RAW_TEXT_PLATFORMS`` (CLI/TUI ``local`` diagnostics,
    API JSON, webhook payloads) keep the raw text unchanged.
    r   )Ú_sanitize_surrogatesr®   )
r†   Úagent.message_sanitizationr  rw   rx   Ú
startswithr   rø   r  r  )r�   rè   r  rö   s       r>   Ú _sanitize_gateway_final_responser"  Á  sµ   € ð ð ØˆÝ'¨Ñ1Ô1ð Øˆð @Ð?Ð?Ð?Ð?Ð?àÐ¥ D¡	¤	Ñ*Ô*€Dõ ˆ4�y„y‡‚ÑÔ×#Ò#Õ$FÑGÔGð Øˆrå2µ3°t±9´9Ñ=Ô=€HÝ)¨(Ñ3Ô3ð 7Ý,¨XÑ6Ô6Ð6Ø€OrM   Ú
event_typeÚmessagec                 óX  — t          |pd¦  «                             ¦   «         }|sdS t          | ¦  «        r|S t          |¦  «        }t                               |¦  «        r*t          ¦   «         rt                               |¦  «        sdS t          |¦  «        rt          |¦  «        S |S )zØFilter/sanitize agent status callbacks before platform delivery.

    Local/CLI sessions keep the raw diagnostic stream. Messaging gateway
    surfaces should not receive transient auxiliary/compression chatter.
    r®   N)
rw   rx   r†   rø   Ú_TELEGRAM_NOISY_STATUS_REr  r|   Ú_COMPRESSION_PROGRESS_STATUS_REr  r  )r�   r#  r$  rè   s       r>   Ú_prepare_gateway_status_messager(  è  s¶   € õ ˆwˆ}˜"ÑÔ×#Ò#Ñ%Ô%€DØð ØˆtÝ'¨Ñ1Ô1ð Øˆå.¨tÑ4Ô4€DÝ ×'Ò'¨Ñ-Ô-ð õ :Ñ;Ô;ð	å/×6Ò6°tÑ<Ô<ð	ð �4Ý)¨$Ñ/Ô/ð 3Ý,¨TÑ2Ô2Ð2Ø€KrM   c                 óf   — t          t          | dd¦  «        pd¦  «                             ¦   «         S )uÊ  Render an AgentNotice to a single plaintext line for messaging platforms.

    Messaging has no persistent status bar (unlike the TUI), so a notice is a
    one-shot standalone push. The notice policy already bakes the level glyph
    (âš  / â€¢ / âœ• / âœ“) into the text, and the TUI + CLI REPL render that text
    verbatim â€” so we emit it as-is here too. Prepending a per-level glyph would
    DOUBLE it ("âš  âš  Credits 90% used", "â›” âœ• Credit access paused"). Plaintext
    only â€” no markdown â€” so it renders uniformly across Telegram/Discord/Slack/
    SMS without per-platform escaping. Fail-soft: a malformed/empty notice
    degrades to "" rather than raising on the agent's callback path.
    rè   r®   )rw   rV   rx   )Únotices    r>   Úrender_notice_liner+    s/   € õ �w�v˜v rÑ*Ô*Ð0¨bÑ1Ô1×7Ò7Ñ9Ô9Ð9rM   c              ƒ   ó¬   K  — t          | dd¦  «        }t          |¦  «        r |||||¬¦  «        ƒ d{V —†S |                      |||¬¦  «        ƒ d{V —†S )a5  Route a status message through adapter.send_or_update_status when supported.

    Issue #30045: adapters that implement send_or_update_status (currently
    Telegram) edit the previous bubble for the same status_key instead of
    appending a new one. Adapters without the method fall back to plain send.
    Úsend_or_update_statusN©r¯   )rV   ÚcallableÚsend)ÚadapterÚchat_idÚ
status_keyÚcontentr¯   Úsenders         r>   Ú_send_or_update_status_coror6    s€   è è € õ �WÐ5°tÑ<Ô<€FÝ�ÑÔð MØ�V˜G Z°À8ÐLÑLÔLÐLÐLÐLÐLÐLÐLÐLØ—’˜g w¸�ÑBÔBÐBÐBÐBÐBÐBÐBÐBrM   ©Úreply_in_threadÚsource_thread_idÚevent_message_idr8  c                ó0  — t          | d| ¦  «        }t          |pd¦  «                             ¦   «         }|s9|r$|r"t          |¦  «        t          |¦  «        k    rdS |rt          |¦  «        ndS |rt          |¦  «        S |dv r|rt          |¦  «        S dS )uÈ  Return thread/root ID that progress/status bubbles should target.

    ``reply_in_thread=False`` (Slack ``platforms.slack.extra.reply_in_thread``)
    disables the synthetic-thread fallback: progress messages must not create
    a thread the final flat reply would then inherit. A source.thread_id equal
    to the event's own message id is the adapter's synthetic session-keying
    thread, not a real thread â€” treat it as "no thread" too (#18859).
    r­   r®   N>   ÚslackÚ
mattermost)rV   rw   ry   )r�   r9  r:  r8  Úplatform_valueÚplatform_keys         r>   Ú_resolve_progress_thread_idr@  "  sÆ   € õ ˜X w°Ñ9Ô9€NÝ�~Ð+¨Ñ,Ô,×2Ò2Ñ4Ô4€LØð Càð	à ð	õ Ð$Ñ%Ô%­Ð-=Ñ)>Ô)>Ò>Ð>à�4Ø(8ÐB�sÐ#Ñ$Ô$Ð$¸dÐBØð %ÝÐ#Ñ$Ô$Ð$ØÐ.Ð.Ð.Ð3CÐ.ÝÐ#Ñ$Ô$Ð$Øˆ4rM   Úuser_configr?  Úsettingc                 ó<  — t          | t          ¦  «        r|                      d¦  «        nd}t          |t          ¦  «        sdS |                     d¦  «        }t          |t          ¦  «        sdS |                     |¦  «        }t          |t          ¦  «        o||v S )zFReturn True when display.platforms.<platform> explicitly sets setting.ÚdisplayNFÚ	platforms©rt   ru   rv   )rA  r?  rB  rD  rE  Úplatform_cfgs         r>   Ú_has_platform_display_overriderH  B  s‘   € å,6°{ÅDÑ,IÔ,IÐSˆk�oŠo˜iÑ(Ô(Ð(Èt€GÝ�g�tÑ$Ô$ð ØˆuØ—’˜KÑ(Ô(€IÝ�i¥Ñ&Ô&ð ØˆuØ—=’= Ñ.Ô.€LÝ�l¥DÑ)Ô)ÐE¨g¸Ð.EÐErM   ©Údefaultr�   Úrequire_platform_override_forrJ  rK  c                ó–  — t          |p|¦  «        }d„ |pt          ¦   «         D ¦   «         }||v rt          | ||¦  «        sdS ddlm}  || |||¦  «        }	t          |	t          ¦  «        r|	S t          |	t          ¦  «        r(|	                     ¦   «          	                    ¦   «         dv S |	€t          |¦  «        S t          |	¦  «        S )aj  Resolve a boolean display setting with optional platform-only opt-in.

    Some display features expose assistant scratch text rather than deliberate
    user-facing output.  For high-noise threaded chat surfaces such as
    Mattermost, a global opt-in is too broad: they must be enabled with an
    explicit display.platforms.<platform>.<setting> override.
    c                 ó,   — h | ]}t          |¦  «        ’ŒS © ©rƒ   )rb   Ú	candidates     r>   ú	<setcomp>z0_resolve_gateway_display_bool.<locals>.<setcomp>_  s0   € ð ð ð àõ 	  	Ñ*Ô*ðð ð rM   Fr   ©Úresolve_display_setting>   ro   rp   rq   rr   )
rƒ   r•   rH  Úgateway.display_configrS  rt   rº   rw   rx   ry   )
rA  r?  rB  rJ  r�   rK  Úcurrent_platformÚplatform_onlyrS  r­   s
             r>   Ú_resolve_gateway_display_boolrW  N  sõ   € õ  /¨xÐ/G¸<ÑHÔHÐðð à7Ð@½3¹5¼5ðñ ô €Mð
 	˜MÐ)Ð)Ý.¨{¸LÈ'ÑRÔRð 	*ð ˆuà>Ð>Ð>Ð>Ð>Ð>à#Ð# K°¸wÈÑPÔP€EÝ�%�ÑÔð ØˆÝ�%�ÑÔð CØ�{Š{‰}Œ}×"Ò"Ñ$Ô$Ð(BÐBÐBØ€}Ý�G‰}Œ}ÐÝ�‰;Œ;ÐrM   c                 óÀ   ‡— t          |d|¦  «        }|dk    r| S ddlmŠ dt          j        t
                   dt
          fˆfd„}t                               || ¦  «        S )a%  Rewrite slash-command mentions to Telegram-valid command names.

    Telegram Bot API command names allow only lowercase letters, digits, and
    underscores.  Keep other platform renderings unchanged, but normalize
    Telegram help text so command mentions remain clickable/valid there.
    r­   Útelegramr   )Ú_sanitize_telegram_nameÚmatchr-   c                 óx   •—  ‰|                       d¦  «        ¦  «        }|rd|› �n|                       d¦  «        S )Nr(   ú/r   )rð   )r[  Ú	sanitizedrZ  s     €r>   Ú_replacez/_telegramize_command_mentions.<locals>._replace‚  s<   ø€ Ø+Ð+¨E¯KªK¸©N¬NÑ;Ô;ˆ	Ø"+Ð?ˆ�9ˆˆˆ°·²¸Q±´Ð?rM   )rV   Úhermes_cli.commandsrZ  r_   ÚMatchrw   Ú_TELEGRAM_COMMAND_MENTION_RErõ   )rè   r�   r>  r_  rZ  s       @r>   Ú_telegramize_command_mentionsrc  u  sŠ   ø€ õ ˜X w°Ñ9Ô9€NØ˜Ò#Ð#Øˆà;Ð;Ð;Ð;Ð;Ð;ð@�œ¥œð @­#ð @ð @ð @ð @ð @ð @õ (×+Ò+¨H°dÑ;Ô;Ð;rM   é  r­   c                 óz  — | €dS t          | t          ¦  «        r|                      ¦   «         S t          | t          ¦  «        rdS t          | t          t
          f¦  «        r4t          | ¦  «        dk    rt          | ¦  «        dz  nt          | ¦  «        S t          | t          ¦  «        r‘|                      ¦   «         }|sdS 	 t          |¦  «        }|dk    r|dz  n|S # t          $ r Y nw xY w	 t          j	        | 
                    dd¦  «        ¦  «                             ¦   «         S # t          $ r Y dS w xY wdS )a¢  Best-effort conversion of stored gateway timestamps to epoch seconds.

    Missing/unparseable timestamps return None so legacy transcripts keep the
    historical auto-continue behaviour instead of being silently dropped.
    Accepts: datetime, epoch seconds (int/float), epoch milliseconds (when
    the magnitude exceeds year-2286), ISO-8601 strings (with or without a
    trailing ``Z``), and numeric strings.
    Nl    d(	 g     @�@ÚZz+00:00)rt   r   Ú	timestamprº   ÚintÚfloatrw   rx   Ú
ValueErrorÚfromisoformatÚreplace)r­   rè   Únumerics      r>   Ú_coerce_gateway_timestamprn  ¦  sX  € ð €}ØˆtÝ�%�Ñ"Ô"ð !Ø�ŠÑ Ô Ð Ý�%�ÑÔð ØˆtÝ�%�#�u˜Ñ&Ô&ð Xå(-¨e©¬°~Ò(EÐ(E�u�U‰|Œ|˜fÑ$Ð$Í5ÐQVÉ<Ì<ÐWÝ�%�ÑÔð Ø�{Š{‰}Œ}ˆØð 	Ø�4ð	Ý˜D‘k”kˆGØ'.°Ò'?Ð'?�7˜VÑ#Ð#ÀWÐLøÝð 	ð 	ð 	ØˆDð	øøøð	ÝÔ)¨$¯,ª,°s¸HÑ*EÔ*EÑFÔF×PÒPÑRÔRÐRøÝð 	ð 	ð 	Ø�4�4ð	øøøàˆ4s$   ÃC Ã
C,Ã+C,Ã09D* Ä*
D8Ä7D8c                  ó"   — ddl m}   | ¦   «         S )a÷  Return the configured auto-continue freshness window in seconds.

    Thin wrapper that delegates to the canonical implementation in
    ``gateway.session`` (the single source of truth shared with the
    routing-time zombie gate in ``get_or_create_session``).  Reads
    ``HERMES_AUTO_CONTINUE_FRESHNESS`` (bridged from ``config.yaml``
    ``agent.gateway_auto_continue_freshness`` at gateway startup, same
    pattern as ``HERMES_AGENT_TIMEOUT``).  Falls back to the module default
    when unset or malformed.  Non-positive values disable the freshness gate
    (restores the pre-fix "always fresh" behaviour for users who want to opt
    out).  Kept here so existing call sites and test patches importing it
    from ``gateway.run`` continue to work.
    r   ©Úauto_continue_freshness_window)Úgateway.sessionrq  rp  s    r>   Ú_auto_continue_freshness_windowrs  È  s%   € ð ?Ð>Ð>Ð>Ð>Ð>Ø)Ð)Ñ+Ô+Ð+rM   c                  óî   — t           j                             d¦  «        } | �| dk    rt          t          ¦  «        S 	 t          | ¦  «        S # t
          t          f$ r t          t          ¦  «        cY S w xY w)u8  Max seconds ``_finish_startup_restore`` waits on boot auto-resume turns
    before releasing the inbound gate and draining the queue.

    While startup restore is in progress the gateway QUEUES every inbound
    message (``_queue_startup_restore_event``) instead of processing it, so no
    channel gets a reply until the gate opens.  The gate is opened by
    ``_finish_startup_restore``, which waits for the synthetic boot
    auto-resume turns to finish.  A single long resumed turn therefore held
    the gate shut for every channel â€” inbound piled up unanswered for as long
    as that one turn ran.

    This bounds that wait.  Duplicate-agent safety does NOT depend on the
    wait: ``_schedule_resume_pending_sessions`` claims each session's
    ``_running_agents`` slot SYNCHRONOUSLY (before the gate ever runs), so a
    message drained while a resume turn is still running queues behind that
    slot rather than spawning a second agent.  So on timeout we release the
    gate and let the slow turn finish in the background.

    Reads ``HERMES_STARTUP_RESTORE_DRAIN_TIMEOUT`` (bridged from
    ``config.yaml`` ``agent.gateway_startup_restore_drain_timeout`` at gateway
    startup, same pattern as the other ``agent.*`` knobs).  Non-positive
    disables the bound (restores the historical "wait forever" behaviour).
    Ú$HERMES_STARTUP_RESTORE_DRAIN_TIMEOUTNr®   )r’   r“   rv   ri  Ú+_STARTUP_RESTORE_DRAIN_TIMEOUT_SECS_DEFAULTÚ	TypeErrorrj  )Úraws    r>   Ú#_startup_restore_drain_timeout_secsry  Ú  s   € õ0 Œ*�.Š.Ð?Ñ
@Ô
@€CØ
€{�c˜R’i�iÝÕ@ÑAÔAÐAðBÝ�S‰zŒzÐøÝ•zÐ"ð Bð Bð BÝÕ@ÑAÔAÐAÐAÐAðBøøøs   ½A Á%A4Á3A4Úinfoc                 óÖ   — t          | t          ¦  «        rSt          | ¦  «        dk    r@t          d„ | D ¦   «         ¦  «        r't	          t
          t          t          f         | ¦  «        S dS )zÂ*info* as a (thread_id, initial_name) pair, or None if it isn't one.

    The pair comes back across the relay connector boundary, so its shape is
    the connector's word rather than ours.
    é   c              3   ó@   K  — | ]}t          |t          ¦  «        V — Œd S r^   ©rt   rw   )rb   Úxs     r>   rd   z"_as_thread_info.<locals>.<genexpr>  s-   è è € Ð9[Ð9[ÐQR½*ÀQÍÑ:LÔ:LÐ9[Ð9[Ð9[Ð9[Ð9[Ð9[rM   N)rt   Útupler7   Úallr   r   rw   )rz  s    r>   Ú_as_thread_infor‚  û  s]   € õ �$�ÑÔð +¥3 t¡9¤9°¢> >µcÐ9[Ð9[ÐVZÐ9[Ñ9[Ô9[Ñ6[Ô6[ >Ý•E�#�s˜(”O TÑ*Ô*Ð*Øˆ4rM   rÖ   c                 óÚ   — t           j                             | ¦  «        }|�|dk    rt          |¦  «        S 	 t          |¦  «        S # t          t
          f$ r t          |¦  «        cY S w xY w)zÚRead an env var as float, falling back to ``default`` on typos/empty.

    A misconfigured env var (e.g. ``HERMES_AGENT_TIMEOUT=abc``) must not
    crash the gateway or an agent turn.  Unset/empty also falls back.
    Nr®   )r’   r“   rv   ri  rw  rj  )rÖ   rJ  rx  s      r>   Ú
_float_envr„    ss   € õ Œ*�.Š.˜Ñ
Ô
€CØ
€{�c˜R’i�iÝ�W‰~Œ~ÐðÝ�S‰zŒzÐøÝ•zÐ"ð ð ð Ý�W‰~Œ~ÐÐÐðøøøs   ¸A Á A*Á)A*ÚdescÚ
provenanceÚActivityProvenanceÚdebug_labelc                 ó�   — 	 |                       ||¬¦  «         dS # t          $ r  t                               |d¬¦  «         Y dS w xY w)zJBest-effort activity provenance stamp for hygiene compression transitions.)r†  Trß   N)Ú_touch_activityr2   r3   r4   )rµ   r…  r†  rˆ  s       r>   Ú%_stamp_hygiene_compression_provenancer‹    s`   € ð1Ø×Ò˜d¨zÐÑ:Ô:Ð:Ð:Ð:øÝð 1ð 1ð 1Ý�Š�[¨4ˆÑ0Ô0Ð0Ð0Ð0Ð0ð1øøøs   ‚ ›&AÁA)ÚnowÚwindow_secsrŒ  r�  c                óÂ   — |�t          |¦  «        nt          t          ¦  «        }|dk    rdS t          | ¦  «        }|€dS |€t          j        ¦   «         n|}||z
  |k    S )aÂ  Return True when an interruption marker is fresh enough to auto-continue.

    Unknown timestamps are treated as fresh for backward compatibility with
    legacy transcripts (pre-dating timestamp persistence) and with in-memory
    test scaffolding that constructs history entries without timestamps.

    A non-positive ``window_secs`` disables the gate (always fresh), which
    restores the pre-fix behaviour for users who opt out via config.
    Nr   T)ri  Ú%_AUTO_CONTINUE_FRESHNESS_SECS_DEFAULTrn  rU   )r­   rŒ  r�  Úwindowrg  Úcurrents         r>   Ú_is_fresh_gateway_interruptionr’  "  sv   € ð" Ð"õ 	ˆkÑÔÐåÕ8Ñ9Ô9ð ð
 �‚{€{ØˆtÝ)¨%Ñ0Ô0€IØÐØˆtØ ˜[�dŒi‰kŒkˆk¨c€GØ�YÑ &Ò(Ð(rM   r®   ©ÚinteractiveÚreasonr”  c                óv   — | dk    rdn	| dk    rdnd}|rd}d}n|rd}d}nd	}d
}d|› d|› d|› d�|rd|› �ndz   S )up  Build the resume-pending recovery system note for an interrupted turn.

    ``reason`` is the session's ``resume_reason`` (``restart_timeout``,
    ``shutdown_timeout``, or anything else â†’ generic interruption phrasing).
    ``message`` is the user's NEW message text; empty means this is the
    startup auto-resume turn synthesized by
    ``_schedule_resume_pending_sessions`` with no human message attached.

    ``interactive`` selects the empty-message guidance: on interactive
    platforms a human is present, so "report the restore and ask what next"
    is right.  On non-interactive event platforms (webhook, API server â€”
    adapters with ``interactive_resume = False``) nobody can answer; the
    resumed turn must instead complete the interrupted work, or the task is
    silently abandoned behind a "restored" acknowledgement that goes
    nowhere (#57056).
    Úrestart_timeoutza gateway restartÚshutdown_timeoutza gateway shutdownza gateway interruptionzTAddress the user's NEW message below FIRST and focus on what the user is asking now.u\   Do NOT re-execute old tool calls â€” skip any unfinished work from the conversation history.zfReport to the user that the session was restored successfully and ask what they would like to do next.zËNo user is present on this non-interactive platform, so do NOT emit a 'session restored' acknowledgement or ask questions. Review the conversation history and CONTINUE the interrupted task to completion.u€   Do NOT re-run tool calls whose results already appear in the history â€” resume from the first step that has no recorded result.z3[System note: The previous turn was interrupted by u‚   ; the gateway is now back online. Any restart/shutdown command in the history has already run â€” do NOT re-execute or verify it. Ú Ú]r  r®   rN  )r•  r$  r”  Úreason_phraseÚresume_guidanceÚtail_guidances         r>   Úbuild_resume_recovery_noterž  ?  sã   € ð0 Ð&Ò&Ð&ð 	Ðð Ð'Ò'Ð'ð "Ð!à%ð ð ð 
ð.ð 	ð
=ð 	ˆð 
ð 
ðDð 	ð
=ð 	ˆð;ð 	ð+ð 	ð	Øð	ð 	ð 4Cð	ð 	ð ð		ð 	ð 	ð
  'Ð.Ð�'ÐÐÐ¨Bñ	0ðrM   )Ú	reasoningÚreasoning_contentÚreasoning_detailsÚcodex_reasoning_itemsÚcodex_message_itemsÚfinish_reason.Ú_ASSISTANT_REPLAY_FIELDSÚroler4  ÚmsgÚpreserve_timestampc                 ó`  — | |dœ}|                      d¦  «        }| dv r5t          |t          ¦  «        r |r||                      d¦  «        k    r||d<   | dk    r6t          D ].}||vrŒ|                      |¦  «        }|dk    r|€Œ%n|sŒ)|||<   Œ/|r|                      d¦  «        }|r||d<   |S )	u	  Build a replay entry for a non-tool-calling message, preserving the
    assistant fields the agent's API builders rely on for multi-turn fidelity.

    Lifted out of the inline ``run_sync`` closure so the field whitelist can
    be unit-tested in isolation.  Mirrors the ``_ASSISTANT_REPLAY_FIELDS``
    contract above.

    ``preserve_timestamp``: when True, copy the source row's ``timestamp``
    onto the replay entry. Currently only user messages need this â€” the
    stale-dangerous-confirmation stripper in ``agent/replay_cleanup.py``
    reads the timestamp to decide whether a confirmation is too old to
    replay safely.  Assistant/tool messages are not timestamp-stripped in
    the same way, so we keep the existing default of dropping it.

    Empty values: most fields are dropped when falsy (matching the original
    PR #2974 behaviour) since an empty list/string for those carries no
    information.  The exception is ``reasoning_content``: DeepSeek/Kimi
    thinking-mode replay treats an empty string as a meaningful sentinel
    that ``_copy_reasoning_content_for_api`` upgrades to a single space.
    Dropping it here would make the gateway send no ``reasoning_content``
    at all on the next turn, which can cause HTTP 400 from strict thinking
    providers.
    ©r¦  r4  Úapi_content)ÚuserÚ	assistantr4  r­  r   Nrg  )rv   rt   rw   r¥  )	r¦  r4  r§  r¨  ÚentryÚ_sidecarÚ_rkeyÚ_rvalÚtss	            r>   Ú_build_replay_entryr³  ª  s  € ð: &*°gÐ>Ð>€Eð �wŠw�}Ñ%Ô%€HàÐ%Ð%Ð%Ý�x¥Ñ%Ô%ð 	&àð 	&ð �s—w’w˜yÑ)Ô)Ò)Ð)à'ˆˆmÑØˆ{ÒÐÝ-ð 
	!ð 
	!ˆEØ˜CÐÐØØ—G’G˜E‘N”NˆEØÐ+Ò+Ð+à�=Øð !àð ØØ ˆE�%‰LˆLØð $Ø�WŠW�[Ñ!Ô!ˆØð 	$Ø!#ˆE�+ÑØ€LrM   zobserved Telegram group contextz>[Observed Telegram group context - context only, not requests]zh[Current addressed message - answer only this unless it explicitly asks you to use the observed context]Úchannel_promptc                 ó2   — t          | ot          | v ¦  «        S )aé  Return True for Telegram group turns that may include observed chatter.

    Telegram's observe-unmentioned mode persists skipped group chatter so a
    later @mention can see it. Those rows must not replay as ordinary user
    turns: a weak wake word like ``@bot cambio`` should not make the model treat
    old unmentioned chatter as pending work. The Telegram adapter marks these
    turns with a channel prompt; this helper keeps the run-path check explicit
    and unit-testable.
    )rº   Ú(_TELEGRAM_OBSERVED_CONTEXT_PROMPT_MARKER)r´  s    r>   Ú%_uses_telegram_observed_group_contextr·  ñ  s   € õ �Ð]Õ#KÈ~Ð#]Ñ^Ô^Ð^rM   rx  c                 ó  — | €t          ¦   «         S t          | t          ¦  «        rd„ | D ¦   «         S t          | ¦  «                             ¦   «         }|st          ¦   «         S d„ |                     d¦  «        D ¦   «         S )zDNormalize a config list or comma-separated scalar into a string set.Nc                 ó’   — h | ]D}t          |¦  «                             ¦   «         ¯#t          |¦  «                             ¦   «         ’ŒES rN  )rw   rx   ra   s     r>   rQ  z&_csv_or_list_to_set.<locals>.<setcomp>  s=   € ÐGÐGÐG dµS¸±Y´Y·_²_Ñ5FÔ5FÐG•�D‘	”	—’Ñ!Ô!ÐGÐGÐGrM   c                 ó^   — h | ]*}|                      ¦   «         ¯|                      ¦   «         ’Œ+S rN  ©rx   ra   s     r>   rQ  z&_csv_or_list_to_set.<locals>.<setcomp>  s-   € ÐBÐBÐB˜T°T·Z²Z±\´\ÐBˆD�JŠJ‰LŒLÐBÐBÐBrM   Ú,)r•   rt   Úlistrw   rx   re   )rx  Úss     r>   Ú_csv_or_list_to_setr¿  ÿ  s{   € à
€{Ý‰uŒuˆÝ�#•tÑÔð HØGÐG¨cÐGÑGÔGÐGÝˆC‰Œ�ŠÑÔ€AØð Ý‰uŒuˆØBÐB Q§W¢W¨S¡\¤\ÐBÑBÔBÐBrM   rz   c                 óü   — t          | di ¦  «                             t          j        ¦  «        }d}|�$t          |di ¦  «                             d¦  «        }|€t	          j        d¦  «        pd}t          |¦  «        S )a®  Return Slack channels that the generic gateway must never dispatch.

    The Slack adapter has the first-line drop, but this runner-level guard is
    intentionally duplicated as a fail-safe. If a future Slack code path, test
    hook, malformed event, or stale adapter instance bypasses the Slack plugin
    adapter, ignored channels still cannot reach auth, pairing, sessions, or
    the agent/home-channel prompt pipeline.
    rE  NÚextraÚignored_channelsÚSLACK_IGNORED_CHANNELS)rV   rv   ÚPlatformÚSLACKr’   Úgetenvr¿  )rz   rG  rx  s      r>   Ú+_slack_ignored_channels_from_gateway_configrÇ    sz   € õ ˜6 ;°Ñ3Ô3×7Ò7½¼ÑGÔG€LØ
€CØÐÝ�l G¨RÑ0Ô0×4Ò4Ð5GÑHÔHˆØ
€{õ ŒiÐ0Ñ1Ô1Ð9°TˆÝ˜sÑ#Ô#Ð#rM   r2  c                 ó\   — | sdS t          | ¦  «                             dd¦  «        d         S )zFReturn the parent Slack channel from a possibly thread-scoped chat ID.r®   ú:r(   r   )rw   re   ©r2  s    r>   Ú_slack_parent_channel_idrË     s0   € àð ØˆrÝˆw‰<Œ<×Ò˜c 1Ñ%Ô% aÔ(Ð(rM   c                 ól   — t          |¦  «        }t          | ¦  «        }t          |od|v p||v ¦  «        S )zDCheck the generic Slack gateway blacklist for channel or thread IDs.Ú*)rË  rÇ  rº   )rz   r2  Ú
channel_idÚignoreds       r>   Ú_is_slack_ignored_channelrÐ  '  s=   € å)¨'Ñ2Ô2€JÝ9¸&ÑAÔA€GÝ�
ÐH  w Ð G°*ÀÐ2GÑIÔIÐIrM   c                 ó@  — t          | t          ¦  «        sdS |                      d¦  «        }t          |t          ¦  «        sdS |                     d¦  «        }t          |t          ¦  «        r#t          |                     dd¦  «        ¦  «        S t          |¦  «        S )a;  True when gateway.message_timestamps.enabled is opted in.

    Default OFF: injecting a ``[Tue 2026-04-28 13:40:53 CEST]`` prefix onto
    every user message changes what the model sees for all gateway users, so
    it must be explicitly enabled in config.yaml under
    ``gateway.message_timestamps.enabled``.
    Fr9   Úmessage_timestampsÚenabled)rt   ru   rv   rº   )rA  ÚgwÚmts      r>   Ú_message_timestamps_enabledrÖ  .  sŽ   € õ �k¥4Ñ(Ô(ð ØˆuØ	�Š˜Ñ	#Ô	#€BÝ�b�$ÑÔð ØˆuØ	�ŠÐ$Ñ	%Ô	%€BÝ�"•dÑÔð .Ý�B—F’F˜9 eÑ,Ô,Ñ-Ô-Ð-å�‰8Œ8€OrM   ©r´  Úinject_timestampsÚhistoryrØ  c                ó\  — ddl m} ddlm}  |¦   «         }g }g }t	          |¦  «        }| pg D �]‘}	|	                     d¦  «        }
|
sŒ|
dv rŒ |
dk    rŒ'|	                     d¦  «        }|r<|
dk    r6t          |t          ¦  «        r! |||	                     d	¦  «        |¬
¦  «        }|rR|	                     d¦  «        r=|
dk    r7|r5|                     t          |¦  «         	                    ¦   «         ¦  «         ŒÎd|	v }d|	v }|
dk    }|s|s|r5d„ |	 
                    ¦   «         D ¦   «         }|                     |¦  «         �Œ|rx|
dk    rt          |¦  «        }|s�Œ2|	                     d¦  «        r|	                     dd¦  «        }d|› d|› �}t          |
||	|
dk    ¬¦  «        }|                     |¦  «         �Œ“t          |¦  «        }t          |¦  «        }t          |t!          j        ¦   «         ¬¦  «        }d                     |¦  «         	                    ¦   «         pd}||fS )a�  Convert stored gateway transcript rows into agent replay messages.

    Observed Telegram group rows are returned as API-only context for the
    current addressed message instead of being replayed as normal prior user
    turns.  Keeping that context out of ``conversation_history`` avoids
    consecutive-user repair merging it with the live user turn and then hiding
    the current message behind ``history_offset`` during persistence.

    When ``inject_timestamps`` is True (gateway.message_timestamps.enabled),
    each replayed user message is rendered with a single human-readable
    timestamp prefix from its stored metadata.
    r   ©Úget_timezone)Ú"render_user_content_with_timestampr¦  >   Úsession_metaÚsystemr4  r¬  rg  ©ÚtzÚobservedÚ
tool_callsÚtool_call_idÚtoolc                 ó"   — i | ]\  }}|d v¯	||“ŒS )>   râ  rg  rN  ©rb   ÚkÚvs      r>   ú
<dictcomp>z0_build_gateway_agent_history.<locals>.<dictcomp>{  s)   € Ð\Ð\Ð\¡$ ! Q¸ÐB[Ð9[Ð9[˜˜AÐ9[Ð9[Ð9[rM   ÚmirrorÚmirror_sourcezanother sessionz[Delivered from ú] )r¨  ©rŒ  r  N)Úhermes_timerÜ  Úgateway.message_timestampsrÝ  r·  rv   rt   rw   r”   rx   ÚitemsÚ_strip_auto_continue_noiser³  Ústrip_interrupted_tool_tailsÚstrip_dangling_tool_call_tailÚ#strip_stale_dangerous_confirmationsrU   rf   )rÙ  r´  rØ  Ú_get_msg_tzÚ_render_msg_tsÚ_msg_tzÚagent_historyÚobserved_group_contextÚseparate_observed_contextr§  r¦  r4  Úhas_tool_callsÚhas_tool_call_idÚis_tool_messageÚ	clean_msgÚ
mirror_srcr®  Úobserved_contexts                      r>   Ú_build_gateway_agent_historyr  B  sÂ  € ð& 8Ð7Ð7Ð7Ð7Ð7ðð ð ð ð ð ð ˆk‰mŒm€GØ*,€MØ(*ÐÝ EÀnÑ UÔ UÐàˆ}˜"ð 2(ñ 2(ˆØ�wŠw�v‰ŒˆØð 	Øð Ð$Ð$Ð$Øð �8ÒÐØà—'’'˜)Ñ$Ô$ˆØð 	P ¨¢ µJ¸wÍÑ4LÔ4L Ø$�n W¨c¯gªg°kÑ.BÔ.BÀwÐOÑOÔOˆGØ$ð 	¨¯ª°Ñ)<Ô)<ð 	ÀÈÂÀÐT[ÀØ"×)Ò)­#¨g©,¬,×*<Ò*<Ñ*>Ô*>Ñ?Ô?Ð?Øð &¨Ð,ˆØ)¨SÐ0ÐØ &š.ˆàð 	(Ð-ð 	(°ð 	(Ø\Ð\¨#¯)ª)©+¬+Ð\Ñ\Ô\ˆIØ× Ò  Ñ+Ô+Ð+Ñ+Øð 	(ð �vŠ~ˆ~Ý4°WÑ=Ô=�Øð Ùà�wŠw�xÑ Ô ð EØ ŸWšW _Ð6GÑHÔH�
ØD¨ZÐDÐD¸7ÐDÐD�õ (¨¨g°sÐPTÐX^ÒP^Ð`Ñ`Ô`ˆEØ× Ò  Ñ'Ô'Ð'ùõ 1°Ñ?Ô?€Mõ 2°-Ñ@Ô@€Mõ 8Ø�4œ9™;œ;ðñ ô €Mð —y’yÐ!7Ñ8Ô8×>Ò>Ñ@Ô@ÐHÀDÐØÐ*Ð*Ð*rM   Úpersisted_historyÚlive_historyc                 óÖ   ‡— t          |t          ¦  «        rRt          |¦  «        t          | ¦  «        k    r2ddlmŠ t          ˆfd„|D ¦   «         ¦  «        }|rt          |¦  «        S | S )a¯  Prefer a cached live transcript only when it is longer and contains at
    least one real, non-ephemeral unpersisted row.

    Guards the FTS write-corruption case (#50502): when message writes fail
    silently through corrupt FTS triggers, the next turn reloads a stale/empty
    ``conversation_history`` from disk even though the same cached ``AIAgent``
    still holds unpersisted real rows in ``_session_messages``. Replacing those
    rows with the shorter persisted copy causes immediate same-session amnesia.
    Length alone does not trigger retention.

    Returns ``persisted_history`` unchanged unless the live copy is a longer
    list containing at least one real transcript row without the intrinsic
    ``_db_persisted`` marker. A longer all-durable list can be an expected
    replay-filtering delta (for example, cleanup of an interrupted read-only
    tool block). Deliberately unpersisted retry scaffolding is ignored.
    r   )Ú_is_ephemeral_scaffoldingc              3   ó†   •K  — | ];}t          |t          ¦  «        o!|                     d ¦  «         o ‰|¦  «         V — Œ<dS )Ú_db_persistedNrF  )rb   r$  r  s     €r>   rd   z/_select_cached_agent_history.<locals>.<genexpr>Â  sp   øè è € ð "
ð "
ð õ �w¥Ñ%Ô%ð 7Ø—K’K Ñ0Ô0Ð0ð7à-Ð-¨gÑ6Ô6Ð6ð"
ð "
ð "
ð "
ð "
ð "
rM   )rt   r½  r7   Ú	run_agentr  Úany)r  r  Úhas_unpersisted_rowr  s      @r>   Ú_select_cached_agent_historyr  «  sš   ø€ õ( �,¥Ñ%Ô%ð 
&­#¨lÑ*;Ô*;½cÐBSÑ>TÔ>TÒ*TÐ*TØ7Ð7Ð7Ð7Ð7Ð7å!ð "
ð "
ð "
ð "
ð (ð	"
ñ "
ô "
ñ 
ô 
Ðð ð 	&Ý˜Ñ%Ô%Ð%ØÐrM   r  c                 óŽ  — |s| S t           › d|› dt          › d�}t          | t          ¦  «        r|› | › �S t          | t          ¦  «        r{d„ | D ¦   «         }|D ]Q}t          |t
          ¦  «        r:|                     d¦  «        dk    r!|› |                     dd¦  «        › �|d<   |c S ŒRd|                     ¦   «         dœg|z   S | S )zDPrepend observed Telegram context to the API-only current user turn.r  r  c                 óZ   — g | ](}t          |t          ¦  «        rt          |¦  «        n|‘Œ)S rN  )rt   ru   ra   s     r>   ú
<listcomp>z?_wrap_current_message_with_observed_context.<locals>.<listcomp>Ý  s1   € ÐVÐVÐVÀd¥¨Dµ$Ñ!7Ô!7ÐA•4˜‘:”:�:¸TÐVÐVÐVrM   rÎ   rè   r®   )rÎ   rè   )Ú_OBSERVED_GROUP_CONTEXT_HEADERÚ!_CURRENT_ADDRESSED_MESSAGE_HEADERrt   rw   r½  ru   rv   Úrstrip)r$  r  ÚprefixÚwrappedrc   s        r>   Ú+_wrap_current_message_with_observed_contextr  Í  s  € ð ð Øˆõ *ð 	1ð 	1Øð	1ð 	1å,ð	1ð 	1ð 	1ð õ �'�3ÑÔð $ØÐ#˜'Ð#Ð#Ð#å�'�4Ñ Ô ð EØVÐVÈgÐVÑVÔVˆØð 	ð 	ˆDÝ˜$¥Ñ%Ô%ð ¨$¯(ª(°6Ñ*:Ô*:¸fÒ*DÐ*DØ"(Ð@¨$¯(ª(°6¸2Ñ*>Ô*>Ð@Ð@��V‘Ø���øØ¨¯ª©¬Ð9Ð9Ð:¸WÑDÐDà€NrM   c                 óÐ   — | sdS t          | ¦  «        D ]Q}t          |t          ¦  «        sŒ|                     d¦  «        }|r|dv rŒ4|                     d¦  «        }|�|c S  dS dS )uI  Return the ``timestamp`` of the last usable transcript row, if any.

    Skips metadata-only rows (``session_meta``, system injections) that are
    dropped before being handed to the agent.  Returns ``None`` when no
    usable row carries a timestamp â€” callers should treat that as "fresh"
    for backward compatibility.
    Nr¦  >   rß  rÞ  rg  )Úreversedrt   ru   rv   )rÙ  r§  r¦  r²  s       r>   Ú_last_transcript_timestampr  ç  s�   € ð ð ØˆtÝ˜Ñ Ô ð ð ˆÝ˜#�tÑ$Ô$ð 	ØØ�wŠw�v‰ŒˆØð 	�tÐ9Ð9Ð9ØØ�WŠW�[Ñ!Ô!ˆØˆ>ØˆIˆIˆIð ˆtˆtØˆ4rM   >   Úimage_generateÚtext_to_speechÚtext_to_speech_toolÚbfl_flux3_get_result)ró  rô  rõ  z [System note: Your previous turnz[System note: A new messagec                 ó˜   — t          | t          ¦  «        sdS |                      t          ¦  «        p|                      t          ¦  «        S )z†Return True if this user-message content is a gateway-injected
    auto-continue note that should NOT be replayed as a real user turn.F)rt   rw   r!  Ú_AUTO_CONTINUE_NOTE_PREFIXÚ_AUTO_CONTINUE_FALLBACK_PREFIX)r4  s    r>   Ú_is_auto_continue_noiser     sI   € õ �g�sÑ#Ô#ð Øˆuà×ÒÕ5Ñ6Ô6ð 	>Ø×ÒÕ<Ñ=Ô=ðrM   c                 óú   — t          | ¦  «        s| S t          | ¦  «        }t          |¦  «        rK|                     d¦  «        }|dk     rdS ||dz   d…                              ¦   «         }t          |¦  «        °K|S )aW  Remove persisted gateway auto-continue note prefix from user text.

    Older gateway builds prepended the recovery note directly to the user
    message, so the transcript row can contain both the synthetic note and
    the user's real question.  Strip one or more leading synthetic notes while
    preserving any real text that follows.
    rš  r   r®   r(   N)r   rw   ÚfindÚlstrip)r4  rè   Úends      r>   rò  rò  (  s‡   € õ # 7Ñ+Ô+ð ØˆÝˆw‰<Œ<€DÝ
! $Ñ
'Ô
'ð (Ø�iŠi˜‰nŒnˆØ�Š7ˆ7Ø�2Ø�C˜!‘G�I�IŒ×%Ò%Ñ'Ô'ˆõ	 " $Ñ
'Ô
'ð (ð
 €KrM   )Ú
host_imageÚimageÚagent_visible_imagez MEDIA:((?:[A-Za-z]:[/\\]|/|~\/)\S+\.(?:png|jpe?g|gif|webp|mp4|mov|avi|mkv|webm|ogg|opus|mp3|wav|m4a|flac|epub|pdf|zip|rar|7z|docx?|xlsx?|pptx?|txt|csv|apk|ipa))ÚmessagesÚhistory_offsetÚhistory_media_pathsc                 ó  — |pt          ¦   «         }|rt          | ¦  «        |k    r| |d…         }n| }i }|D ]Æ}|                     d¦  «        dk    rŒ|                     d¦  «        pg D ]’}|                     d¦  «        p|                     d¦  «        }|                     d¦  «        pi }t          |                     d¦  «        p|                     d¦  «        pd	¦  «        }	|r|	r|	|t          |¦  «        <   Œ“ŒÇg }
d
}|D �]ø}|                     d¦  «        dvrŒt          |                     d¦  «        p|                     d¦  «        pd	¦  «        }|                     |¦  «        t          vrŒqt          |                     d¦  «        pd	¦  «        }|                     |¦  «        }|dk    rÇd|vrÃ	 t          j        |¦  «        }n# t          $ r d}Y nw xY wt          |t          ¦  «        r„|                     d¦  «        rot          D ]g}|                     |¦  «        }t          |t          ¦  «        r;t                               d|› �¦  «        r||vr|
                     d|› �¦  «          nŒh�Œwd|vr�Œ}t                               |¦  «        D ]Z}|                     d¦  «                             ¦   «                              d¦  «        }|r||vr|
                     d|› �¦  «         Œ[d|v rd}�Œú|
|fS )a9  Collect real media tags from current-turn producer-tool results only.

    Two layered guards keep stale/example MEDIA: strings out of the reply:

    1. Producer-tool allowlist: only tools that intentionally emit deliverable
       artifacts (TTS) are eligible. Documentation, logs, and search results can
       contain example strings such as MEDIA:/absolute/path/to/file, which must
       never be delivered as attachments. (Fixes the original report behind #16721.)
    2. Current-turn isolation: only messages produced this turn are scanned, so a
       tool result from an earlier turn (still present in the full message list)
       cannot leak onto a later text-only reply (#34608).

    Mid-run context compression can rewrite/shrink the message list below the
    original history length. When that happens the slice boundary is no longer
    trustworthy, so fall back to scanning every message and rely on
    ``history_media_paths`` for dedup, preserving the compression-safe behaviour
    of #160. The producer-tool allowlist still applies on the fallback path.
    Nr¦  r­  rã  rÍ   Úcall_idÚfunctionrÖ   r®   F)rå  r-  rä  r4  r  úMEDIA:Úsuccessr(   ú",}ú[[audio_as_voice]]T)r•   r7   rv   rw   Ú_AUTO_APPEND_MEDIA_TOOL_NAMESÚjsonÚloadsr2   rt   ru   Ú_JSON_MEDIA_TOOL_PATH_FIELDSÚ_TOOL_MEDIA_REÚ	fullmatchr”   Úfinditerrð   rx   r  )r(  r)  r*  Únew_messagesÚtool_name_by_call_idr§  Úcallr,  ÚfnrÖ   Ú
media_tagsÚhas_voice_directiver4  Ú	tool_nameÚpayloadÚfieldr™   r[  s                     r>   Ú_collect_auto_append_media_tagsrB  O  s^  € ð. .Ð6µ±´Ðð ð  �#˜h™-œ-¨>Ò9Ð9Ø   Ô0ˆˆàˆà+-ÐØð :ð :ˆØ�7Š7�6‰?Œ?˜kÒ)Ð)ØØ—G’G˜LÑ)Ô)Ð/¨Rð 	:ð 	:ˆDØ—h’h˜t‘n”nÐ;¨¯ª°Ñ(;Ô(;ˆGØ—’˜*Ñ%Ô%Ð+¨ˆBÝ�r—v’v˜f‘~”~Ð?¨¯ª°&Ñ)9Ô)9Ð?¸RÑ@Ô@ˆDØð :˜4ð :Ø59Ð$¥S¨¡\¤\Ñ2øð	:ð €JØÐØð  'ñ  'ˆØ�7Š7�6‰?Œ?Ð"6Ð6Ð6ØÝ�c—g’g˜nÑ-Ô-ÐI°·²¸Ñ1CÔ1CÐIÀrÑJÔJˆØ×#Ò# GÑ,Ô,Õ4QÐQÐQØÝ�c—g’g˜iÑ(Ô(Ð.¨BÑ/Ô/ˆØ(×,Ò,¨WÑ5Ô5ˆ	ð Ð(Ò(Ð(¨X¸WÐ-DÐ-DðÝœ* WÑ-Ô-��øÝð ð ð Ø���ðøøøå˜'¥4Ñ(Ô(ð ¨W¯[ª[¸Ñ-CÔ-Cð Ý9ð ð �EØ"Ÿ;š; uÑ-Ô-�DÝ" 4­Ñ-Ô-ð Ý .× 8Ò 8¸À$¸¸Ñ IÔ Iðà $Ð,?Ð ?Ð ?Ø"×)Ò)¨/°4¨/¨/Ñ:Ô:Ð:Ø˜øÙØ˜7Ð"Ð"ÙÝ#×,Ò,¨WÑ5Ô5ð 	3ð 	3ˆEØ—;’;˜q‘>”>×'Ò'Ñ)Ô)×0Ò0°Ñ7Ô7ˆDØð 3˜Ð$7Ð7Ð7Ø×!Ò! /¨4 / /Ñ2Ô2Ð2øØ 7Ð*Ð*Ø"&ÐùàÐ*Ð*Ð*s   Æ9GÇGÇGrù  c                 óÚ  ‡— t          ¦   «         Ši }dt          ddfˆfd„}| D ]Å}|                     d¦  «        dk    rª|                     d¦  «        pg D ]’}|                     d¦  «        p|                     d	¦  «        }|                     d
¦  «        pi }t          |                     d¦  «        p|                     d¦  «        pd¦  «        }|r|r||t          |¦  «        <   Œ“ŒÆ| D �]~}|                     d¦  «        }|dk    r5t          |                     dd¦  «        pd¦  «        }	d|	v r ||	¦  «         ŒS|dvrŒXt          |                     dd¦  «        pd¦  «        }	d|	v r ||	¦  «         Œ�t          |                     d¦  «        p|                     d	¦  «        pd¦  «        }|                     |¦  «        dk    rŸ	 t          j        |	¦  «        }
n# t
          $ r d}
Y nw xY wt          |
t          ¦  «        rb|
                     d¦  «        rMt          D ]E}|
                     |¦  «        }t          |t          ¦  «        r|r‰ 	                    |¦  «          nŒF�Œ€‰S )a�  Collect every media path already delivered in prior assistant/tool output.

    Used to dedup auto-appended and model-emitted MEDIA tags so the same file
    is not re-sent on later turns. Covers three delivery shapes:
      * ``MEDIA:<path>`` text tags in tool results,
      * ``MEDIA:<path>`` text tags in assistant messages (model-generated tags),
      * ``image_generate`` JSON-payload paths (``host_image`` / ``image`` /
        ``agent_visible_image``), which carry no MEDIA: tag.

    Missing the JSON-payload shape caused #46627; missing the assistant-message
    shape caused repeated delivery when the model echoed a previous MEDIA tag.
    r4  r-   Nc                 óP  •— t                                | ¦  «        D ]S}|                     d¦  «                             ¦   «                              d¦  «        }|r‰                     |¦  «         ŒTt          j        | ¦  «        \  }}‰                     d„ |D ¦   «         ¦  «         d S )Nr(   r0  c              3   ó    K  — | ]	\  }}|V — Œ
d S r^   rN  )rb   r™   Ú	_is_voices      r>   rd   zN_collect_history_media_paths.<locals>._add_text_media_paths.<locals>.<genexpr>º  s&   è è € Ð=Ð=™o˜d I�TÐ=Ð=Ð=Ð=Ð=Ð=rM   )	r6  r8  rð   rx   r  r—   ÚBasePlatformAdapterÚextract_mediaÚupdate)r4  r[  r™   Úmedia_filesÚ_Úpathss        €r>   Ú_add_text_media_pathsz;_collect_history_media_paths.<locals>._add_text_media_paths°  sž   ø€ Ý#×,Ò,¨WÑ5Ô5ð 	 ð 	 ˆEØ—;’;˜q‘>”>×'Ò'Ñ)Ô)×0Ò0°Ñ7Ô7ˆDØð  Ø—	’	˜$‘”�øõ
 -Ô:¸7ÑCÔC‰ˆ�QØ�ŠÐ=Ð=°Ð=Ñ=Ô=Ñ=Ô=Ð=Ð=Ð=rM   r¦  r­  rã  rÍ   r,  r-  rÖ   r®   r.  >   rå  r-  rä  r  r/  )
r•   rw   rv   r3  r4  r2   rt   ru   r5  r—   )rù  r:  rM  r§  r;  Úcidr<  rÖ   r¦  r4  r@  rA  ÚjprL  s                @r>   Ú_collect_history_media_pathsrP     s½  ø€ õ ‘”€EØ+-Ðð
>¥sð 
>¨tð 
>ð 
>ð 
>ð 
>ð 
>ð 
>ð ð :ð :ˆØ�7Š7�6‰?Œ?˜kÒ)Ð)ØŸš Ñ-Ô-Ð3°ð :ð :�Ø—h’h˜t‘n”nÐ;¨¯ª°Ñ(;Ô(;�Ø—X’X˜jÑ)Ô)Ð/¨R�Ý˜2Ÿ6š6 &™>œ>ÐC¨T¯XªX°fÑ-=Ô-=ÐCÀÑDÔD�Øð :˜4ð :Ø59Ð(­¨S©¬Ñ2øøØð ñ ˆØ�wŠw�v‰ŒˆØ�;ÒÐÝ˜#Ÿ'š' )¨RÑ0Ô0Ð6°BÑ7Ô7ˆGØ˜7Ð"Ð"Ø%Ð% gÑ.Ô.Ð.ØØÐ+Ð+Ð+ØÝ�c—g’g˜i¨Ñ,Ô,Ð2°Ñ3Ô3ˆØ�wÐÐØ!Ð! 'Ñ*Ô*Ð*ØÝ�#—'’'˜.Ñ)Ô)ÐE¨S¯WªW°YÑ-?Ô-?ÐEÀ2ÑFÔFˆØ×#Ò# CÑ(Ô(Ð,<Ò<Ð<ðÝœ* WÑ-Ô-��øÝð ð ð Ø���ðøøøå˜'¥4Ñ(Ô(ð ¨W¯[ª[¸Ñ-CÔ-Cð Ý9ð ð �EØ Ÿš UÑ+Ô+�BÝ! "¥cÑ*Ô*ð ¨rð ØŸ	š	 "™œ˜Ø˜øùØ€Ls   ÇG Ç G/Ç.G/c                  ó¸  — t           j                             d¦  «        } | rnt           j                             | ¦  «        rdS t          j        t          ¦  «                             d| ¦  «         t           j         	                    dd¦  «         ddl
}|                     ¦   «         }|j        |j        fD ]5}|r1t           j                             |¦  «        r|t           j        d<    dS Œ6	 ddl}|                     ¦   «         t           j        d<   dS # t           $ r Y nw xY wdD ]3}t           j                             |¦  «        r|t           j        d<    dS Œ4dS )a±  Set SSL_CERT_FILE if the system doesn't expose CA certs to Python.

    Windows startup paths (Desktop, Scheduled Tasks, installer children) can
    occasionally inherit a stale SSL_CERT_FILE. Returning just because the
    variable is present makes every later httpx/OpenAI client construction fail
    with FileNotFoundError from ssl.load_verify_locations(). Treat a missing
    path as unset and fall back to certifi instead.
    ÚSSL_CERT_FILENz?Ignoring stale SSL_CERT_FILE=%r because the path does not existr   )z"/etc/ssl/certs/ca-certificates.crtz /etc/pki/tls/certs/ca-bundle.crtz1/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pemz/etc/ssl/ca-bundle.pemz/etc/ssl/cert.pemz/etc/pki/tls/cert.pemz#/usr/local/etc/openssl@1.1/cert.pemz&/opt/homebrew/etc/openssl@1.1/cert.pem)r’   r“   rv   r™   r˜   ÚloggingÚ	getLoggerrÏ   rã   ÚpopÚsslÚget_default_verify_pathsÚcafileÚopenssl_cafileÚcertifiÚwhereÚImportError)Úconfigured_certrV  rL  rP  rZ  s        r>   Ú_ensure_ssl_certsr^  ã  ss  € õ ”j—n’n _Ñ5Ô5€OØð .ÝŒ7�>Š>˜/Ñ*Ô*ð 	ØˆFÝÔ�(Ñ#Ô#×+Ò+ØMØñ	
ô 	
ð 	
õ 	Œ
�Š�¨Ñ-Ô-Ð-à€J€J€Jð ×(Ò(Ñ*Ô*€EØ”l EÔ$8Ð9ð ð ˆ	Øð 	�œŸš¨	Ñ2Ô2ð 	Ø*3�BŒJ�Ñ'ØˆFˆFøðØˆˆˆØ&-§m¢m¡o¤o�Œ
�?Ñ#ØˆøÝð ð ð Øˆðøøøð	ð ð ˆ	õ Œ7�>Š>˜)Ñ$Ô$ð 	Ø*3�BŒJ�Ñ'ØˆFˆFð	ðð s   Ã-%D Ä
D!Ä D!Úplatform_namec                 óZ   — ddl m}  || ¦  «        }|r|S |                      ¦   «         › d�S )a  Return the configured home-target env var for a platform.

    Consults built-in ``_HOME_TARGET_ENV_VARS`` first, then the plugin
    registry via ``cron.scheduler._resolve_home_env_var``, then falls back
    to ``<PLATFORM>_HOME_CHANNEL`` for unknown names.
    r   )Ú_resolve_home_env_varÚ_HOME_CHANNEL)Úcron.schedulerra  Úupper)r_  ra  Úresolveds      r>   Ú_home_target_env_varrf    sN   € ð 5Ð4Ð4Ð4Ð4Ð4à$Ð$ ]Ñ3Ô3€HØð ØˆØ×!Ò!Ñ#Ô#Ð2Ð2Ð2Ð2rM   c                 ó&   — t          | ¦  «        › d�S )zDReturn the optional thread/topic env var for a platform home target.Ú
_THREAD_ID)rf  )r_  s    r>   Ú_home_thread_env_varri  %  s   € å" =Ñ1Ô1Ð=Ð=Ð=Ð=rM   c                  ó:   — t           dz                       ¦   «         S )zIReturn True when a /restart completion marker is waiting to be delivered.ú.restart_notify.json)Ú_hermes_homer˜   rN  rM   r>   Ú_restart_notification_pendingrm  *  s   € åÐ1Ñ1×9Ò9Ñ;Ô;Ð;rM   c                  ó   — t           dz  S )Nz.restart_pending.json)rl  rN  rM   r>   Ú"_planned_restart_notification_pathro  /  s   € ÝÐ1Ñ1Ð1rM   c                  óB   — t          ¦   «                              ¦   «         S )zHReturn True when a non-chat planned restart should notify home channels.)ro  r˜   rN  rM   r>   Ú%_planned_restart_notification_pendingrq  3  s   € å-Ñ/Ô/×6Ò6Ñ8Ô8Ð8rM   c                  óJ   — t          ¦   «                              d¬¦  «         d S )NT©Ú
missing_ok)ro  ÚunlinkrN  rM   r>   Ú#_clear_planned_restart_notificationrv  8  s%   € Ý&Ñ(Ô(×/Ò/¸4Ð/Ñ@Ô@Ð@Ð@Ð@rM   ro   Ú_HERMES_GATEWAY)Úget_hermes_homeÚget_hermes_home_override)Úatomic_json_writeÚis_truthy_value)Úload_dotenv)Úload_hermes_dotenvú.envr(   ©Úhermes_homeÚproject_envc                  ó
  — ddl m}   | ¦   «         rt          t          ¦  «         dS t	          t          t          t          ¦  «                             ¦   «         j        d         dz  ¬¦  «         t          t          ¦  «         dS )a  Reload .env for fresh credentials without letting stale .env override config.

    Gateway processes are long-lived, so per-turn code reloads ~/.hermes/.env to
    pick up rotated API keys. config.yaml remains authoritative for agent budget
    settings such as agent.max_turns; otherwise a stale HERMES_MAX_ITERATIONS in
    .env can replace the startup bridge on later turns.

    In multiplex mode this is a NO-OP for the credential reload: secrets come
    from the per-turn ``set_secret_scope`` (installed by ``_profile_runtime_scope``)
    which loads the routed profile's ``.env`` into an isolated mapping. Mutating
    the process-global ``os.environ`` here would defeat that isolation and leak
    the default profile's keys to every profile's turns and subprocesses.
    r   ©Úis_multiplex_activeNr(   r~  r  )	Úagent.secret_scoper„  Ú_bridge_max_turns_from_configrl  r}  r   r�   r�   Úparentsrƒ  s    r>   Ú/_reload_runtime_env_preserving_config_authorityrˆ  R  sŽ   € ð 7Ð6Ð6Ð6Ð6Ð6ØÐÑÔð õ 	&¥lÑ3Ô3Ð3ØˆåÝ Ý�‘N”N×*Ò*Ñ,Ô,Ô4°QÔ7¸&Ñ@ðñ ô ð õ "¥,Ñ/Ô/Ð/Ð/Ð/rM   Úhomer   c                 ó´  — | dz  }|                      ¦   «         sdS 	 ddlm}m}  ||¦  «        } ||¦  «        }t	          |t
          ¦  «        si }	 ddlm}  |j        |¦  «        }n# t          $ r Y nw xY wn# t          $ r Y dS w xY w| 
                    di ¦  «        }t	          |t
          ¦  «        r&d|v r"t          |d         ¦  «        t          j        d<   | 
                    d	i ¦  «        }t	          |t
          ¦  «        rNd
|v r"t          |d
         ¦  «        t          j        d<   d|v r&t          |d         ¦  «        t          j        d<   dS dS dS )zIBridge config.yaml agent.max_turns into HERMES_MAX_ITERATIONS (a global).úconfig.yamlNr   ©Ú_expand_env_varsÚread_user_config_raw©Úmanaged_scoperµ   Ú	max_turnsÚHERMES_MAX_ITERATIONSÚsessionsÚcjk_ftsÚHERMES_CJK_FTSÚsearch_slow_msÚHERMES_SEARCH_SLOW_MS)r˜   Úhermes_cli.configr�  rŽ  rt   ru   Ú
hermes_clir�  Úapply_managed_overlayr2   rv   rw   r’   r“   )r‰  Úconfig_pathr�  rŽ  Úcfgr�  Ú	agent_cfgÚsessions_cfgs           r>   r†  r†  o  sÂ  € à˜Ñ&€KØ×ÒÑÔð ØˆðØLÐLÐLÐLÐLÐLÐLÐLð #Ð" ;Ñ/Ô/ˆØÐ˜sÑ#Ô#ˆÝ˜#�tÑ$Ô$ð 	ØˆCð
	Ø0Ð0Ð0Ð0Ð0Ð0Ø5�-Ô5°cÑ:Ô:ˆCˆCøÝð 	ð 	ð 	ØˆDð	øøøøøåð ð ð Øˆˆðøøøð —’˜ Ñ$Ô$€IÝ�)�TÑ"Ô"ð J {°iÐ'?Ð'?Ý.1°)¸KÔ2HÑ.IÔ.I�Œ
Ð*Ñ+ð —7’7˜: rÑ*Ô*€LÝ�,¥Ñ%Ô%ð VØ˜Ð$Ð$Ý+.¨|¸IÔ/FÑ+GÔ+G�BŒJÐ'Ñ(Ø˜|Ð+Ð+Ý25°lÐCSÔ6TÑ2UÔ2U�BŒJÐ.Ñ/Ð/Ð/ð	Vð Vð ,Ð+s5   �5A; ÁA* Á)A; Á*
A7Á4A; Á6A7Á7A; Á;
B	ÂB	c                  ó”   — t          ¦   «          	 t          t          j        dd¦  «        ¦  «        S # t          t
          f$ r Y dS w xY w)zGReturn the current per-turn iteration budget after runtime env refresh.r’  Ú500éô  )rˆ  rh  r’   rÆ  rw  rj  rN  rM   r>   Ú_current_max_iterationsr¢  •  sU   € å3Ñ5Ô5Ð5ðÝ•2”9Ð4°eÑ<Ô<Ñ=Ô=Ð=øÝ•zÐ"ð ð ð Øˆsˆsðøøøs   �!2 ²AÁA)Úcontextmanager)ÚPORT_BINDING_PLATFORM_VALUESÚplatform_binds_portc                   ó   — e Zd ZdZdS )ÚMultiplexConfigErrora  A profile multiplexer config is invalid.

    Distinct from a transient adapter-connect failure: a config error means the
    operator must fix config.yaml. Fatal configuration errors propagate to the
    startup guard instead of being treated as retryable adapter noise.
    N©rÏ   Ú
__module__Ú__qualname__Ú__doc__rN  rM   r>   r§  r§  ®  s   € € € € € ðð ð ð rM   r§  c                   ó   — e Zd ZdZdS )ÚSecondaryPortBindingConfigErrorzEA secondary profile conflicts with the multiplexer's shared listener.Nr¨  rN  rM   r>   r­  r­  ·  s   € € € € € ØOÐOÐOÐOrM   r­  Úprofile_homec              #   óH  K  — ddl m}m} ddlm}m}m} ddlm}  |t          | ¦  «        ¦  «        } |t          | ¦  «        ¦  «          | |t          | ¦  «        ¦  «        ¦  «        }	 dV —  ||¦  «          ||¦  «         dS #  ||¦  «          ||¦  «         w xY w)uõ  Scope config/skills/memory AND credentials to a profile for one turn.

    Combines the two seams the multiplexer needs:
      1. ``set_hermes_home_override`` â€” redirects ``get_hermes_home()`` (config,
         skills, memory, SOUL, sessions) to the profile's home. Contextvar, so
         it propagates into the agent worker thread via ``copy_context()``.
      2. ``set_secret_scope`` â€” installs the profile's ``.env`` secrets as the
         authoritative credential source, so ``get_secret`` reads this profile's
         keys and never the process-global ``os.environ`` (which in a
         multiplexer may hold another profile's values).

    Only used on the multiplexed inbound path. Single-profile gateways never
    enter this scope, so their behavior is unchanged. Loading the profile's
    ``.env`` here does NOT mutate ``os.environ`` â€” ``build_profile_secret_scope``
    returns an isolated dict â€” which is what keeps subprocesses (MCP, kanban)
    from inheriting cross-profile secrets.
    r   )Úset_hermes_home_overrideÚreset_hermes_home_override)Úbuild_profile_secret_scopeÚset_secret_scopeÚreset_secret_scope)Úhydrate_profile_secret_sourcesN)Úhermes_constantsr°  r±  r…  r²  r³  r´  Úhermes_cli.env_loaderrµ  rw   r   )	r®  r°  r±  r²  r³  r´  rµ  Ú
home_tokenÚsecret_tokens	            r>   Ú_profile_runtime_scoperº  »  s  è è € ð& VÐUÐUÐUÐUÐUÐUÐUðð ð ð ð ð ð ð ð ð ð
 EÐDÐDÐDÐDÐDà)Ð)­#¨lÑ*;Ô*;Ñ<Ô<€JØ"Ð"¥4¨Ñ#5Ô#5Ñ6Ô6Ð6Ø#Ð#Ð$>Ð$>½tÀLÑ?QÔ?QÑ$RÔ$RÑSÔS€Lð/ØˆˆˆàÐ˜<Ñ(Ô(Ð(Ø"Ð" :Ñ.Ô.Ð.Ð.Ð.øð 	Ð˜<Ñ(Ô(Ð(Ø"Ð" :Ñ.Ô.Ð.Ð.øøøs   Á-B	 Â	B!ÚGatewayConfigc                  ón  — t          ¦   «         } t          | dd¦  «        s| S 	 t          ¦   «         }n# t          $ r | cY S w xY w	 t	          t          |¦  «        ¦  «        5  t          ¦   «         cddd¦  «         S # 1 swxY w Y   dS # t          $ r! t                               dd¬¦  «         | cY S w xY w)u.  Load gateway config for the process-level GatewayRunner.

    When ``gateway.multiplex_profiles`` is off, this is identical to
    ``load_gateway_config()`` (legacy single-profile path).

    When multiplexing is on, reload under the default/active profile's
    ``_profile_runtime_scope`` so platform tokens in that profile's ``.env``
    resolve through the secret scope â€” the same path secondary profiles use
    in ``_start_one_profile_adapters``. Without this, primary startup calls
    ``load_gateway_config()`` unscoped: ``_getenv`` falls through to
    ``os.environ``, which often has no ``TELEGRAM_BOT_TOKEN`` once the token
    lives only under ``profiles/<name>/.env`` (#64674).

    Single-profile gateways never set ``multiplex_profiles``, so they keep the
    unscoped load and are unaffected.
    Úmultiplex_profilesFNzAmultiplex default-scope config reload failed; using unscoped loadTrß   )Úload_gateway_configrV   rx  r2   rº  r   r3   r4   )rœ  r‰  s     r>   Úload_gateway_config_for_runnerr¿  à  s,  € õ" Ñ
Ô
€CÝ�3Ð,¨eÑ4Ô4ð Øˆ
ðÝÑ Ô ˆˆøÝð ð ð Øˆ
ˆ
ˆ
ðøøøðÝ#¥D¨¡J¤JÑ/Ô/ð 	)ð 	)Ý&Ñ(Ô(ð	)ð 	)ð 	)ð 	)ñ 	)ô 	)ð 	)ð 	)ð 	)ð 	)ð 	)ð 	)øøøð 	)ð 	)ð 	)ð 	)ð 	)ð 	)øåð ð ð Ý�ŠØOØð 	ñ 	
ô 	
ð 	
ð ˆ
ˆ
ˆ
ðøøøsE   £2 ²AÁ AÁB	 Á!A<Á/B	 Á<B Â B	 ÂB ÂB	 Â	(B4Â3B4rÄ  Úplatform_configÚPlatformConfigc                 ó  — ddl m} | |vrdS t          |dd¦  «        pd}t          |t          ¦  «        r|                     ¦   «         rdS t          |dd¦  «        pd}t          |t          ¦  «        r|                     ¦   «         rdS dS )	zõReturn True when a token-authenticated platform has a usable bot credential.

    Platforms that do not use ``PlatformConfig.token`` always return True so we
    never skip them here (Signal session paths, port-binding HTTP adapters, etc.).
    r   )ÚPLATFORM_TOKEN_ENV_NAMESTÚtokenNr®   Úapi_keyF)Úgateway.configrÃ  rV   rt   rw   rx   )r�   rÀ  rÃ  rÄ  rÅ  s        r>   Ú_platform_has_bot_credentialrÇ    s¤   € ð 8Ð7Ð7Ð7Ð7Ð7àÐ/Ð/Ð/ØˆtÝ�O W¨dÑ3Ô3Ð9°r€EÝ�%�ÑÔð  %§+¢+¡-¤-ð Øˆtå�o y°$Ñ7Ô7Ð=¸2€GÝ�'�3ÑÔð  G§M¢M¡O¤Oð ØˆtØˆ5rM   z=^(?P<host>.+):(?P<container>/[^:]+?)(?::(?P<options>[^:]+))?$z/outputz/outputs©ÚDEFAULT_CONFIGÚgateway_turn_lease_timeoutÚHERMES_TURN_LEASE_TIMEOUTr‹  rŒ  r�  ÚterminalÚbackendÚTERMINAL_ENVÚdegraded_modeÚTERMINAL_DEGRADED_MODEÚcwdÚTERMINAL_CWDÚtimeoutÚTERMINAL_TIMEOUTÚ	home_modeÚTERMINAL_HOME_MODEÚlifetime_secondsÚTERMINAL_LIFETIME_SECONDSÚdocker_imageÚTERMINAL_DOCKER_IMAGEÚdocker_forward_envÚTERMINAL_DOCKER_FORWARD_ENVÚsingularity_imageÚTERMINAL_SINGULARITY_IMAGEÚmodal_imageÚTERMINAL_MODAL_IMAGEÚdaytona_imageÚTERMINAL_DAYTONA_IMAGEÚvercel_runtimeÚTERMINAL_VERCEL_RUNTIMEÚssh_hostÚTERMINAL_SSH_HOSTÚssh_userÚTERMINAL_SSH_USERÚssh_portÚTERMINAL_SSH_PORTÚssh_keyÚTERMINAL_SSH_KEYÚcontainer_cpuÚTERMINAL_CONTAINER_CPUÚTERMINAL_CONTAINER_MEMORYÚTERMINAL_CONTAINER_DISKÚTERMINAL_CONTAINER_PERSISTENTÚTERMINAL_DOCKER_VOLUMESÚTERMINAL_DOCKER_ENVÚTERMINAL_DOCKER_EXTRA_ARGSÚTERMINAL_DOCKER_SHM_SIZEÚ&TERMINAL_DOCKER_MOUNT_CWD_TO_WORKSPACEÚTERMINAL_DOCKER_NETWORKÚ TERMINAL_DOCKER_RUN_AS_HOST_USERÚ(TERMINAL_DOCKER_PERSIST_ACROSS_PROCESSESÚTERMINAL_DOCKER_ORPHAN_REAPERÚTERMINAL_SANDBOX_DIRÚTERMINAL_PERSISTENT_SHELL)Úcontainer_memoryÚcontainer_diskÚcontainer_persistentÚdocker_volumesÚ
docker_envÚdocker_extra_argsÚdocker_shm_sizeÚdocker_mount_cwd_to_workspaceÚdocker_networkÚdocker_run_as_host_userÚdocker_persist_across_processesÚdocker_orphan_reaperÚsandbox_dirÚpersistent_shell>   rÑ  Úautor
  Ú	auxiliary>   ÚvisionÚapprovalÚweb_extract)Úget_plugin_auxiliary_tasksÚkeyÚproviderÚmodelÚbase_urlrÅ  r  Ú
AUXILIARY_Ú	_PROVIDERÚ_MODELÚ	_BASE_URLÚ_API_KEYr‘  r’  Úgateway_timeoutÚHERMES_AGENT_TIMEOUTÚgateway_timeout_warningÚHERMES_AGENT_TIMEOUT_WARNINGÚgateway_notify_intervalÚHERMES_AGENT_NOTIFY_INTERVALÚsession_stall_timeoutÚHERMES_SESSION_STALL_TIMEOUTÚrestart_drain_timeoutÚHERMES_RESTART_DRAIN_TIMEOUTÚgateway_auto_continue_freshnessÚHERMES_AUTO_CONTINUE_FRESHNESSÚ%gateway_startup_restore_drain_timeoutru  r“  r”  r•  r–  r—  rD  Úbusy_input_modeÚHERMES_GATEWAY_BUSY_INPUT_MODEÚbusy_text_modeÚHERMES_GATEWAY_BUSY_TEXT_MODEÚbusy_ack_enabledÚHERMES_GATEWAY_BUSY_ACK_ENABLEDÚbusy_steer_ack_enabledÚ%HERMES_GATEWAY_BUSY_STEER_ACK_ENABLEDÚtimezoneÚHERMES_TIMEZONEÚsecurityÚredact_secretsÚHERMES_REDACT_SECRETSr9   ÚstrictÚ0ÚHERMES_MEDIA_DELIVERY_STRICTÚmedia_delivery_allow_dirsc              #   ó8   K  — | ]}|¯t          |¦  «        V — Œd S r^   ©rw   ©rb   Úps     r>   rd   rd   ü  s.   è è € Ð5WÐ5WÀÐUVÐ5Wµc¸!±f´fÐ5WÐ5WÐ5WÐ5WÐ5WÐ5WrM   ÚHERMES_MEDIA_ALLOW_DIRSÚtrust_recent_filesÚHERMES_MEDIA_TRUST_RECENT_FILESÚtrust_recent_files_secondsÚ!HERMES_MEDIA_TRUST_RECENT_SECONDSÚplatform_connect_timeoutÚ'HERMES_GATEWAY_PLATFORM_CONNECT_TIMEOUTu.     Warning: config.yaml â†’ env bridge failed: ú: )Úfilezz  Gateway will fall back to .env values, which may not match your current config.yaml. Run `hermes doctor` to investigate.)Úapply_ipv4_preferenceÚ_cfgÚnetworkÚ
force_ipv4rì   z/  Warning: IPv4 preference application failed: )Úprint_config_warningsz%  Warning: config validation failed: )Úwarn_deprecated_cwd_env_varsz%  Warning: deprecation check failed: ÚHERMES_QUIETÚHERMES_EXEC_ASK)ÚCWD_PLACEHOLDERSÚ resolve_placeholder_terminal_cwdÚMESSAGING_CWDÚfalse>   ro   rq   rr   )Úconfigured_cwdÚterminal_backendÚmessaging_cwdr  Úhome_fallback)ÚChannelOverriderÄ  Ú_BUILTIN_PLATFORM_VALUESr»  rÁ  Ú_getenvr¾  )ÚAsyncSessionStoreÚSessionEntryÚSessionStoreÚSessionSourceÚSessionContextÚbuild_session_contextÚbuild_session_context_promptÚbuild_channel_continuity_noteÚbuild_session_keyÚis_shared_multi_user_sessionÚ neutralize_untrusted_inline_text)ÚDeliveryRouterÚ#looks_like_telegram_private_chat_idÚresolve_delivery_transport)ÚDEFAULT_LEASE_WAITÚSessionTurnLeaseRegistryÚTurnLeaseTimeoutError)ÚSERVICE_TIER_UNSETÚSessionStateÚlegacy_dict_propertyÚlegacy_lease_token_property)ÚGatewayAuthorizationMixin)ÚGatewayKanbanWatchersMixin)ÚGatewaySlashCommandsMixin)ÚTurnContext)	rG  ÚEphemeralReplyÚMessageEventÚMessageTypeÚ_prefix_within_utf16_limitÚ_reply_anchor_for_eventÚbuild_auto_tts_output_pathÚmerge_pending_message_eventÚ	utf16_len)ÚDEFAULT_HEARTBEAT_INTERVAL_SÚ_arm_loop_floor_timerÚarm_shutdown_watchdogÚloop_heartbeat_foreverÚresolve_shutdown_watchdog_delayÚstart_loop_liveness_watchdog)Ú*DEFAULT_GATEWAY_RESTART_AFTER_TURN_TIMEOUTÚ%DEFAULT_GATEWAY_RESTART_DRAIN_TIMEOUTÚGATEWAY_FATAL_CONFIG_EXIT_CODEÚ!GATEWAY_SERVICE_RESTART_EXIT_CODEÚ parse_restart_after_turn_timeoutÚparse_restart_drain_timeout)Úcanonical_whatsapp_identifierÚexpand_whatsapp_aliasesÚnormalize_whatsapp_identifier)ÚWECOM_DM_POLICYÚWECOM_GROUP_POLICYÚWECOM_ALLOW_ALL_USERS)ÚWEIXIN_DM_POLICYÚWEIXIN_GROUP_POLICYÚWEIXIN_ALLOW_ALL_USERS)ÚYUANBAO_DM_POLICYÚYUANBAO_GROUP_POLICYÚYUANBAO_ALLOW_ALL_USERS)NNÚQQ_ALLOW_ALL_USERS)ÚWHATSAPP_DM_POLICYÚWHATSAPP_GROUP_POLICYÚWHATSAPP_ALLOW_ALL_USERSc                 ó.  — t          | di ¦  «                             ¦   «         D �]o\  }}t          |dd¦  «        sŒt                               |¦  «        }|sŒ5|\  }}}t          |dd¦  «        pi }t	          |                     d¦  «        p|rt          |d¦  «        nd¦  «                             ¦   «                              ¦   «         }t	          |                     d¦  «        p|rt          |d¦  «        nd¦  «                             ¦   «                              ¦   «         }	|d	k    r|	d	k    r�Œt          j	        d
d¦  «                             ¦   «         dv }
|
p%|o#t          |d¦  «                             ¦   «         dv }|r�Œe|j
        › d�c S dS )zFReturn a startup-abort reason when open policy lacks allow-all opt-in.rE  rÓ  FrÁ  NÚ	dm_policyÚpairingÚgroup_policyÚopenÚGATEWAY_ALLOW_ALL_USERSr®   >   ro   rq   rr   z&: open policy without allow-all opt-in)rV   rñ  Ú_OWN_POLICY_OPEN_ENVrv   rw   rW  rx   ry   r’   rÆ  r­   )rz   r�   rÀ  Úopen_envÚdm_envÚ	group_envÚallow_all_envrÁ  r–  r˜  Úgateway_allow_allÚplatform_opted_ins               r>   Ú"_own_policy_open_startup_violationr¢  ·	  sÍ  € å%,¨V°[À"Ñ%EÔ%E×%KÒ%KÑ%MÔ%Mð Iñ IÑ!ˆ�/Ý�¨	°5Ñ9Ô9ð 	ØÝ'×+Ò+¨HÑ5Ô5ˆØð 	ØØ+3Ñ(ˆ�	˜=Ý˜¨°$Ñ7Ô7Ð=¸2ˆÝØ�IŠI�kÑ"Ô"ð EØ.4ÐC•˜ 	Ñ*Ô*Ð*¸)ñ
ô 
÷ Š%‰'Œ'—%’%‘'”'ð 	õ Ø�IŠI�nÑ%Ô%ð KØ1:ÐI•˜	 9Ñ-Ô-Ð-À	ñ
ô 
÷ Š%‰'Œ'—%’%‘'”'ð 	ð ˜ÒÐ <°6Ò#9Ð#9ÙÝœIØ% rñ
ô 
ç
Š%‰'Œ'Ð)ð*Ðð .ð 
Øð KÝ˜ rÑ*Ô*×0Ò0Ñ2Ô2Ð6JÐJð 	ð ð 	ÙØ”.ÐHÐHÐHÐHÐHÐHØˆ4rM   )	Ú_session_model_overridesÚ _pending_one_turn_model_restoresÚ_session_reasoning_overridesÚ_session_service_tier_overridesÚ_pending_model_notesÚ_last_resolved_modelÚ_queued_eventsÚ_session_stall_notifiedÚ_pending_turn_sidecar_notesÚ_CONVERSATION_SCOPED_STATEc                  ó†  — ddl m} m}m} ddlm}m} 	  | ¦   «         }n¥# |$ rw} ||¦  «        rt                               d|¦  «         nt                               d|¦  «         t          ¦   «         }|�|cY d}~S t           ||¦  «        ¦  «        |‚d}~wt          $ r}t           ||¦  «        ¦  «        |‚d}~ww xY w |¦   «         }	d}
t          j                             d¦  «        }|r*	 t          |¦  «        }
nZ# t           t"          f$ r d}
Y nEw xY wt%          |	t&          ¦  «        r,|	                     d¦  «        }t%          |t          ¦  «        r|}
|
€2|                     d	¦  «        }t%          |t          ¦  «        r|dk    r|}
|                     d
¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        t)          |                     d¦  «        pg ¦  «        |                     d¦  «        |
dœ	S )u5  Resolve provider credentials for gateway-created AIAgent instances.

    Provider is read from ``config.yaml`` ``model.provider`` (the single
    source of truth). ``resolve_runtime_provider()`` falls through to env
    var lookups internally for legacy compatibility, but the gateway does
    not consult environment variables for behavioral config â€” config.yaml
    is authoritative.

    If the primary provider fails with an authentication error, attempt to
    resolve credentials using the fallback provider chain from config.yaml
    before giving up.
    r   )Úresolve_runtime_providerÚformat_runtime_provider_errorÚ_get_model_config)Ú	AuthErrorÚis_rate_limited_auth_erroru;   Primary provider rate-limited (429): %s â€” trying fallbacku4   Primary provider auth failed: %s â€” trying fallbackNÚHERMES_MAX_TOKENSÚ
max_tokensÚmax_output_tokensrÅ  r  r  Úrequested_providerÚapi_moder   ÚargsÚcredential_pool©	rÅ  r  r  r¶  r·  r   r¸  r¹  r´  )Úhermes_cli.runtime_providerr®  r¯  r°  Úhermes_cli.authr±  r²  r3   rã   Ú_try_resolve_fallback_providerÚRuntimeErrorr2   r’   r“   rv   rh  rj  rw  rt   ru   r½  )r®  r¯  r°  r±  r²  ÚruntimeÚauth_excÚ	fb_configr<   Ú	model_cfgr´  Ú_env_mtrÕ  Ú_runtime_mots                 r>   Ú_resolve_runtime_agent_kwargsrÅ  

  sÀ  € ðð ð ð ð ð ð ð ð ð ð
 FÐEÐEÐEÐEÐEÐEÐEðHØ*Ð*Ñ,Ô,ˆˆøØð Rð Rð Rð
 &Ð% hÑ/Ô/ð 	]Ý�NŠNÐXÐZbÑcÔcÐcÐcå�NŠNÐQÐS[Ñ\Ô\Ð\Ý2Ñ4Ô4ˆ	ØÐ ØÐÐÐÐÐÐÝÐ8Ð8¸ÑBÔBÑCÔCÈÐQøøøøÝð Hð Hð HÝÐ8Ð8¸Ñ=Ô=Ñ>Ô>ÀCÐGøøøøðHøøøð "Ð!Ñ#Ô#€IØ€JÝŒj�nŠnÐ0Ñ1Ô1€GØð ð	Ý˜W™œˆJˆJøÝ�IÐ&ð 	ð 	ð 	ØˆJˆJˆJð	øøøå	�I�tÑ	$Ô	$ð Ø�]Š]˜<Ñ(Ô(ˆÝ�b�#ÑÔð 	ØˆJð ÐØ—{’{Ð#6Ñ7Ô7ˆÝ�l¥CÑ(Ô(ð 	&¨\¸AÒ-=Ð-=Ø%ˆJð —;’;˜yÑ)Ô)Ø—K’K 
Ñ+Ô+Ø—K’K 
Ñ+Ô+Ø%ŸkškÐ*>Ñ?Ô?Ø—K’K 
Ñ+Ô+Ø—;’;˜yÑ)Ô)Ý�W—[’[ Ñ(Ô(Ð.¨BÑ/Ô/Ø"Ÿ;š;Ð'8Ñ9Ô9Ø ð
ð 
ð 
s?   ”
 ŸC¤ABÁ7CÁ=BÂCÂ#B<Â<CÃ2D ÄDÄDc                 óè  — ddl m}m} 	  || ¬¦  «        }n+# t          $ r}t	           ||¦  «        ¦  «        |‚d}~ww xY w|                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d	¦  «        |                     d
¦  «        t          |                     d¦  «        pg ¦  «        |                     d¦  «        dœS )zQResolve runtime credentials for a specific provider (e.g. from channel override).r   )r®  r¯  )Ú	requestedNrÅ  r  r  r¶  r·  r   r¸  r¹  )rÅ  r  r  r¶  r·  r   r¸  r¹  )r»  r®  r¯  r2   r¾  rv   r½  )r  r®  r¯  r¿  r<   s        r>   Ú*_resolve_runtime_agent_kwargs_for_providerrÈ  Q
  s  € ðð ð ð ð ð ð ð ðHØ*Ð*°XÐ>Ñ>Ô>ˆˆøÝð Hð Hð HÝÐ8Ð8¸Ñ=Ô=Ñ>Ô>ÀCÐGøøøøðHøøøð —;’;˜yÑ)Ô)Ø—K’K 
Ñ+Ô+Ø—K’K 
Ñ+Ô+Ø%ŸkškÐ*>Ñ?Ô?Ø—K’K 
Ñ+Ô+Ø—;’;˜yÑ)Ô)Ý�W—[’[ Ñ(Ô(Ð.¨BÑ/Ô/Ø"Ÿ;š;Ð'8Ñ9Ô9ð	ð 	ð 	s   Š —
?¡:º?c                 ó,  — | r!t          | ¦  «                             ¦   «         sdS 	 t          t          | ¦  «                             ¦   «         ¦  «                             d¦  «        S # t          $ r! t
                               d| d¬¦  «         Y dS w xY w)zJReturn the live credential pool for a provider id (e.g. ``custom:hyper``).Nr¹  z1Failed to resolve credential pool for provider=%sTrß   )rw   rx   rÈ  rv   r2   r3   r4   )r  s    r>   Ú_credential_pool_for_providerrÊ  g
  s¬   € àð �3˜x™=œ=×.Ò.Ñ0Ô0ð Øˆtð
Ý9½#¸h¹-¼-×:MÒ:MÑ:OÔ:OÑPÔP×TÒTØñ
ô 
ð 	
øõ ð ð ð Ý�ŠØ?ØØð 	ñ 	
ô 	
ð 	
ð
 ˆtˆtðøøøs   §A A( Á('BÂBc                  óÖ  — ddl m}  	 t          ¦   «         }t          |¦  «        }|sdS |D �]«}	 ddlm}  | |                     d¦  «        |                     d¦  «         ||¦  «        ¬¦  «        }t                               d|                     d¦  «        p|                     d¦  «        |                     d	¦  «        ¦  «         |                     d
¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        t          |                     d¦  «        pg ¦  «        |                     d¦  «        |                     d	¦  «        dœ	c S # t          $ r:}t                               d|                     d¦  «        |¦  «         Y d}~�Œ¥d}~ww xY wn# t          $ r Y nw xY wdS )zQAttempt to resolve credentials from the fallback_model/fallback_providers config.r   )r®  N)Úresolve_entry_api_keyr  r  )rÇ  Úexplicit_base_urlÚexplicit_api_keyz'Fallback provider resolved: %s model=%sr  rÅ  r¶  r·  r   r¸  r¹  )	rÅ  r  r  r¶  r·  r   r¸  r¹  r  zFallback entry %s failed: %s)r»  r®  Ú_load_gateway_runtime_configr"   Úhermes_cli.fallback_configrÌ  rv   r3   rz  r½  r2   r4   )r®  rœ  Úfb_listr®  rÌ  r¿  Úfb_excs          r>   r½  r½  x
  s!  € àDÐDÐDÐDÐDÐDð)õ +Ñ,Ô,ˆÝ$ SÑ)Ô)ˆØð 	Ø�4Øð 	ñ 	ˆEðØLÐLÐLÐLÐLÐLà2Ð2Ø#Ÿiši¨
Ñ3Ô3Ø&+§i¢i°
Ñ&;Ô&;Ø%:Ð%:¸5Ñ%AÔ%Aðñ ô �õ —’Ø=Ø—I’I˜jÑ)Ô)ÐD¨W¯[ª[¸Ñ-DÔ-DØ—I’I˜gÑ&Ô&ñô ð ð  'Ÿ{š{¨9Ñ5Ô5Ø '§¢¨JÑ 7Ô 7Ø '§¢¨JÑ 7Ô 7Ø*1¯+ª+Ð6JÑ*KÔ*KØ '§¢¨JÑ 7Ô 7Ø&Ÿ{š{¨9Ñ5Ô5Ý  §¢¨VÑ!4Ô!4Ð!:¸Ñ;Ô;Ø'.§{¢{Ð3DÑ'EÔ'EØ"ŸYšY wÑ/Ô/ð
ð 
ð 
ð 
ð 
øõ ð ð ð Ý—’Ð;¸U¿YºYÀzÑ=RÔ=RÐTZÑ[Ô[Ð[Ø���‘øøøøðøøøð;	øõ@ ð ð ð Øˆðøøøàˆ4s@   ˆG ©G ¯EFÆG Æ
GÆ/GÇ
G ÇGÇG Ç
G&Ç%G&Úindexc                 ób   — t          | dd¦  «        pg }|t          |¦  «        k     r||         ndS )zÇReturn the per-attachment MIME for the attachment at *index*.

    Empty string when the platform didn't populate a per-file MIME for
    that slot (some adapters only set a message-level type).
    Úmedia_typesNr®   )rV   r7   )ÚeventrÓ  rÕ  s      r>   Ú_event_media_type_atr×  ¨
  s<   € õ ˜% °Ñ5Ô5Ð;¸€KØ!&­¨[Ñ)9Ô)9Ò!9Ð!9ˆ;�uÔÐ¸rÐArM   c                 óŽ   — t          | |¦  «        }|r|                     d¦  «        S t          | dd¦  «        t          j        k    S )až  True if the attachment at *index* is an image.

    Trust the per-attachment MIME when present. Only fall back to the
    message-level ``PHOTO`` type when this attachment's MIME is unknown --
    otherwise a document (or any non-image) uploaded alongside an image in
    the same message gets mis-routed as an image, base64'd into a vision
    content part, and the provider 400s ("Could not process image").
    úimage/Úmessage_typeN)r×  r!  rV   rs  ÚPHOTO©rÖ  rÓ  Úmtypes      r>   Ú_event_media_is_imagerÞ  ²
  sI   € õ ! ¨Ñ.Ô.€EØð *Ø×Ò Ñ)Ô)Ð)Ý�5˜.¨$Ñ/Ô/µ;Ô3DÒDÐDrM   c                 ó¢   — t          | |¦  «        }|r|                     d¦  «        S t          | dd¦  «        t          j        t          j        hv S )zGTrue if the attachment at *index* is audio (per-attachment MIME first).úaudio/rÚ  N)r×  r!  rV   rs  ÚVOICEÚAUDIOrÜ  s      r>   Ú_event_media_is_audiorã  Á
  sO   € å  ¨Ñ.Ô.€EØð *Ø×Ò Ñ)Ô)Ð)Ý�5˜.¨$Ñ/Ô/µKÔ4EÅ{ÔGXÐ3YÐYÐYrM   c                 óÂ   — t          | dd¦  «        }|t          j        t          j        hv rdS |t          j        k    p"t          | |¦  «                             d¦  «        S )zFTrue when an audio attachment should enter the automatic STT pipeline.rÚ  NFrà  )rV   rs  râ  ÚDOCUMENTrá  r×  r!  )rÖ  rÓ  rÚ  s      r>   Ú_event_media_is_stt_inputræ  É
  s_   € å˜5 .°$Ñ7Ô7€LØ�Ô)­;Ô+?Ð@Ð@Ð@Øˆuà�Ô)Ò)ð 	CÝ  uÑ-Ô-×8Ò8¸ÑBÔBðrM   c                 óŽ   — t          | |¦  «        }|r|                     d¦  «        S t          | dd¦  «        t          j        k    S )zGTrue if the attachment at *index* is video (per-attachment MIME first).úvideo/rÚ  N)r×  r!  rV   rs  ÚVIDEOrÜ  s      r>   Ú_event_media_is_videorê  Ô
  sG   € å  ¨Ñ.Ô.€EØð *Ø×Ò Ñ)Ô)Ð)Ý�5˜.¨$Ñ/Ô/µ;Ô3DÒDÐDrM   c                 ó®  — g }t          | dd¦  «        pg }t          |¦  «        D ]œ\  }}t          | |¦  «        r|                     d|› d�¦  «         Œ/t	          | |¦  «        r|                     d|› d�¦  «         ŒYt          | |¦  «        r|                     d|› d�¦  «         Œƒ|                     d|› d�¦  «         Œ�d                     |¦  «        S )	ag  Build a text placeholder for media-only events so they aren't dropped.

    When a photo/document is queued during active processing and later
    dequeued, only .text is extracted.  If the event has no caption,
    the media would be silently lost.  This builds a placeholder that
    the vision enrichment pipeline will replace with a real description.
    Ú
media_urlsNz[User sent an image: rš  z[User sent audio: z[User sent a video: z[User sent a file: r  )rV   Ú	enumeraterÞ  r”   rã  rê  rf   )rÖ  rg   rì  ÚiÚurls        r>   Ú_build_media_placeholderrð  Ü
  s  € ð €EÝ˜ ¨dÑ3Ô3Ð9°r€JÝ˜JÑ'Ô'ð 7ð 7‰ˆˆ3Ý  ¨Ñ*Ô*ð 	7Ø�LŠLÐ7°Ð7Ð7Ð7Ñ8Ô8Ð8Ð8Ý" 5¨!Ñ,Ô,ð 	7Ø�LŠLÐ4¨cÐ4Ð4Ð4Ñ5Ô5Ð5Ð5Ý" 5¨!Ñ,Ô,ð 	7Ø�LŠLÐ6°Ð6Ð6Ð6Ñ7Ô7Ð7Ð7à�LŠLÐ5¨sÐ5Ð5Ð5Ñ6Ô6Ð6Ð6Ø�9Š9�UÑÔÐrM   Údisplay_nameÚ
agent_pathrÝ  c                 óP   — |                      d¦  «        r	d| › d|› d�S d| › d|› d�S )uf  Context note prepended to a user turn when they attach a document.

    Text documents (``text/*``) have their content inlined upstream by the
    platform adapter, so the note just confirms that and records the path.

    Binary documents (PDF, DOCX, XLSX, â€¦) cannot be inlined as text. The note
    must tell the agent to *extract* the text itself before answering â€” earlier
    wording ("Ask the user what they'd like you to do with it") steered the
    model into punting back to the user, which is why attached PDFs/DOCX looked
    "unreadable" to the agent even though it has the tools to read them.
    ztext/z![The user sent a text document: 'zC'. Its content has been included below. The file is also saved at: rš  z[The user sent a document: 'ú'. It is saved at: u
  . Its text is not inlined here (it's a binary format such as PDF or DOCX). To read it, extract the document's text yourself â€” for example with the terminal tool or the ocr-and-documents skill â€” before answering, instead of asking the user to paste the contents.])r!  )rñ  rò  rÝ  s      r>   Ú_build_document_context_noterõ  ò
  si   € ð ×Ò˜Ñ Ô ð 
ð8°ð 8ð 8à*4ð8ð 8ð 8ð	
ð	6 |ð 	6ð 	6È
ð 	6ð 	6ð 	6ðrM   Úsecondsc                 óÂ   — t          t          | ¦  «        ¦  «        }|dk     rd}t          |d¦  «        \  }}t          |d¦  «        \  }}|r|› d|d›d|d›�S |› d|d›�S )Nr   rd  é<   rÉ  Ú02d)rh  ÚroundÚdivmod)rö  ÚtotalÚhoursÚremÚminutesÚsecss         r>   Ú_format_durationr    sˆ   € Ý•�g‘”ÑÔ€EØˆq‚y€yØˆÝ˜˜tÑ$Ô$�J€Eˆ3Ý˜3 ‘O”O�M€GˆTØð 3ØÐ2Ð2˜'Ð2Ð2Ð2¨Ð2Ð2Ð2Ð2ØÐ"Ð"˜Ð"Ð"Ð"Ð"rM   r™   c              ƒ   óJ  ‡ K  — t           j                             ‰ ¦  «        d                              ¦   «         }|dk    rG	 dt          fˆ fd„}t          j        |¦  «        ƒ d{V —†}t          |¦  «        S # t          $ r Y nw xY w|dv rG	 dt          fˆ fd„}t          j        |¦  «        ƒ d{V —†}t          |¦  «        S # t          $ r Y nw xY w	 t          j	        dd	d
dddd‰ t
          j
        j        t
          j
        j        ¬¦
  «
        ƒ d{V —†}t          j        |                     ¦   «         d¬¦  «        ƒ d{V —†\  }}|j        dk    r@t          t	          |                     ¦   «                              ¦   «         ¦  «        ¦  «        S n# t          $ r Y nw xY wdS )zSBest-effort duration probe. Returns formatted MM:SS / HH:MM:SS, or None on failure.r(   z.wavr-   c                  óä   •— dd l } |                      ‰d¦  «        5 }|                     ¦   «         }|                     ¦   «         pd}|t	          |¦  «        z  cd d d ¦  «         S # 1 swxY w Y   d S )Nr   Úrbr(   )Úwaver™  Ú
getnframesÚgetframerateri  )r  ÚwfÚframesÚrater™   s       €r>   Ú_wav_durationz,_probe_audio_duration.<locals>._wav_duration  s°   ø€ Ø���Ø—Y’Y˜t TÑ*Ô*ð 0¨bØŸ]š]™_œ_�FØŸ?š?Ñ,Ô,Ð1°�DØ!¥E¨$¡K¤KÑ/ð0ð 0ð 0ð 0ñ 0ô 0ð 0ð 0ð 0ð 0ð 0ð 0øøøð 0ð 0ð 0ð 0ð 0ð 0s   œ<A%Á%A)Á,A)N)z.oggz.opusz.ogac                  óT   •— ddl m}  t           | ‰¦  «        j        j        ¦  «        S )Nr   )ÚOggOpus)Úmutagen.oggopusr  ri  rz  Úlength)r  r™   s    €r>   Ú_ogg_durationz,_probe_audio_duration.<locals>._ogg_duration+  s1   ø€ Ø3Ð3Ð3Ð3Ð3Ð3Ý˜W˜W T™]œ]Ô/Ô6Ñ7Ô7Ð7rM   Úffprobeú-vrP   z-show_entrieszformat=durationz-ofz"default=noprint_wrappers=1:nokey=1)ÚstdoutÚstderrr&   ©rÓ  r   )r’   r™   Úsplitextry   ri  ÚasyncioÚ	to_threadr  r2   Úcreate_subprocess_execÚ
subprocessÚPIPEÚwait_forÚcommunicateÚ
returncodeÚdecoderx   )r™   Úextr  r   r  Úprocr  rK  s   `       r>   Ú_probe_audio_durationr"    s7  øè è € å
Œ'×
Ò
˜4Ñ
 Ô
  Ô
#×
)Ò
)Ñ
+Ô
+€Cà
ˆf‚}€}ð
	ð0¥5ð 0ð 0ð 0ð 0ð 0ð 0õ !Ô*¨=Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9ˆDÝ# DÑ)Ô)Ð)øÝð 	ð 	ð 	ØˆDð	øøøð Ð'Ð'Ð'ð	ð8¥5ð 8ð 8ð 8ð 8ð 8ð 8õ !Ô*¨=Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9ˆDÝ# DÑ)Ô)Ð)øÝð 	ð 	ð 	ØˆDð	øøøð
ÝÔ3Ø�t˜W oÐ7HØÐ7¸ÝÔ%Ô*µ7Ô3EÔ3Jð
ñ 
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ˆõ
 "Ô*¨4×+;Ò+;Ñ+=Ô+=ÀsÐKÑKÔKÐKÐKÐKÐKÐKÐK‰	ˆ�ØŒ?˜aÒÐÝ#¥E¨&¯-ª-©/¬/×*?Ò*?Ñ*AÔ*AÑ$BÔ$BÑCÔCÐCð  øåð ð ð Øˆðøøøð ˆ4s7   Á5A8 Á8
BÂBÂ5C Ã
CÃCÃB=F Æ
F ÆF c                 ó,   — |                       |¦  «        S )z÷Consume and return the full pending event for a session.

    Queued follow-ups must preserve their media metadata so they can re-enter
    the normal image/STT/document preprocessing path instead of being reduced
    to a placeholder string.
    )Úget_pending_message)r1  r+   s     r>   Ú_dequeue_pending_eventr%  B  s   € ð ×&Ò& {Ñ3Ô3Ð3rM   zStop requestedzSession reset requestedz Execution timed out (inactivity)zSSE client disconnectedzGateway shutting downzGateway restarting)Úis_still_currentÚtask_idÚsourcer&  c                óž  — | sdS |�X	  |¦   «         st                                d| |¦  «         dS n.# t          $ r! t                                d| |d¬¦  «         Y nw xY wddlm} 	 |                     | ||¬¦  «        }n/# t          $ r" t                                d	| |d¬¦  «         Y dS w xY w|rt                                d
|| |¦  «         |S )u›  Reap only background processes created by one abandoned turn.

    ``task_id`` is session-scoped (task_id == session_id), not turn-scoped,
    so a *replacement* turn on the same session can start and spawn its own
    legitimate process while this reap is still in flight. ``is_still_current``
    â€” a closure over the run_generation captured when the reaping turn began
    or was interrupted â€” lets the caller detect that a newer turn has since
    claimed the session and bail out instead of killing that newer turn's
    process. The newer turn snapshots its own baseline independently, so
    skipping here does not leave anything permanently unreaped.
    r   NzdSkipping reap for turn %s (%s): a newer turn already claimed this session; it owns its own baseline.z>is_still_current check failed for turn %s (%s); reaping anywayTrß   ©Úprocess_registry©r(  z4Failed to reap background processes for turn %s (%s)zBReaped %d background process(es) created by abandoned turn %s (%s))r3   r4   r2   Útools.process_registryr+  Úkill_started_sincerã   )r'  Úprocess_baseliner(  r&  r+  Úkilleds         r>   Ú_reap_gateway_turn_processesr1  T  sk  € ð$ ð ð ˆqØÐ#ð	Ø#Ð#Ñ%Ô%ð Ý—’ðFàØñ	ô ð ð �qðøõ ð 	ð 	ð 	Ý�LŠLØPØØØð	 ñ ô ð ð ð ð	øøøð 8Ð7Ð7Ð7Ð7Ð7ðØ!×4Ò4ØØØð 5ñ 
ô 
ˆˆøõ
 ð ð ð õ
 	�ŠØBØØØð	 	ñ 	
ô 	
ð 	
ð ˆqˆqðøøøð ð 
Ý�ŠØPØØØñ		
ô 	
ð 	
ð €Ms!   ˆ&1 ±(AÁAÁ&A? Á?(B+Â*B+Úworker_doneÚtimeout_firedÚcleanup_lockc                 óô  — |5  |                      ¦   «         s|                      ¦   «         r	 ddd¦  «         dS |                     ¦   «          ddd¦  «         n# 1 swxY w Y   | r| d         nd}|�C	 t          |t          ¦  «         n,# t          $ r t
                               dd¬¦  «         Y nw xY w	 t          ||d|¬¦  «         n-# t          $ r  t
                               d	|d¬¦  «         Y nw xY wdS )
z@Interrupt one timed-out turn and reap only processes it created.NFr   z Timed-out agent interrupt failedTrß   Úgateway_turn_timeout©r(  r&  z9Failed to reap background processes for timed-out turn %s)	Úis_setr•   r   Ú_INTERRUPT_REASON_TIMEOUTr2   r3   r4   r1  rã   )Úagent_holderr'  r/  r2  r3  r4  r&  rµ   s           r>   Ú_abandon_timed_out_gateway_turnr;  ›  s´  € ð 
ð ð Ø×ÒÑÔð 	 =×#7Ò#7Ñ#9Ô#9ð 	Øðð ð ñ ô ð ð ð ð 	×ÒÑÔÐðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð
  ,Ð5ˆL˜ŒOˆO°€EØÐð	LÝ" 5Õ*CÑDÔDÐDÐDøÝð 	Lð 	Lð 	LÝ�LŠLÐ;ÀdˆLÑKÔKÐKÐKÐKð	Løøøð
Ý$ØØØ)Ø-ð		
ñ 	
ô 	
ð 	
ð 	
øõ ð 
ð 
ð 
Ý�ŠØGØØð 	ñ 	
ô 	
ð 	
ð 	
ð 	
ð
øøøð ˆ4s:   ƒ*AºAÁAÁ!AÁ4B
 Â
&B3Â2B3Â7C Ã'C5Ã4C5)Úpoll_intervalr&  r<  c        	   	      óV  — |                      t          d|¦  «        ¦  «        s…| r| d         nd}	|	�t          |	d¦  «        sŒB	 t          |	                     ¦   «                              dd¦  «        ¦  «        }
n# t          $ r Y Œ…w xY w|
|k     rŒ�t          | ||||||¬¦  «         dS dS )zFThread watchdog that remains runnable when gateway asyncio is starved.g{®Gáz„?r   NÚget_activity_summaryÚseconds_since_activityç        ©r:  r'  r/  r2  r3  r4  r&  )ÚwaitÚmaxrá   ri  r>  rv   r2   r;  )r:  r'  r/  rÓ  r2  r3  r4  r<  r&  rµ   Úidle_secondss              r>   Ú_watch_gateway_turn_inactivityrE  Â  sð   € ð ×Ò�s 4¨Ñ7Ô7Ñ8Ô8ð Ø#/Ð9�˜Q”�°TˆØˆ=¥¨Ð/EÑ FÔ Fˆ=Øð	Ý Ø×*Ò*Ñ,Ô,×0Ò0Ð1IÈ3ÑOÔOñô ˆLˆLøõ ð 	ð 	ð 	ØˆHð	øøøà˜'Ò!Ð!ØÝ'Ø%ØØ-Ø#Ø'Ø%Ø-ð	
ñ 	
ô 	
ð 	
ð 	ˆð+ð s   Á5A: Á:
BÂBc                 óÌ   — | sdS d                      t          | ¦  «                             ¦   «                              ¦   «         ¦  «                             ¦   «         }|t
          v S )z?Return True when an interrupt message is internal control flow.Fr™  )rf   rw   rx   re   ry   Ú_CONTROL_INTERRUPT_MESSAGES)r$  Ú
normalizeds     r>   Ú_is_control_interrupt_messagerI  ó  sV   € àð ØˆuØ—’�#˜g™,œ,×,Ò,Ñ.Ô.×4Ò4Ñ6Ô6Ñ7Ô7×=Ò=Ñ?Ô?€JØÕ4Ð4Ð4rM   Úresponsec                 óú   — |                      | ¦  «        \  }}|                     dd¦  «                             ¦   «         }|                     dd¦  «                             ¦   «         }|                     ¦   «         S )uï  Return the visible text portion of a response before direct send().

    Queued follow-up resends only replay explicit ``MEDIA:`` attachments in
    this path. Keep bare local paths and ordinary image URLs visible because
    the post-stream uploader intentionally ignores them (#20834).

    Do not apply a broad ``MEDIA:`` regex after ``extract_media()`` â€” the
    extractor deliberately preserves protected code/inline spans and
    unsupported or unvalidated tags in the cleaned text.
    r1  r®   ú[[as_document]])rH  rl  rx   )rJ  r1  rK  Úcleaneds       r>   Ú+_strip_response_attachments_for_direct_sendrN  û  si   € ð ×&Ò& xÑ0Ô0�J€A€wØ�oŠoÐ2°BÑ7Ô7×=Ò=Ñ?Ô?€GØ�oŠoÐ/°Ñ4Ô4×:Ò:Ñ<Ô<€GØ�=Š=‰?Œ?ÐrM   Úskill_mdc                 ó–  — 	 |                       dd¬¦  «        }n# t          $ r Y dS w xY w|                     d¦  «        }|                     d¦  «        sdS |                     dd¦  «        }|d	k     rdS d
}|d|…                              ¦   «         D ]¨}|                     ¦   «         }|                     d¦  «        r}|                     dd¦  «        d                              ¦   «         }t          |¦  «        dk    r&|d	         |d         k    r|d	         dv r
|dd…         }|                     ¦   «         } nŒ©|sdS | 	                    ¦   «          
                    dd¦  «         
                    dd¦  «        }d	d
l}|                     dd|¦  «        }|                     dd|¦  «                             d¦  «        }|sd
|fS ||fS )uÖ  Derive the /command slug and declared frontmatter name from a SKILL.md.

    Matches the exact normalization used by
    :func:`agent.skill_commands.scan_skill_commands` so the slug here is the
    same string a user types after the leading ``/`` (e.g. a skill with
    frontmatter ``name: Stable Diffusion Image Generation`` resolves to
    ``stable-diffusion-image-generation`` â€” NOT the parent directory name,
    which is commonly shorter/different, e.g. ``stable-diffusion``).

    Using the directory name silently broke :func:`_check_unavailable_skill`
    for every skill whose directory name drifted from its frontmatter name
    (19 such skills on a standard install as of 2026-05), causing a generic
    "unknown command" response where a "disabled â€” enable with â€¦" or
    "not installed â€” install with â€¦" hint was expected.

    Returns ``(slug, declared_name)`` or ``(None, None)`` when the file
    can't be read or lacks a ``name:`` in its frontmatter.
    úutf-8rl  )ÚencodingÚerrors©NNu   ï»¿z---z
---r)   r   Nzname:rÉ  r(   r|  r	  >   ú"ú'r™  Ú-rK  z
[^a-z0-9-]r®   z-{2,})Ú	read_textr2   r#  r!  r"  Ú
splitlinesrx   re   r7   ry   rl  r_   rõ   )rO  r4  r$  Údeclared_nameÚlinerx  ÚslugÚ_res           r>   Ú_skill_slug_from_frontmatterr^    sò  € ð&Ø×$Ò$¨g¸iÐ$ÑHÔHˆˆøÝð ð ð Øˆzˆzðøøøà�nŠn˜XÑ&Ô&€GØ×Ò˜eÑ$Ô$ð ØˆzØ
�,Š,�w Ñ
"Ô
"€CØ
ˆQ‚w€wØˆzØ $€MØ˜˜#˜”×)Ò)Ñ+Ô+ð ð ˆØ�zŠz‰|Œ|ˆØ�?Š?˜7Ñ#Ô#ð 	Ø—*’*˜S !Ñ$Ô$ QÔ'×-Ò-Ñ/Ô/ˆCå�3‰xŒx˜1Š}ˆ}  Q¤¨3¨r¬7Ò!2Ð!2°s¸1´vÀÐ7KÐ7KØ˜!˜B˜$”i�ØŸIšI™KœKˆMØˆEð	ð ð ØˆzØ×ÒÑ Ô ×(Ò(¨¨cÑ2Ô2×:Ò:¸3ÀÑDÔD€DàÐÐÐØ�7Š7�= " dÑ+Ô+€DØ�7Š7�8˜S $Ñ'Ô'×-Ò-¨cÑ2Ô2€DØð #Ø�]Ð"Ð"Ø�ÐÐs   ‚ š
(§(Úcommand_namec                 ó\  — |                       ¦   «                              dd¦  «        }	 ddlm} ddlm}m}  |¦   «         } |¦   «         D ]f}|                     ¦   «         sŒ|                     d¦  «        D ]9} ||¦  «        rŒt          |¦  «        \  }}	|r|	sŒ%||k    r|	|v r
d| › d�c c S Œ:Œgdd	l
m}
 t          t          ¦  «                             ¦   «         j        j        } |
|d
z  ¦  «        }|                     ¦   «         r�|                     d¦  «        D ]z} ||¦  «        rŒt          |¦  «        \  }}|sŒ#||k    rQ|j                             |¦  «        }t#          |j        ¦  «        }dd                     |¦  «        › �}d| › d|› d�c S Œ{n# t(          $ r Y nw xY wdS )u£  Check if a command matches a known-but-inactive skill.

    Returns a helpful message if the skill exists but is disabled or only
    available as an optional install. Returns None if no match found.

    The slug for each on-disk skill is derived from its frontmatter ``name:``
    (via :func:`_skill_slug_from_frontmatter`), NOT from its containing
    directory name â€” because the two can differ (e.g. directory
    ``stable-diffusion`` + frontmatter ``Stable Diffusion Image Generation``
    yields slug ``stable-diffusion-image-generation``). Matching on
    directory name would miss that slug entirely and fall through to the
    generic "unknown command" path.
    rK  rW  r   )Ú_get_disabled_skill_names)Úget_all_skills_dirsÚis_excluded_skill_pathzSKILL.mdúThe **zJ** skill is installed but disabled.
Enable it with: `hermes skills config`)Úget_optional_skills_dirzoptional-skillsz	official/r]  zQ** skill is available but not installed.
Install it with: `hermes skills install r  N)ry   rl  Útools.skills_toolra  Úagent.skill_utilsrb  rc  r˜   Úrglobr^  r¶  re  r   r�   r�   r‘   Úrelative_tor½  rg   rf   r2   )r_  rH  ra  rb  rc  ÚdisabledÚ
skills_dirrO  r\  rZ  re  Ú	repo_rootÚoptional_dirÚ	_declaredÚrelrg   Úinstall_paths                    r>   Ú_check_unavailable_skillrq  ?  s�  € ð ×#Ò#Ñ%Ô%×-Ò-¨c°3Ñ7Ô7€Jð,Ø?Ð?Ð?Ð?Ð?Ð?ØQÐQÐQÐQÐQÐQÐQÐQØ,Ð,Ñ.Ô.ˆð .Ð-Ñ/Ô/ð 	ð 	ˆJØ×$Ò$Ñ&Ô&ð ØØ&×,Ò,¨ZÑ8Ô8ð ð �Ø)Ð)¨(Ñ3Ô3ð ØÝ&BÀ8Ñ&LÔ&LÑ#��mØð  =ð Øð ˜:Ò%Ð%¨-¸8Ð*CÐ*CðB ð Bð Bð Bðð ð ð ð øðð 	=Ð<Ð<Ð<Ð<Ð<Ý�‘N”N×*Ò*Ñ,Ô,Ô3Ô:ˆ	Ø.Ð.¨yÐ;LÑ/LÑMÔMˆØ×ÒÑ Ô ð 	Ø(×.Ò.¨zÑ:Ô:ð ð �Ø)Ð)¨(Ñ3Ô3ð ØÝ">¸xÑ"HÔ"H‘��iØð ØØ˜:Ò%Ð%à"œ/×5Ò5°lÑCÔC�CÝ  ¤™OœO�EØ#@¨s¯xªx¸©¬Ð#@Ð#@�LðS ð Sð SØCOðSð Sð Sðð ð ð &øøõ ð ð ð Øˆðøøøàˆ4s   ªBF Â1C(F ÆF Æ
F)Æ(F)c                 ó4   — | t           j        k    rdn| j        S )uN   Map a Platform enum to its config.yaml key (LOCALâ†’"cli", restâ†’enum value).Úcli)rÄ  ÚLOCALr­   r…   s    r>   Ú_platform_config_keyru    s   € à¥¤Ò.Ð.ˆ5ˆ5°H´NÐBrM   c                  ó‚   — t          ¦   «         } t          | ddg ¬¦  «        }t          |t          ¦  «        sdS d|v pd|v S )zAReturn True when the standalone Teams pipeline plugin is enabled.ÚpluginsrÓ  ©rJ  FÚteams_pipelinezteams-pipeline)rs   r!   rt   r½  )rz   rÓ  s     r>   Ú_teams_pipeline_plugin_enabledrz  „  sP   € å!Ñ#Ô#€FÝ�f˜i¨¸BÐ?Ñ?Ô?€GÝ�g�tÑ$Ô$ð ØˆuØ˜wÐ&ÐEÐ*:¸gÐ*EÐErM   c                  óN   — t          ¦   «         } | rt          | ¦  «        S t          S )z<Return the Hermes home that gateway config reads should use.)ry  r   rl  )Úoverrides    r>   Ú_gateway_config_homer}  �  s'   € å'Ñ)Ô)€HØð Ý�H‰~Œ~ÐÝÐrM   c                  ó¢  — t          ¦   «         } | dz  }i }d}	 ddlm}m} | |¦   «         k    r |¦   «         }d}n# t          $ r Y nw xY w|sˆ	 |                     ¦   «         rEddl}t          |dd¬	¦  «        5 }|                     |¦  «        pi }ddd¦  «         n# 1 swxY w Y   n-# t          $ r  t           
                    d
|¦  «         i }Y nw xY w	 ddlm}  |j        t          |t          ¦  «        r|ni ¦  «        }n# t          $ r Y nw xY wt          |t          ¦  «        si S 	 ddlm}	  |	|¦  «        }n# t          $ r Y nw xY w|S )u  Load and parse ~/.hermes/config.yaml, returning {} on any error.

    Uses the module-level ``_hermes_home`` (so tests that monkeypatch it
    still see their fixture) and shares the mtime-keyed raw-yaml cache
    from ``hermes_cli.config.read_raw_config`` when the paths match.

    Managed scope is overlaid on the result (via the shared helper) so the
    gateway honors administrator-pinned values â€” neither read_raw_config nor a
    direct yaml.safe_load carries the managed merge on its own. Fail-open.
    r‹  Fr   )Úget_config_pathÚread_raw_configTNÚrrQ  ©rR  z%Could not load gateway config from %sr�  )Ú_normalize_root_model_keys)r}  r˜  r  r€  r2   r˜   Úyamlr™  Ú	safe_loadr3   r4   r™  r�  rš  rt   ru   rƒ  )
Úconfig_homer›  rx  Úused_canonicalr  r€  r„  Úfr�  rƒ  s
             r>   rs   rs   •  s/  € õ 'Ñ(Ô(€KØ Ñ-€KØ€CØ€Nð
ØFÐFÐFÐFÐFÐFÐFÐFð
 ˜/˜/Ñ+Ô+Ò+Ð+Ø!�/Ñ#Ô#ˆCØ!ˆNøøÝð ð ð Øˆðøøøð ð ð	Ø×!Ò!Ñ#Ô#ð 2Ø���Ý˜+ s°WÐ=Ñ=Ô=ð 2ÀØŸ.š.¨Ñ+Ô+Ð1¨r�Cð2ð 2ð 2ñ 2ô 2ð 2ð 2ð 2ð 2ð 2ð 2øøøð 2ð 2ð 2ð 2øøåð 	ð 	ð 	Ý�LŠLÐ@À+ÑNÔNÐNØˆCˆCˆCð	øøøðØ,Ð,Ð,Ð,Ð,Ð,Ø1ˆmÔ1½ÀCÍÑ9NÔ9NÐ2V°#°#ÐTVÑWÔWˆˆøÝð ð ð Øˆðøøøå�c�4Ñ Ô ð Øˆ	ðØ@Ð@Ð@Ð@Ð@Ð@Ø(Ð(¨Ñ-Ô-ˆˆøÝð ð ð Øˆðøøøà€Jsi   ™"< ¼
A	ÁA	Á*B) Á9BÂB) ÂB!Â!B) Â$B!Â%B) Â)'CÃCÃ-D Ä
DÄDÄ-D? Ä?
EÅEc                 ó¸  — t          | t          ¦  «        r|                      di ¦  «        ni }t          |t          ¦  «        rd|i}nt          |t          ¦  «        si }ddlm} |d         }|                     d|d         ¦  «        |                     d|d         ¦  «        |                     d|d         ¦  «        |                     d|d         ¦  «        dœS )	a,  Translate gateway checkpoint config into ``AIAgent`` constructor args.

    The gateway reads raw YAML instead of ``load_config()``, so checkpoint
    defaults must be supplied here.  Keep legacy ``checkpoints: true`` configs
    working while giving every gateway-created agent the same limits.
    ÚcheckpointsrÓ  r   rÈ  Úmax_snapshotsÚmax_total_size_mbÚmax_file_size_mb)Úcheckpoints_enabledÚcheckpoint_max_snapshotsÚcheckpoint_max_total_size_mbÚcheckpoint_max_file_size_mb)rt   ru   rv   rº   r˜  rÉ  )rz   Úcp_cfgrÉ  Údefaultss       r>   Ú_checkpoint_agent_kwargsr”  Ó  sø   € õ /9¸ÅÑ.FÔ.FÐNˆV�ZŠZ˜ rÑ*Ô*Ð*ÈB€FÝ�&�$ÑÔð Ø˜VÐ$ˆˆÝ˜¥Ñ%Ô%ð Øˆà0Ð0Ð0Ð0Ð0Ð0Ø˜mÔ,€Hà%Ÿzšz¨)°X¸iÔ5HÑIÔIØ$*§J¢JØ˜X oÔ6ñ%
ô %
ð )/¯
ª
Ø Ð*=Ô!>ñ)
ô )
ð (.§z¢zØ Ð);Ô <ñ(
ô (
ðð ð rM   c                  ó¤   — t          ¦   «         } t          | t          ¦  «        r| si S ddlm}  || ¦  «        }t          |t          ¦  «        r|ni S )u  Load gateway config for runtime reads, expanding supported ``${VAR}`` refs.

    Runtime helpers should honor the same env-template expansion documented for
    ``config.yaml`` while still respecting tests that monkeypatch
    ``gateway.run._hermes_home``. Build on ``_load_gateway_config()`` rather
    than calling the canonical loader directly so both behaviors stay aligned.

    Expansion failures are intentionally NOT swallowed â€” silently returning
    the unexpanded dict would mask the very bug this helper exists to fix.
    r   ©r�  )rs   rt   ru   r˜  r�  )rœ  r�  Úexpandeds      r>   rÏ  rÏ  ð  sh   € õ Ñ
 Ô
 €CÝ�c�4Ñ Ô ð ¨ð Øˆ	Ø2Ð2Ð2Ð2Ð2Ð2àÐ Ñ$Ô$€HÝ! (­DÑ1Ô1Ð9ˆ8ˆ8°rÐ9rM   c                 ó  — | �| nt          ¦   «         }|                     di ¦  «        }t          |t          ¦  «        r|S t          |t          ¦  «        r,|                     d¦  «        p|                     d¦  «        pdS dS )uÝ   Read model from config.yaml â€” single source of truth.

    Without this, temporary AIAgent instances (e.g. /compress) fall
    back to the hardcoded default which fails when the active provider is
    openai-codex.
    Nr  rJ  r®   )rs   rv   rt   rw   ru   )rz   rœ  rÂ  s      r>   Ú_resolve_gateway_modelr™    s…   € ð Ð&ˆ&ˆ&Õ,@Ñ,BÔ,B€CØ—’˜ Ñ$Ô$€IÝ�)�SÑ!Ô!ð HØÐÝ	�I�tÑ	$Ô	$ð HØ�}Š}˜YÑ'Ô'ÐG¨9¯=ª=¸Ñ+AÔ+AÐGÀRÐGØˆ2rM   ©Ú	thread_idÚ	parent_idr›  rœ  c                ó¸   — g }t          ¦   «         }| ||fD ]C}|sŒt          |¦  «        }||v rŒ|                     |¦  «         |                     |¦  «         ŒD|S )záOrdered, de-duplicated keys for ``channel_overrides`` lookup.

    Matches ``resolve_channel_prompt`` semantics: exact thread/channel id first,
    then parent channel/forum id (Discord threads inherit parent overrides).
    )r•   rw   r—   r”   )r2  r›  rœ  Úkeysr¢   r  Úsks          r>   Ú_channel_override_lookup_keysr     so   € ð €DÝ‘U”U€DØ˜ IÐ.ð ð ˆØð 	ØÝ�‰XŒXˆØ�ˆ:ˆ:ØØ�Š�‰ŒˆØ�Š�B‰ŒˆˆØ€KrM   c                óÞ   — t          | dd¦  «        }|sdS |                     |¦  «        }|r|j        sdS |j        }t          |||¬¦  «        D ]}|                     |¦  «        }	|	�|	c S ŒdS )zÞReturn per-channel override for this platform/chat_id, or None.

    Looks up ``channel_overrides`` by ``chat_id``, then ``thread_id``, then
    ``parent_id`` (forum threads / child channels inherit the parent entry).
    rE  Nrš  )rV   rv   Úchannel_overridesr   )
rz   r�   r2  r›  rœ  rE  rÀ  Ú	overridesr  Úovs
             r>   Ú_get_channel_overrider¥  ,  s¢   € õ ˜ ¨TÑ2Ô2€IØð ØˆtØ—m’m HÑ-Ô-€OØð  /Ô"Cð ØˆtØÔ1€IÝ,Ø˜9°	ðñ ô ð ð ˆð �]Š]˜3ÑÔˆØˆ>ØˆIˆIˆIð àˆ4rM   c                  óÀ   — ddl } |                      d¦  «        }|r|gS 	 ddl}|j                             d¦  «        �t
          j        ddgS n# t          $ r Y nw xY wdS )us  Resolve the Hermes update command as argv parts.

    Tries in order:
    1. ``shutil.which("hermes")`` â€” standard PATH lookup
    2. ``sys.executable -m hermes_cli.main`` â€” fallback when Hermes is running
       from a venv/module invocation and the ``hermes`` shim is not on PATH

    Returns argv parts ready for quoting/joining, or ``None`` if neither works.
    r   NÚhermesr™  z-mzhermes_cli.main)ÚshutilÚwhichÚimportlib.utilÚutilÚ	find_specrŽ   Ú
executabler2   )r¨  Ú
hermes_binÚ	importlibs      r>   Ú_resolve_hermes_binr°  I  s‘   € ð €M€M€Mà—’˜hÑ'Ô'€JØð Øˆ|ÐðØÐÐÐàŒ>×#Ò# LÑ1Ô1Ð=Ý”N DÐ*;Ð<Ð<ð >øåð ð ð Øˆðøøøð ˆ4s    ,A Á
AÁAzdict | Nonec                 ó
  — |                       d¦  «        }t          |¦  «        dk    rZ|d         dk    rN|d         dk    rB|d         |d         |d	         d
œ}t          |¦  «        dk    r|d         dv r|d         |d<   |S dS )a@  Parse a session key into its component parts.

    Session keys follow the format
    ``agent:main:{platform}:{chat_type}:{chat_id}[:{extra}...]``.
    Returns a dict with ``platform``, ``chat_type``, ``chat_id``, and
    optionally ``thread_id`` keys, or None if the key doesn't match.

    The 6th element is only returned as ``thread_id`` for chat types where
    it is unambiguous (``dm`` and ``thread``).  For group/channel sessions
    the suffix may be a user_id (per-user isolation) rather than a
    thread_id, so we leave ``thread_id`` out to avoid mis-routing.
    rÉ  é   r   rµ   r(   Úmainr|  r)   r  )r�   Ú	chat_typer2  >   ÚdmÚthreadr›  N)re   r7   )r+   rg   Úresults      r>   Ú_parse_session_keyr¸  d  s›   € ð ×Ò˜cÑ"Ô"€EÝ
ˆ5�z„z�Q‚€˜5 œ8 wÒ.Ð.°5¸´8¸vÒ3EÐ3Eà˜aœØ˜qœØ˜Q”xð
ð 
ˆõ
 ˆu‰:Œ:˜Š>ˆ>˜e AœhÐ*:Ð:Ð:Ø"'¨¤(ˆF�;ÑØˆØˆ4rM   Úevtc                 óÈ  — |                       dd¦  «        }|                       dd¦  «        }|                       dd¦  «        }|dk    rd|                       dd	¦  «        › d
�S |dk    rb|                       dd¦  «        }|                       dd	¦  «        }|                       dd¦  «        }d|› d|› d|› d|› �}|r	|d|› d�z  }|d
z  }|S |dk    rddlm}  || ¦  «        S dS )zOFormat a watch pattern event from completion_queue into a [IMPORTANT:] message.rÎ   Ú
completionrN   Úunknownr   Úwatch_disabledz[IMPORTANT: r$  r®   rš  Úwatch_matchr÷   ú?ÚoutputÚ
suppressedr   z[IMPORTANT: Background process z matched watch pattern "z".
Command: z
Matched output:
z
(z/ earlier matches were suppressed by rate limit)Úasync_delegation)Úformat_process_notificationN)rv   r-  rÃ  )	r¹  Úevt_typeÚ_sidÚ_cmdÚ_patÚ_outÚ_suprè   rÃ  s	            r>   Ú$_format_gateway_process_notificationrÊ  ~  sL  € à�wŠw�v˜|Ñ,Ô,€HØ�7Š7�< Ñ+Ô+€DØ�7Š7�9˜iÑ(Ô(€DàÐ#Ò#Ð#Ø7˜cŸgšg i°Ñ4Ô4Ð7Ð7Ð7Ð7à�=Ò Ð Ø�wŠw�y #Ñ&Ô&ˆØ�wŠw�x Ñ$Ô$ˆØ�wŠw�| QÑ'Ô'ˆð'¨dð 'ð 'Ø#ð'ð 'àð'ð 'ð !%ð'ð 'ð 	ð ð 	PØÐO˜$ÐOÐOÐOÑOˆDØ�‰ˆØˆàÐ%Ò%Ð%àFÐFÐFÐFÐFÐFØ*Ð*¨3Ñ/Ô/Ð/àˆ4rM   ú
list[dict]c                 ót  — g }g }|                       ¦   «         s…	 |                      ¦   «         }n# t          $ r Y ncw xY w|                     dd¦  «        }|dv r|                     |¦  «         n|dk    r|                     |¦  «         |                       ¦   «         ¯…|D ]}|                      |¦  «         Œ|S )a÷  Drain gateway-owned watch events without spinning on requeued events.

    Watch events are handled by the post-turn gateway drain. Process
    completions are owned by their per-process watcher task, and async
    delegation completions are owned by ``_async_delegation_watcher``.
    Requeueing async events inside ``while not queue.empty()`` would make the
    loop non-terminating, so detach the current batch first, then requeue any
    events this drain does not own after the queue is empty.
    rÎ   r»  >   r¾  r½  rÂ  )ÚemptyÚ
get_nowaitr2   rv   r”   Úput)Úcompletion_queueÚwatch_eventsÚrequeuer¹  rÄ  s        r>   Ú_drain_gateway_watch_eventsrÓ  ž  sò   € ð  "€LØ€GØ×$Ò$Ñ&Ô&ð 	 ð	Ø"×-Ò-Ñ/Ô/ˆCˆCøÝð 	ð 	ð 	ØˆEð	øøøà—7’7˜6 <Ñ0Ô0ˆØÐ8Ð8Ð8Ø×Ò Ñ$Ô$Ð$Ð$ØÐ+Ò+Ð+Ø�NŠN˜3ÑÔÐð ×$Ò$Ñ&Ô&ð 	 ð ð "ð "ˆØ×Ò˜SÑ!Ô!Ð!Ð!ØÐs   š/ ¯
<»<c                  ó   — d S r^   rN  rN  rM   r>   rò   rò   ¾  s   € ¨D€ rM   Ú_gateway_runner_ref©Úhistory_lenÚagent_resultr×  c                óÆ  ‡— |r|S |                       d¦  «        rÙ|                       d¦  «        pd}t          |¦  «                             ¦   «         Št          |                       d¦  «        pd¦  «        }|                     d¦  «        sd‰v r|                     d¦  «        sd	‰v r	 d
S 	 dS t          ˆfd„dD ¦   «         ¦  «        p	d‰v o|dk    }|r	 dS dt          |¦  «        dd…         › d�S t          |                       dd¦  «        pd¦  «        }|                       d¦  «        r|dk    r	 dS |S |dk    rZt          | ¦  «        rdS |                       d¦  «        r1|                       dd¦  «        }dt          |¦  «        dd…         › d�S 	 dS |dk    rB|                       d¦  «        s-|                       d¦  «        s|                       d¦  «        s	 dS |S ) a>  Normalize empty/None agent responses into user-facing messages.

    Consolidates the existing ``failed`` handler and adds a catch-all for
    the case where the agent did work (api_calls > 0) but returned no text.
    Fix for #18765.

    Also surfaces a retry hint when the agent never ran at all
    (api_calls == 0) for a non-interrupted, non-failed turn -- this is the
    silent-drop pattern observed after ``/stop`` where the next user
    message hits a stale generation token and returns an empty result,
    leaving the platform with nothing to send. (#31884)
    ÚfailedrP   úunknown errorÚfailure_reasonr®   Úsession_persistence_failedzsession storagez:diskÚdisku³   âš ï¸� Session storage was temporarily unavailable, so this turn was stopped to protect your conversation history. Please check available disk space, then send your message again.u½   âš ï¸� Session storage was temporarily unavailable, so this turn was stopped to protect your conversation history. Your message should already be saved â€” please send it again in a moment.c              3   ó    •K  — | ]}|‰v V — Œ	d S r^   rN  )rb   r;  Ú	error_strs     €r>   rd   z2_normalize_empty_agent_response.<locals>.<genexpr>ò  s;   øè è € ð !
ð !
àð �ˆNð!
ð !
ð !
ð !
ð !
ð !
rM   )rÙ   rÄ  z	too largeztoo longÚexceedr@  Ú400é2   õ}   âš ï¸� Session too large for the model's context window.
Use /compact to compress the conversation, or /reset to start fresh.zThe request failed: Né,  ú2
Try again or use /reset to start a fresh session.Ú	api_callsr   Úinterrupteduo   âš ï¸� Your message was interrupted before processing started (likely by a recent /stop). Please send it again.Úpartialúprocessing incompleteu   âš ï¸� Processing stopped: r  z. Try again.u|   âš ï¸� Processing completed but no response was generated. This may be a transient error â€” try sending your message again.uj   âš ï¸� Your message wasn't processed (the previous turn was still being cleaned up). Please send it again.)rv   rw   ry   r!  Úendswithr
  rh  Ú,_is_gateway_hidden_reasoning_incomplete_turn)	rØ  rJ  r×  Úerror_detailrÜ  Úis_context_failurerç  Úerrrà  s	           @r>   Ú_normalize_empty_agent_responserð  Á  sµ  ø€ ð$ ð Øˆà×Ò˜Ñ!Ô!ð )
ð
 $×'Ò'¨Ñ0Ô0ÐC°OˆÝ˜Ñ%Ô%×+Ò+Ñ-Ô-ˆ	õ
 ˜\×-Ò-Ð.>Ñ?Ô?ÐEÀ2ÑFÔFˆØ×$Ò$Ð%AÑBÔBð 	Ø Ð*Ð*à×&Ò& wÑ/Ô/ð °6¸YÐ3FÐ3Fð%ðð ð%ðð õ !ð !
ð !
ð !
ð !
àWð!
ñ !
ô !
ñ 
ô 
ð 7ð �yÐ Ð5 [°2Ò%5ð 	ð ð 	ð)ðð ð@¥3 |Ñ#4Ô#4°T°c°TÔ#:ð @ð @ð @ð	
õ
 �L×$Ò$ [°!Ñ4Ô4Ð9¸Ñ:Ô:€IØ×Ò˜Ñ&Ô&ð ð ˜Š>ˆ>ðDðð ð ˆØ�1‚}€}Ý7¸ÑEÔEð 	Ø�2Ø×Ò˜IÑ&Ô&ð 	NØ×"Ò" 7Ð,CÑDÔDˆCØMµ°S±´¸$¸3¸$´ÐMÐMÐMÐMðPð	
ð 	
ð 	�QŠˆØ× Ò  Ñ/Ô/ð 	à× Ò  Ñ*Ô*ð 	ð × Ò  Ñ+Ô+ð 	ð7ð	
ð 	
ð
 €OrM   c                 óÒ  — t          | t          ¦  «        sdS |                      d¦  «        s|                      d¦  «        rdS |                      d¦  «        sdS t          |                      dd¦  «        pd¦  «                             ¦   «         }d|                     ¦   «         vrdS t          |                      d¦  «        pd¦  «                             ¦   «         }| p||k    S )	uJ  Detect retry-exhausted turns with hidden reasoning but no visible answer.

    The conversation loop returns the retry-exhaustion sentinel as BOTH
    ``final_response`` and ``error`` ("Codex response remained incomplete
    after 3 continuation attempts"), so ``final_response`` being non-empty
    does not mean the model produced a visible answer. Treat the turn as
    hidden when the error sentinel is present and ``final_response`` is
    either empty or merely echoes that sentinel â€” any genuinely different
    final text means the model DID answer and must be delivered.
    FrÚ  rè  ré  rP   r®   zremained incomplete afterÚfinal_response)rt   ru   rv   rw   rx   ry   )rØ  Ú
error_textrò  s      r>   rì  rì  /  sð   € õ �l¥DÑ)Ô)ð ØˆuØ×Ò˜Ñ!Ô!ð  \×%5Ò%5°mÑ%DÔ%Dð ØˆuØ×Ò˜IÑ&Ô&ð ØˆuÝ�\×%Ò% g¨rÑ2Ô2Ð8°bÑ9Ô9×?Ò?ÑAÔA€JØ"¨*×*:Ò*:Ñ*<Ô*<Ð<Ð<ØˆuÝ˜×)Ò)Ð*:Ñ;Ô;ÐA¸rÑBÔB×HÒHÑJÔJ€NØÐÐ= °:Ò!=Ð=rM   c                 ó  — t          | t          ¦  «        sdS |                      d¦  «        rdS |                      d¦  «        s*|                      d¦  «        s|                      d¦  «        rdS |                      d¦  «        du rdS dS )a¡  Return True only when a gateway turn really completed successfully.

    Restart recovery uses ``resume_pending`` as a durable marker for sessions
    interrupted during gateway drain.  A soft interrupt can still bubble out as
    a syntactically normal agent result with an empty final response; clearing
    the marker in that case loses the recovery signal and startup auto-resume
    has nothing to schedule.
    Frè  rÚ  ré  rP   Ú	completedTrF  )rØ  s    r>   Ú'_should_clear_resume_pending_after_turnrö  G  sŸ   € õ �l¥DÑ)Ô)ð ØˆuØ×Ò˜Ñ&Ô&ð ØˆuØ×Ò˜Ñ!Ô!ð  \×%5Ò%5°iÑ%@Ô%@ð ÀL×DTÒDTÐU\ÑD]ÔD]ð ØˆuØ×Ò˜Ñ$Ô$¨Ð-Ð-ØˆuØˆ4rM   Úcurrent_resultÚfollowup_resultc                 óF  — t          |t          ¦  «        s|S t          | t          ¦  «        s|S |                      d¦  «        }|                     d¦  «        }t          |t          ¦  «        s|S t          |t          ¦  «        r||k    r|S t          |¦  «        }||d<   |S )ae  Carry the outer history offset through queued follow-up drains.

    ``_process_message_background()`` persists transcript rows only once, after the
    entire in-band queued-follow-up chain returns.  Each recursive ``_run_agent()``
    call advances ``history_offset`` to the history it received, so without
    correction the outermost persistence step sees only the *last* queued turn as
    "new" and silently drops earlier turns from the same drain chain.

    Preserve the earliest (outermost) history offset so the final transcript slice
    still includes every queued turn that ran during the chain.
    r)  )rt   ru   rv   rh  )r÷  rø  Úcurrent_offsetÚfollowup_offsetr³   s        r>   Ú(_preserve_queued_followup_history_offsetrü  [  s³   € õ �o¥tÑ,Ô,ð ØÐÝ�n¥dÑ+Ô+ð ØÐà#×'Ò'Ð(8Ñ9Ô9€NØ%×)Ò)Ð*:Ñ;Ô;€OÝ�n¥cÑ*Ô*ð ØÐÝ�/¥3Ñ'Ô'ð ¨O¸~Ò,MÐ,MØÐå�/Ñ"Ô"€FØ-€FÐÑØ€MrM   r1  úBasePlatformAdapter | Nonec              ƒ   óæ   K  — | €dS 	 |                       ¦   «         ƒ d{V —† dS # t          $ rB t                               dt	          | dt          | ¦  «        j        ¦  «        d¬¦  «         Y dS w xY w)uT  Best-effort dispose for an adapter that never made it onto ``self.adapters``.

    The reconnect watcher in ``GatewayRunner._platform_reconnect_watcher``
    constructs a fresh adapter on every retry attempt. When the connect
    call fails â€” for any of the three reasons (non-retryable error,
    retryable error, exception during connect) â€” the adapter is dropped
    without ever being installed, so nothing else will call its
    ``disconnect()``. Any resources the adapter opened in ``__init__``
    (e.g. ``APIServerAdapter`` opens a SQLite ``ResponseStore`` that
    holds 2 fds â€” the db file and its WAL sidecar) stay open until
    garbage collection sweeps the unreachable object, which Python's
    cyclic GC does not do promptly for asyncio-bound objects with
    native handles. The cumulative leak is 2 fds Ã— every retry at the
    300s backoff cap â‰ˆ 12 fds/hour, and the default 2560-fd ulimit
    is exhausted in ~12h of continuous failure, after which every
    open() call on the gateway raises ``OSError: [Errno 24] Too many
    open files`` and the gateway becomes a zombie (#37011).

    This helper centralises the dispose-with-suppression so the three
    failure paths in the reconnect watcher can all call it without
    each one having to know that ``disconnect()`` may itself raise
    on a half-constructed adapter.

    ``adapter`` may be ``None``: the reconnect watcher initialises
    ``adapter = None`` before the ``try`` so the ``except Exception``
    arm can dispose a half-constructed object, and also early-returns
    here when ``_create_adapter()`` returned ``None``.
    Nz,Adapter dispose raised on unowned adapter %rrÖ   Trß   )Ú
disconnectr2   r3   r4   rV   rÎ   rÏ   ©r1  s    r>   Ú_dispose_unused_adapterr  {  s¦   è è € ð: €Øˆð
Ø× Ò Ñ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"Ð"Ð"Ð"øÝð 
ð 
ð 
õ 	�ŠØ:Ý�G˜V¥T¨'¡]¤]Ô%;Ñ<Ô<Øð 	ñ 	
ô 	
ð 	
ð 	
ð 	
ð 	
ð
øøøs   ˆ$ ¤AA0Á/A0rå  Úattemptc                 ó>   — t          dd| dz
  z  z  t          ¦  «        S )zCExponential reconnect backoff: 30s, 60s, 120s, ... capped at 5 min.é   r|  r(   )r6   Ú_RECONNECT_BACKOFF_CAP)r  s    r>   Ú_reconnect_backoffr  ¶  s!   € åˆr�Q˜7 Q™;Ñ'Ñ(Õ*@ÑAÔAÐArM   c            	       ó–   — e Zd ZdZdddeddfd„Zdded	ed
edefd„Zd„ Z	d„ Z
dededdfd„Zdededdfd„Zdd„Zdededdfd„Zd„ ZdS )Ú
TurnRunnera   Per-turn collaborator carrying the tool-progress callbacks that used to
    be nested closures inside ``GatewayRunner._run_agent_inner``.

    The bodies are byte-identical to the original closures modulo
    ``local_name`` -> ``ctx.field`` rewrites (closed-over locals now travel on
    the shared :class:`gateway.turn_context.TurnContext`) and ``self`` ->
    ``self._runner`` (the owning :class:`GatewayRunner`). Module-global
    references (logger, cfg_get, BasePlatformAdapter, ...) resolve in this
    same module exactly as before.
    ÚrunnerÚGatewayRunnerÚctxr-   Nc                 ó"   — || _         || _        d S r^   )Ú_runnerÚ_ctx)Úselfr	  r  s      r>   Ú__init__zTurnRunner.__init__Ç  s   € ØˆŒØˆŒ	ˆ	ˆ	rM   r#  r?  Úpreviewr¸  c                 óÆ  — | j         }|j        �Ñ|j        dk    rÆ|dk    rÀ	 |dk    r[|rY|                     ¦   «         rEddlm}  |||j        dk    r|nd¦  «        }|j                             |j        j        |¦  «         n+|dk    r%|j                             |j        j        d¦  «         n2# t          $ r%}	t                               d	|	¦  «         Y d}	~	nd}	~	ww xY w|j        �{|dk    rl|rj|dk    rdt          j        ¦   «                              d
¦  «        }
|rd|› d�nd}|j                             |
› d|› d|› �                     ¦   «         ¦  «         |j        sdS |j        r|                     ¦   «         sdS |dk    rø|j        d         së	 |                     d¦  «        pd}||j        k    r“|j        dk    rˆddlm}m}m}m} t9          ¦   «         }t;          t=          |dd¦  «        d¬¦  «        }|rL |||¦  «        s@d|j        d<   |j                              |¦   «         ¦  «          |t>          dz  |¦  «         n2# t          $ r%}t                               d|¦  «         Y d}~nd}~ww xY wdS |dk    s|dk    r:|j         sdS |dk    r|n|}|rd|› �nd}|r|j                             |¦  «         dS |j!        sdS |dvrdS |dk    rdS 	 |j"        r|j"        d         nd}|�tG          |dd¦  «        rdS n# t          $ r Y nw xY w|j        dk    r||j$        d         k    rdS ||j$        d<   ddlm%}  ||d ¬¦  «        }d}d}	 | j&         '                    |j        ¦  «        }n# t          $ r d}Y nw xY wtG          |d!d¦  «        �r|d"k    �rtQ          |tR          ¦  «        rûtQ          |                     d#¦  «        tT          ¦  «        rÓ|d#          +                    ¦   «         r¹dd$lm,} |d#                              ¦   «         }|j-        d         rdn|› d%|› d&�}|› d'|› d(�} |¦   «         }|dk    r|nd)} | .                    ¦   «         }!|!r|!d         n|}"t_          |!¦  «        d*k    }#t_          |"¦  «        | k    r|"d| d+z
  …         d,z   }"n|#r|"d-z   }"|› d'|"› d(�}|j        d.k    rè|�&d|j-        d<   |j                             |¦  «         dS d|j-        d<   |r‚dd$lm,}  |¦   «         }ta          j1        |dtT          ¬/¦  «        }$|dk    r#t_          |$¦  «        |k    r|$d|d+z
  …         d,z   }$|› d%|› d0te          | 3                    ¦   «         ¦  «        › d1|$› �}n|r|› d%|› d2|› d�}n|› d%|› d,�}|j                             |¦  «         dS |�|}d|j-        d<   n¯|r›dd3lm,}m4}%m5}&m6}'m7}(  |¦   «         }|dk    r|nd)}  |&|||| ¬4¦  «        })|�| 8                    |)¦  «        }n|)j9        } |%|¦  «        }*|*r( |(|¦  «        r|› d%|*› �}n |› d%|*›  |'|¦  «        › |› �}n|› d%|› d2|› d�}d|j-        d<   n|› d%|› d,�}d|j-        d<   ||j:        d         k    r?|j;        dxx         d*z  cc<   |j                             d5||j;        d         f¦  «         dS ||j:        d<   d|j;        d<   |j                             |¦  «         dS )6z3Callback invoked by agent on tool lifecycle events.NÚoffÚ	_thinkingútool.startedr   )Úbuild_status_phraseÚfullztool.completedzlive status update failed: %sz%Y-%m-%d %H:%M:%Sz "rU  r®   z  rÉ  Údurationr�  )ÚTOOL_PROGRESS_FLAGÚis_seenÚ	mark_seenÚtool_progress_hint_gatewayrD  Útool_progress_commandFrx  Tr‹  z(tool-progress onboarding hint failed: %su   ðŸ’¬ >   r  ÚclarifyÚis_interruptedÚnew)Úget_tool_emojiu   âš™ï¸�Úsupports_code_blocksrÌ  r   )Úget_tool_preview_max_lenr™  r  ú```
ú
```é(   r(   r)   r  z ...Úverbose)Úensure_asciirJ  ú(z)
z: ")r#  Úget_tool_verbÚprepare_tool_previewÚtool_verb_connectorÚverb_drops_preview)ÚfallbackÚmax_lenÚ	__dedup__)<r  Ú_live_status_adapterÚ_live_status_modeÚ_run_still_currentÚagent.displayr  Úset_status_textr(  r2  r2   r3   r4   Ú	log_queuer   rŒ  ÚstrftimerÏ  r  Úprogress_queueÚlong_tool_hint_firedrv   Ú_LONG_TOOL_THRESHOLD_SÚprogress_modeÚagent.onboardingr  r  r  r  rs   r{  r!   rl  Ú_thinking_enabledÚtool_progress_enabledr:  rV   Ú	last_toolr!  r  Ú_adapter_for_sourcert   ru   rw   rx   r#  Úlast_was_terminal_blockrY  r7   r3  Údumpsr½  rž  r*  r+  r,  r-  Úformat_tool_previewrè   Úlast_progress_msgÚrepeat_count)+r  r#  r?  r  r¸  Úkwargsr  r  Ú_phraseÚ_ls_errr²  Úpreview_strr  r  r  r  r  rF  Úgate_onÚ	_hint_errÚthinking_textr§  Ú_agent_for_interruptr!  ÚemojiÚ_code_block_fullÚ_code_block_shortÚ_progress_adapterr#  Ú	_cmd_fullÚ_block_headerÚ_plÚ_capÚ_linesÚ
_cmd_shortÚ
_multilineÚargs_strr*  r+  r,  r-  Ú_prepared_previewÚ_verbs+                                              r>   Úprogress_callbackzTurnRunner.progress_callbackË  s
  € àŒiˆð Ô$Ð0ØÔ%¨Ò.Ð.Ø˜[Ò(Ð(ðGØ Ò/Ð/°IÐ/À#×BXÒBXÑBZÔBZÐ/ØAÐAÐAÐAÐAÐAØ1Ð1Ø!Ø #Ô 5¸Ò ?Ð ?˜˜ÀTñô �Gð Ô,×<Ò<¸S¼ZÔ=OÐQXÑYÔYÐYÐYØÐ#3Ò3Ð3ð Ô,×<Ò<¸S¼ZÔ=OÐQUÑVÔVÐVøøÝð Gð Gð GÝ—’Ð<¸gÑFÔFÐFÐFÐFÐFÐFÐFøøøøðGøøøð
 Œ=Ð$Ø˜^Ò+Ð+°	Ð+¸iÈ;Ò>VÐ>VÝ”\‘^”^×,Ò,Ð-@ÑAÔA�Ø18Ð@˜o 7˜o˜o˜o˜o¸b�Ø”×!Ò! RÐ"DÐ"D¨9Ð"DÐ"D°{Ð"DÐ"D×"KÒ"KÑ"MÔ"MÑNÔNÐNØÔ%ð Ø�ØÔ!ð 	¨×)?Ò)?Ñ)AÔ)Að 	ØˆFð Ð)Ò)Ð)°#Ô2JÈ1Ô2MÐ)ðTØ!Ÿ:š: jÑ1Ô1Ð6°Q�Ø˜sÔ9Ò9Ð9¸cÔ>OÐSXÒ>XÐ>Xðð ð ð ð ð ð ð ð ð ð ð õ 0Ñ1Ô1�DÝ-Ý  iÐ1HÑIÔIØ %ðñ ô �Gð ð T w w¨tÐ5GÑ'HÔ'Hð TØ6:˜Ô0°Ñ3ØÔ*×.Ò.Ð/IÐ/IÑ/KÔ/KÑLÔLÐLØ!˜	¥,°Ñ">Ð@RÑSÔSÐSøøÝð Tð Tð TÝ—’ÐGÈÑSÔSÐSÐSÐSÐSÐSÐSøøøøðTøøøàˆFð ˜Ò$Ð$¨	°[Ò(@Ð(@ØÔ(ð Ø�Ø'0°KÒ'?Ð'?˜G˜GÀYˆMØ-:ÐDÐ)˜-Ð)Ð)Ð)ÀˆCØð ,ØÔ"×&Ò& sÑ+Ô+Ð+ØˆFð Ô(ð 	ØˆFð Ð.Ð.Ð.ØˆFð ˜	Ò!Ð!ØˆFð	Ø:=Ô:JÐ#T 3Ô#3°AÔ#6Ð#6ÐPTÐ Ø#Ð/µGØ$Ð&6¸ñ5ô 5Ð/ð �øøÝð 	ð 	ð 	ØˆDð	øøøð Ô Ò%Ð%¨)°s´}ÀQÔ7GÒ*GÐ*GØˆFØ$ˆŒ�aÑð 	1Ð0Ð0Ð0Ð0Ð0Ø�˜y°(Ð;Ñ;Ô;ˆð  ÐØ Ðð	%Ø $¤× @Ò @ÀÄÑ LÔ LÐÐøÝð 	%ð 	%ð 	%Ø $ÐÐÐð	%øøøõ Ð%Ð'=¸uÑEÔEñ	Ià˜ZÒ'Ñ'Ý˜4¥Ñ&Ô&ð (å˜4Ÿ8š8 IÑ.Ô.µÑ4Ô4ð (ð �Y”×%Ò%Ñ'Ô'ð (ð
 ?Ð>Ð>Ð>Ð>Ð>Ø˜Yœ×.Ò.Ñ0Ô0ˆIð
 Ô1°!Ô4ÐR��¸UÐ:RÐ:RÀYÐ:RÐ:RÐ:Rð ð #0ÐFÐF°iÐFÐFÐFÐà*Ð*Ñ,Ô,ˆCØ š'˜'�3�3 rˆDØ×)Ò)Ñ+Ô+ˆFØ&,Ð;˜ œ˜°)ˆJÝ˜V™œ qšˆJÝ�:‰Œ Ò%Ð%Ø'¨	¨°©¨	Ô2°UÑ:�
�
Øð 1Ø'¨&Ñ0�
Ø#0Ð HÐ H°zÐ HÐ HÐ HÐð Ô 	Ò)Ð)ØÐ+Ø15�Ô+¨AÑ.ØÔ"×&Ò&Ð'7Ñ8Ô8Ð8Ø�Ø-2ˆCÔ'¨Ñ*Øð 0ØBÐBÐBÐBÐBÐBØ.Ð.Ñ0Ô0�Ýœ: d¸ÍÐLÑLÔL�ð ˜’7�7�s 8™}œ}¨sÒ2Ð2Ø'¨¨¨q©¨Ô1°EÑ9�HØÐMÐM ÐMÐM­T°$·)²)±+´+Ñ->Ô->ÐMÐMÀ8ÐMÐM��Øð 0ØÐ;Ð; Ð;Ð;°Ð;Ð;Ð;��àÐ/Ð/ Ð/Ð/Ð/�ØÔ×"Ò" 3Ñ'Ô'Ð'ØˆFð Ð(Ø#ˆCØ-1ˆCÔ'¨Ñ*Ð*Øð $	3ðð ð ð ð ð ð ð ð ð ð ð ð ð ð +Ð*Ñ,Ô,ˆCØ š'˜'�3�3 rˆDØ 4Ð 4ØØØ Øð	!ñ !ô !Ðð !Ð,Ø+×?Ò?Ð@QÑRÔR��à+Ô0�ð "�M )Ñ,Ô,ˆEØð <Ø%Ð% iÑ0Ô0ð VØ"Ð,Ð, UÐ,Ð,�C�Cà"ÐUÐU UÐUÐ,?Ð,?À	Ñ,JÔ,JÐUÈGÐUÐU�C�CàÐ;Ð; Ð;Ð;°Ð;Ð;Ð;�Ø-2ˆCÔ'¨Ñ*Ð*àÐ+Ð+˜YÐ+Ð+Ð+ˆCØ-2ˆCÔ'¨Ñ*ð
 �#Ô'¨Ô*Ò*Ð*ØÔ˜QÐÐÔ 1Ñ$ÐÐÑð Ô×"Ò" K°°cÔ6FÀqÔ6IÐ#JÑKÔKÐKØˆFØ#&ˆÔ˜aÑ ØˆÔ˜ÑàÔ×Ò˜sÑ#Ô#Ð#Ð#Ð#sU   ¡BB. Â.
CÂ8CÃCÆB5I	 É	
I8ÉI3É3I8Ë)L Ì
LÌLÍM7 Í7NÎNc           	   ƒ   óÜ  ‡‡‡‡‡‡‡‡‡‡‡‡ ‡!K  — | j         Š‰j        sd S | j                             ‰j        ¦  «        Š‰sd S t          t          ‰¦  «        dd ¦  «        }|�|t          j        u r_‰j         	                    ¦   «         sD	 ‰j         
                    ¦   «          n# t          $ r Y nw xY w‰j         	                    ¦   «         ¯Dd S g Š d Š!‰j        dk    Šd}d}t          ‰t          ¦  «        r‰j        nt          Š	 t!          t          ‰dd¦  «        pd¦  «        }n# t          $ r d}Y nw xY wt          ‰t          ¦  «        r_	 t!          ‰                     ‰j        j        ¦  «        pd¦  «        }‰                     ‰j        j        ¦  «        Šn# t          $ r Y nw xY wt)          d||dk    rd	nd
z
  ¦  «        ŠdŠ‰j        rh	 t-          j        ‰j        ¦  «        j        }d|v p*t3          d„ |                     ¦   «         D ¦   «         ¦  «        Šn# t6          t8          f$ r dŠY nw xY wdt:          dt:          fˆˆˆfd„Šdt<          dt:          fd„Šdt<          dt<          t<                   fˆˆˆfd„Šd.ˆfd„Šdt:          fˆˆˆfd„Šdt>          fˆˆˆˆˆˆˆ ˆ!fd„}	 	 ‰                      ¦   «         s_‰j         	                    ¦   «         sD	 ‰j         
                    ¦   «          n# t          $ r Y nw xY w‰j         	                    ¦   «         ¯Dd S ‰j         
                    ¦   «         }	 ‰j!        r‰j!        d
         nd }|�,t          |dd¦  «        rtE          j#        d
¦  «        ƒ d {V —† ŒÓn# t          $ r Y nw xY wt          |tH          ¦  «        rBt          |¦  «        dk    r/|d
         dk    r#|\  }	}
}‰ r|
› d|dz   › d�‰ d<   ‰ r‰ d         n|
}net          |tH          ¦  «        r9t          |¦  «        dk    r&|d
         d k    rd Š!g Š d ‰j%        d
<   d
‰j&        d
<   �Œ‰|}‰  '                    |¦  «          |¦   «         ƒ d {V —†rotQ          j)        ¦   «         }tE          j#        d!¦  «        ƒ d {V —† ‰                      ¦   «         r,‰ *                    ‰j        j        ‰j        ¬"¦  «        ƒ d {V —† �ŒtQ          j)        ¦   «         }|||z
  z
  }|d
k    rtE          j#        |¦  «        ƒ d {V —† �Œ\‰                      ¦   «         sd S ‰�rQ‰!��Nd# +                    ‰ ¦  «        } ‰‰!|¦  «        ƒ d {V —†}|j,        �st          |d$d%¦  «        pd% -                    ¦   «         }t          |d&d¦  «        r"t\           /                    d'‰j0        ¦  «         �Œÿd(|v sd)|v r4t\           1                    d*‰j0        ¦  «         tQ          j)        ¦   «         }ndŠ‰ 2                    ‰j        j        |‰j3        ‰j        ¬+¦  «        ƒ d {V —†}‰j4        rNt          |d,d¦  «        r=t          |dd ¦  «        r,‰j5         '                    t;          |j6        ¦  «        ¦  «         nÆ‰rId# +                    ‰ ¦  «        }‰ 2                    ‰j        j        |‰j3        ‰j        ¬+¦  «        ƒ d {V —†}n3‰ 2                    ‰j        j        |‰j3        ‰j        ¬+¦  «        ƒ d {V —†}|j,        rA|j6        r:|j6        Š!‰j4        r,‰j5         '                    t;          |j6        ¦  «        ¦  «         tQ          j)        ¦   «         }tE          j#        d!¦  «        ƒ d {V —† ‰                      ¦   «         r,‰ *                    ‰j        j        ‰j        ¬"¦  «        ƒ d {V —† �nE# tn          j8        $ r tE          j#        d!¦  «        ƒ d {V —† Y �ntD          j9        $ �rÀ ‰j         	                    ¦   «         �sW	 ‰j         
                    ¦   «         }t          |tH          ¦  «        rFt          |¦  «        dk    r3|d
         dk    r'|\  }	}
}‰ r|
› d|dz   › d�‰ d<    |¦   «         ƒ d {V —† n·t          |tH          ¦  «        r}t          |¦  «        dk    rj|d
         d k    r^ |¦   «         ƒ d {V —† ‰r3‰ r1‰!r/ ‰‰ ¦  «        }	  ‰‰!|¦  «        ƒ d {V —† n# t          $ r Y nw xY wd Š!g Š d ‰j%        d
<   d
‰j&        d
<   n%‰  '                    |¦  «          |¦   «         ƒ d {V —† n# t          $ r Y nw xY w‰j         	                    ¦   «         �¯W‰r‰ r‰!r |¦   «         ƒ d {V —† ‰r3‰ r1‰!r/ ‰‰ ¦  «        }	  ‰‰!|¦  «        ƒ d {V —† n# t          $ r Y nw xY wY d S t          $ r?}t\           :                    d-|¦  «         tE          j#        d¦  «        ƒ d {V —† Y d }~nd }~ww xY w�ŒA)/NÚedit_messageÚseparater@  g      ø?ÚMAX_MESSAGE_LENGTHi   r(   r#   é@   r   Fr¯   c              3   óF   K  — | ]}|j         t          j        j        u V — Œd S r^   ©ÚkindÚinspectÚ	ParameterÚVAR_KEYWORD©rb   Úparams     r>   rd   z4TurnRunner.send_progress_messages.<locals>.<genexpr>  sC   è è € ð ð à!ð œ
¥gÔ&7Ô&CÐCðð ð ð ð ð rM   Ú
message_idr4  c              “   ó’   •K  — ‰j         j        | |dœ}t          ‰dd¦  «        rd|d<   ‰r
‰j        |d<    ‰j        di |¤Žƒ d {V —†S )N)r2  rj  r4  ÚREQUIRES_EDIT_FINALIZEFTÚfinalizer¯   rN  )r(  r2  rV   Ú_progress_metadatar^  )rj  r4  rF  Ú_edit_accepts_metadatar1  r  s      €€€r>   Ú_edit_progress_messagezATurnRunner.send_progress_messages.<locals>._edit_progress_message  s‚   øè è € àœ:Ô-Ø(Ø"ðð ˆFõ
 �wÐ 8¸%Ñ@Ô@ð *Ø%)��zÑ"Ø%ð <Ø%(Ô%;��zÑ"Ø-˜Ô-Ð7Ð7°Ð7Ð7Ð7Ð7Ð7Ð7Ð7Ð7Ð7rM   Úlinesr-   c                 ó@   — d                      d„ | D ¦   «         ¦  «        S )Nr  c              3   ó4   K  — | ]}t          |¦  «        V — Œd S r^   r9  )rb   r[  s     r>   rd   zLTurnRunner.send_progress_messages.<locals>._progress_text.<locals>.<genexpr>&  s(   è è € Ð9Ð9¨4�S ™YœYÐ9Ð9Ð9Ð9Ð9Ð9rM   )rf   )rq  s    r>   Ú_progress_textz9TurnRunner.send_progress_messages.<locals>._progress_text%  s#   € Ø—9’9Ð9Ð9°5Ð9Ñ9Ô9Ñ9Ô9Ð9rM   c                 ó¾   •— g }g }| D ]=}||gz   }|r1 ‰ ‰|¦  «        ¦  «        ‰k    r|                      |¦  «         |g}Œ;|}Œ>|r|                      |¦  «         |S )z>Partition progress lines into platform-sized editable bubbles.)r”   )rq  Úgroupsr‘  r[  rP  Ú_PROGRESS_TEXT_LIMITÚ_progress_len_fnrt  s        €€€r>   Ú_split_progress_groupszATurnRunner.send_progress_messages.<locals>._split_progress_groups(  s’   ø€ à!#ˆFØˆGØð (ð (�Ø# t fÑ,�	Øð (Ð/Ð/°°¸yÑ0IÔ0IÑJÔJÐMaÒaÐaØ—M’M 'Ñ*Ô*Ð*Ø#˜f�G�Gà'�G�GØð 'Ø—’˜gÑ&Ô&Ð&ØˆMrM   c                 ó¾   •— ‰j         rPt          | dd¦  «        rAt          | dd ¦  «        r2‰j                             t	          | j        ¦  «        ¦  «         d S d S d S d S )Nr/  Frj  )Ú_cleanup_progressrV   Ú_cleanup_msg_idsr”   rw   rj  )r·  r  s    €r>   Ú_track_progress_resultzATurnRunner.send_progress_messages.<locals>._track_progress_result7  s‰   ø€ àÔ%ðDå˜F I¨uÑ5Ô5ðDõ ˜F L°$Ñ7Ô7ðDð
 Ô$×+Ò+­C°Ô0AÑ,BÔ,BÑCÔCÐCÐCÐCðDð Dð Dð Dð Dð DrM   rè   c              “   óˆ   •K  — ‰                      ‰j        j        | ‰j        ‰j        ¬¦  «        ƒ d {V —†} ‰|¦  «         |S )N©r2  r4  Úreply_tor¯   )r0  r(  r2  Ú_progress_reply_torn  )rè   r·  r}  r1  r  s     €€€r>   Ú_send_progress_textz>TurnRunner.send_progress_messages.<locals>._send_progress_text?  sl   øè è € Ø"Ÿ<š<Øœ
Ô*ØØÔ/ØÔ/ð	 (ñ ô ð ð ð ð ð ð ˆFð #Ð" 6Ñ*Ô*Ð*ØˆMrM   c               “   óô  •K  — ‰
r‰	sdS  ‰‰
¦  «        } t          | ¦  «        dk    rdS  ‰| d         ¦  «        }‰�Q ‰‰|¦  «        ƒ d{V —†}|j        s7t          |dd¦  «        r"t                               d‰j        ¦  «         dS dŠ	dS n& ‰|¦  «        ƒ d{V —†}|j        r|j        r|j        Š| dd…         D ]1} ‰ ‰|¦  «        ¦  «        ƒ d{V —†}|j        r|j        r|j        ŠŒ2| d         Š
dS )	a  Start fresh editable progress bubbles before a bubble exceeds limit.

                Returns True when it delivered/split the current buffer, or when
                a transient edit failure left the buffer and message identity
                intact for a later retry.  In either case the caller should skip
                the normal send/edit path for this tick.
                Fr(   r   NÚ	retryableu>   [%s] Transient overflow edit failure â€” keeping can_edit=TrueTr	  )r7   r/  rV   r3   r4   rÖ   rj  )rv  Ú
first_textr·  rð   rp  rt  r‚  ry  r1  Úcan_editÚprogress_linesÚprogress_msg_ids       €€€€€€€€r>   Ú!_roll_progress_overflow_if_neededzLTurnRunner.send_progress_messages.<locals>._roll_progress_overflow_if_neededI  s‚  øè è € ð "ð ¨ð Ø�uØ+Ð+¨NÑ;Ô;ˆFÝ�6‰{Œ{˜aÒÐØ�uà'˜¨¨q¬	Ñ2Ô2ˆJØÐ*Ø5Ð5°oÀzÑRÔRÐRÐRÐRÐRÐRÐR�Ø”~ð 	!Ý˜v {°EÑ:Ô:ð $ÝŸšØ\Ø#œLñô ð ð  $˜tØ$�Hà ˜5ð	!ð  3Ð2°:Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>�Ø”>ð 8 fÔ&7ð 8Ø&,Ô&7�Oà   œð 8ð 8�Ø2Ð2°>°>À%Ñ3HÔ3HÑIÔIÐIÐIÐIÐIÐIÐI�Ø”>ð 8 fÔ&7ð 8Ø&,Ô&7�Oøð
 $ BœZˆNØ�4rM   Tr  r)   r0  u    (Ã—ú)r	  Ú	__reset__ç333333Ó?r.  r  rP   r®   r„  u5   [%s] Transient edit failure â€” keeping can_edit=TrueÚfloodzretry afterz-[%s] Progress edit flood control, backing offr  r/  zProgress message error: %s©r-   N);r  r8  r  r@  r(  rV   rÎ   rG  r^  rÍ  rÎ  r2   Úprogress_groupingrt   Úmessage_len_fnr7   rh  Úmax_message_length_for_chatr2  Úmessage_len_fn_for_chatrC  rn  re  Ú	signatureÚ
parametersr
  Úvaluesrw  rj  rw   r½  rº   r3  r:  r  Úsleepr€  rD  rE  r”   rU   Ú	monotonicÚsend_typingrf   r/  ry   r3   r4   rÖ   rz  r0  r�  r{  r|  rj  ÚqueueÚEmptyÚCancelledErrorrP   )"r  Ú_adapter_editÚ_last_edit_tsÚ_PROGRESS_EDIT_INTERVALÚ_raw_progress_limitÚ_edit_paramsr‰  rx  rM  rK  Úbase_msgr  r§  Ú_nowÚ
_remainingÚ	full_textr·  Ú_errÚ_flood_resultÚ_pending_textÚerw  ro  rp  rx  rt  r‚  ry  r}  r1  r†  r  r‡  rˆ  s"                        @@@@@@@@@@@@@r>   Úsend_progress_messagesz!TurnRunner.send_progress_messagesÐ  sÄ  øøøøøøøøøøøøøè è € ØŒiˆØÔ!ð 	ØˆFà”,×2Ò2°3´:Ñ>Ô>ˆØð 	ØˆFõ  ¥ W¡¤¨~¸tÑDÔDˆØÐ  MÕ5HÔ5UÐ$UÐ$UØÔ(×.Ò.Ñ0Ô0ð ðØÔ&×1Ò1Ñ3Ô3Ð3Ð3øÝ ð ð ð Ø�Eðøøøð Ô(×.Ò.Ñ0Ô0ð ð
 ˆFàˆØˆØÔ(¨JÒ6ˆØˆØ"%Ðõ ˜'Õ#6Ñ7Ô7ðˆGÔ"Ð"åð 	ð
	'Ý"%¥g¨gÐ7KÈTÑ&RÔ&RÐ&ZÐVZÑ"[Ô"[ÐÐøÝð 	'ð 	'ð 	'Ø"&ÐÐÐð	'øøøõ
 �gÕ2Ñ3Ô3ð 	ðÝ&)Ø×7Ò7¸¼
Ô8JÑKÔKÐSÈtñ'ô 'Ð#ð $+×#BÒ#BÀ3Ä:ÔCUÑ#VÔ#VÐ Ð øÝð ð ð Ø�ðøøøõ  #ØØÐ)<¸sÒ)BÐ)B 2 2ÈÑJñ 
ô  
Ðð "'ÐØÔ!ð 	/ð
/Ý&Ô0°Ô1EÑFÔFÔQ�à ,Ð.ð Ýð ð à%1×%8Ò%8Ñ%:Ô%:ðñ ô ñ ô ð 'Ð&øõ �zÐ*ð /ð /ð /Ø).Ð&Ð&Ð&ð/øøøð
	8µSð 
	8Å3ð 
	8ð 
	8ð 
	8ð 
	8ð 
	8ð 
	8ð 
	8ð 
	8ð	:¥$ð 	:­3ð 	:ð 	:ð 	:ð 	:ð	­$ð 	µ4½´:ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð	Dð 	Dð 	Dð 	Dð 	Dð 	Dð	­Cð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð*	½ð *	ð *	ð *	ð *	ð *	ð *	ð *	ð *	ð *	ð *	ð *	ð *	ð *	ðX|	'ð{'Ø×-Ò-Ñ/Ô/ð Ø!Ô0×6Ò6Ñ8Ô8ð "ð"ØÔ.×9Ò9Ñ;Ô;Ð;Ð;øÝ(ð "ð "ð "Ø!˜Eð"øøøð "Ô0×6Ò6Ñ8Ô8ð "ð
 �FàÔ(×3Ò3Ñ5Ô5�ð	ØBEÔBRÐ+\¨3Ô+;¸AÔ+>Ð+>ÐX\Ð(Ø+Ð7½GØ,Ð.>Àñ=ô =Ð7õ &œm¨AÑ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.Ø øøÝ ð ð ð Ø�Dðøøøõ ˜c¥5Ñ)Ô)ð /­c°#©h¬h¸!ªm¨mÀÀAÄÈ+Ò@UÐ@UØ),Ñ&�A�x Ø%ð KØ08Ð-JÐ-J¸eÀa¹iÐ-JÐ-JÐ-J˜ rÑ*Ø0>ÐL˜.¨Ô,Ð,ÀH�C�CÝ ¥UÑ+Ô+ð /µ°C±´¸A²°À#ÀaÄ&ÈKÒBWÐBWð '+�OØ%'�NØ/3�CÔ)¨!Ñ,Ø*+�CÔ$ QÑ'Ùà�CØ"×)Ò)¨#Ñ.Ô.Ð.à:Ð:Ñ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<ð Ý$(¤NÑ$4Ô$4�MÝ!œ-¨Ñ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,Ø×-Ò-Ñ/Ô/ð gØ%×1Ò1°#´*Ô2DÈsÔOeÐ1ÑfÔfÐfÐfÐfÐfÐfÐfÐfÙõ ”~Ñ'Ô'�Ø4¸¸}Ñ8LÑM�
Ø ’>�>õ "œ-¨
Ñ3Ô3Ð3Ð3Ð3Ð3Ð3Ð3Ð3Ùà×-Ò-Ñ/Ô/ð Ø�Fàñ <P Ñ ;à $§	¢	¨.Ñ 9Ô 9�IØ#9Ð#9¸/È9Ñ#UÔ#UÐUÐUÐUÐUÐUÐU�FØ!œ>ñ "WÝ '¨°¸Ñ <Ô <Ð BÀ×IÒIÑKÔK˜õ # 6¨;¸Ñ>Ô>ð %Ý"ŸLšLØ WØ '¤ñô ð ñ %Ø" d˜?˜?¨m¸tÐ.CÐ.Cõ #ŸKšKØ OØ '¤ñô ð õ -1¬NÑ,<Ô,<˜M˜Mà',˜HØ.5¯lªlØ$'¤JÔ$6Ø$'Ø%(Ô%;Ø%(Ô%;ð	 /;ñ /ô /ð )ð )ð )ð )ð )ð )˜ð  Ô1ðWå '¨°yÀ%Ñ HÔ HðWõ !(¨°|ÀTÑ JÔ JðWð
  Ô0×7Ò7½¸MÔ<TÑ8UÔ8UÑVÔVÐVøàð à$(§I¢I¨nÑ$=Ô$=˜	Ø'.§|¢|Ø$'¤JÔ$6Ø$-Ø%(Ô%;Ø%(Ô%;ð	 (4ñ (ô (ð "ð "ð "ð "ð "ð "˜˜ð (/§|¢|Ø$'¤JÔ$6Ø$'Ø%(Ô%;Ø%(Ô%;ð	 (4ñ (ô (ð "ð "ð "ð "ð "ð "˜ð ”~ð P¨&Ô*;ð PØ*0Ô*;˜ØÔ0ð PØÔ0×7Ò7½¸FÔ<MÑ8NÔ8NÑOÔOÐOå $¤Ñ 0Ô 0�õ ”m CÑ(Ô(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ø×)Ò)Ñ+Ô+ð cØ!×-Ò-¨c¬jÔ.@È3ÔKaÐ-ÑbÔbÐbÐbÐbÐbÐbÐbÐbùøå”;ð )ð )ð )Ý”m CÑ(Ô(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ñ(ÝÔ)ð 'ñ 'ð 'àÔ,×2Ò2Ñ4Ô4ñ ðØ!Ô0×;Ò;Ñ=Ô=˜Ý% c­5Ñ1Ô1ð Fµc¸#±h´hÀ!²m°mÈÈAÌÐR]ÒH]ÐH]Ø14Ñ.˜A˜x¨Ø-ð JØ8@Ð5RÐ5RÀeÈaÁiÐ5RÐ5RÐ5R ¨rÑ 2Ø&GÐ&GÑ&IÔ&IÐ IÐ IÐ IÐ IÐ IÐ IÐ IøÝ'¨­UÑ3Ô3ð F½¸C¹¼ÀAº¸È#ÈaÌ&ÐT_ÒJ_ÐJ_ð #DÐ"CÑ"EÔ"EÐEÐEÐEÐEÐEÐEÐEØ'ð )¨Nð )¸ð )Ø0>°¸~Ñ0NÔ0N ð!)Ø*@Ð*@ÀÐR_Ñ*`Ô*`Ð$`Ð$`Ð$`Ð$`Ð$`Ð$`Ð$`Ð$`øÝ'0ð !)ð !)ð !)Ø$( Dð!)øøøà.2˜OØ-/˜NØ7;˜CÔ1°!Ñ4Ø23˜CÔ,¨QÑ/Ð/à*×1Ò1°#Ñ6Ô6Ð6Ø"CÐ"CÑ"EÔ"EÐEÐEÐEÐEÐEÐEÐEøøÝ$ð ð ð Ø˜ðøøøð5 Ô,×2Ò2Ñ4Ô4ñ ð: ð > ð >°?ð >Ø;Ð;Ñ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=Øð  ð °?ð Ø . ¨~Ñ >Ô >�IðØ4Ð4°_ÀiÑPÔPÐPÐPÐPÐPÐPÐPÐPÐPøÝ$ð ð ð Ø˜ðøøøà��Ýð 'ð 'ð 'Ý—’Ð9¸1Ñ=Ô=Ð=Ý”m AÑ&Ô&Ð&Ð&Ð&Ð&Ð&Ð&Ð&Ð&Ð&Ð&Ð&Ð&øøøøð'øøøñu|	'sN  ÂB% Â%
B2Â1B2Ä D( Ä(D7Ä6D7ÅAF Æ
F+Æ*F+ÇAH! È!H7È6H7Ê.-^' ËK6 Ë5^' Ë6
LÌ ^' ÌLÌ^' Ì!^' Ì;AN  Í?^' Î 
NÎ
^' ÎNÎB&^' Ð5B^' Ó;^' Ô^' ÔB^' Ö+G:^' Þ')g)ß)g)ß=C	d)ãcãd)ã
c'ã$d)ã&c'ã'Ad)ä(g)ä)
d6ä3g)ä5d6ä6Ag)å;fæg)æ
fæg)æfæg)æ!	g)æ*5g$ç$g)c                 óä  — | j         }|j        d         s|j        d         €dS |                     ¦   «         sdS d|j        d<   | j        j                             t          j        ¦  «        }|�t          |d¦  «        sdS 	 t          |                     |j        d         ¦  «        |j        t          d¬¦  «         dS # t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w)z?tool_start_callback: speak a one-time ack in the voice channel.r   NTÚplay_ack_in_voicezvoice ack scheduling error©r3   Úlog_messagezvoice ack schedule failed: %s)r  Ú_voice_ack_firedÚ_voice_ack_guildr3  r  Úadaptersrv   rÄ  ÚDISCORDrá   r   r«  Ú_voice_ack_loopr3   r2   r4   )r  r,  r?  r¸  r  Ú_adapterÚ_ack_errs          r>   Úvoice_ack_callbackzTurnRunner.voice_ack_callback3  s  € àŒiˆØÔ Ô"ð 	 cÔ&:¸1Ô&=Ð&EØˆFØ×%Ò%Ñ'Ô'ð 	ØˆFØ"&ˆÔ˜QÑØ”<Ô(×,Ò,­XÔ-=Ñ>Ô>ˆØÐ¥7¨8Ð5HÑ#IÔ#IÐØˆFð	DÝ$Ø×*Ò*¨3Ô+?ÀÔ+BÑCÔCØÔ#ÝØ8ð	ñ ô ð ð ð øõ ð 	Dð 	Dð 	DÝ�LŠLÐ8¸(ÑCÔCÐCÐCÐCÐCÐCÐCÐCøøøøð	Døøøs   Â;B? Â?
C/Ã	C*Ã*C/Ú	iterationÚ
prev_toolsc                 óè  — | j         }|                     ¦   «         sd S g }|pg D ]d}t          |t          ¦  «        r+|                     |                     d¦  «        pd¦  «         ŒB|                     t          |¦  «        ¦  «         Œet          |j         	                    d|j
        j        r|j
        j        j        nd|j
        j        |j        |||dœ¦  «        |j        t           d¬¦  «         d S )NrÖ   r®   z
agent:step)r�   Úuser_idrN   r¶  Ú
tool_namesÚtoolsz agent:step hook scheduling errorr¬  )r  r3  rt   ru   r”   rv   rw   r   Ú
_hooks_refÚemitr(  r�   r­   r¹  rN   Ú_loop_for_stepr3   )r  r¶  r·  r  Ú_namesÚ_ts         r>   Ú_step_callback_synczTurnRunner._step_callback_syncH  s  € ØŒiˆØ×%Ò%Ñ'Ô'ð 	ØˆFð ˆØÐ# ð 	'ð 	'ˆBÝ˜"�dÑ#Ô#ð 'Ø—’˜bŸfšf V™nœnÐ2°Ñ3Ô3Ð3Ð3à—’�c "™gœgÑ&Ô&Ð&Ð&Ý ØŒN×Ò Ø9<¼Ô9LÐT˜CœJÔ/Ô5Ð5ÐRTØœ:Ô-Ø!œnØ&Ø$Ø#ð/ð /ñ ô ð ÔÝØ:ð	
ñ 	
ô 	
ð 	
ð 	
ð 	
rM   rÙ   c                 óâ   — | j         }	 t          j        |j                             ||¦  «        |j        ¦  «         d S # t          $ r&}t                               d|¦  «         Y d }~d S d }~ww xY w)Nzevent_callback hook error: %s)	r  r  Úrun_coroutine_threadsafer¼  r½  r¾  r2   r3   r4   )r  r#  rÙ   r  Ú_es        r>   Ú_event_callback_synczTurnRunner._event_callback_syncc  s�   € ØŒiˆð	>ÝÔ,Ø”×#Ò# J°Ñ8Ô8ØÔ"ñô ð ð ð øõ ð 	>ð 	>ð 	>Ý�LŠLÐ8¸"Ñ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=øøøøð	>øøøs   ‰3> ¾
A.ÁA)Á)A.c                 ó¢  ‡ ‡‡— 	 dt           dt          ddfd„}||_        t          |dd¦  «        Š|j        Š‰ j                             ‰¦  «        rˆ ˆˆfd„|_        dS ‰ j                             ‰¦  «        s‰ j         	                    ‰¦  «        rˆ ˆˆfd„|_        dS dS # t          $ r  t                               d	d
¬¦  «         Y dS w xY w)aÇ  Wire the platform thread-rename lane onto the agent as `_on_session_title`.

        The session titler runs inside the turn prologue now (it derives the
        title from the user's first message, so it no longer needs the
        response), which means the callback has to be attached before the run
        rather than registered after it. The lane predicates and their
        rationale are unchanged from the old post-response registration.
        rÝ   r<   r-   Nc                 ó>   — t                                d| |¦  «         d S )Nz@Gateway auto-title failure suppressed (not user-visible): %s: %s)r3   r4   ©rÝ   r<   s     r>   Ú_title_failure_cbzDTurnRunner._attach_session_title_callback.<locals>._title_failure_cb{  s*   € Ý—’ØVØ˜#ñô ð ð ð rM   rN   c                 óH   •— |dk    o‰j                              ‰‰| ¦  «        S ©NÚllm)r  Ú%_schedule_telegram_topic_title_rename©ÚtitleÚtitle_sourcer  rN   r(  s     €€€r>   rò   z;TurnRunner._attach_session_title_callback.<locals>.<lambda>Œ  s1   ø€ Ø  EÒ)ð Øœ×JÒJØ 
¨Eñô ð rM   c                 óH   •— |dk    o‰j                              ‰‰| ¦  «        S rË  )r  Ú(_schedule_discord_semantic_thread_renamerÎ  s     €€€r>   rò   z;TurnRunner._attach_session_title_callback.<locals>.<lambda>�  s1   ø€ Ø  EÒ)ð Øœ×MÒMØ 
¨Eñô ð rM   z'Failed to attach session title callbackTrß   )rw   ÚBaseExceptionÚ_title_failure_callbackrV   r(  r  Ú_is_telegram_topic_laneÚ_on_session_titleÚ_is_discord_auto_thread_laneÚ_is_relay_discord_channel_laner2   r3   r4   )r  rµ   r  rÉ  rN   r(  s   `   @@r>   Ú_attach_session_title_callbackz)TurnRunner._attach_session_title_callbackm  s?  øøø€ ð.	Sð
­ð µ-ð ÀDð ð ð ð ð ->ˆEÔ)å  ¨°dÑ;Ô;ˆJØ”ZˆFð Œ|×3Ò3°FÑ;Ô;ð ð+ð +ð +ð +ð +ð +�Ô'Ð'Ð'ð ”×:Ò:¸6ÑBÔBð Ø”×;Ò;¸FÑCÔCðð+ð +ð +ð +ð +ð +�Ô'Ð'Ð'ðð øõ" ð 	Sð 	Sð 	SÝ�LŠLÐBÈTˆLÑRÔRÐRÐRÐRÐRð	Søøøs   …AB$ Á A B$ Â$&CÃCr$  c           
      ó  ‡— | j         Š‰j        r‰                     ¦   «         sd S t          ‰j        j        ||¦  «        }|€`t                               d‰j        j        r‰j        j        j        nd|t          t          |pd¦  «        ¦  «        d d…         ¦  «         d S t          t          ‰j        ‰j        ||‰j        ¦  «        ‰j        t          d|› d�¬¦  «        }|€d S ‰j        rd
ˆfd	„}|                     |¦  «         d S d S )Nz(status_callback suppressed for %s/%s: %sr¼  r®   é    zstatus_callback (z) scheduling errorr¬  r-   c                 óô   •— 	 |                       ¦   «         }n# t          $ r Y d S w xY wt          |dd ¦  «        }t          |dd¦  «        r+|r+‰j                             t          |¦  «        ¦  «         d S d S d S )Nrj  r/  F)r·  r2   rV   r|  r”   rw   )ÚfutÚresÚmidr  s      €r>   Ú_track_status_idz:TurnRunner._status_callback_sync.<locals>._track_status_idÀ  sœ   ø€ ðØŸ*š*™,œ,�C�CøÝ ð ð ð Ø�F�Fðøøøå˜c <°Ñ6Ô6�Ý˜3 	¨5Ñ1Ô1ð :°cð :ØÔ(×/Ò/µ°C±´Ñ9Ô9Ð9Ð9Ð9ð:ð :ð :ð :s   ƒ ˜
&¥&rŽ  )r  Ú_status_adapterr3  r(  r(  r�   r3   r4   r­   rø   rw   r   r6  Ú_status_chat_idÚ_status_thread_metadatar¾  r{  Úadd_done_callback)r  r#  r$  Úprepared_messageÚ_futrà  r  s         @r>   Ú_status_callback_syncz TurnRunner._status_callback_sync¦  s`  ø€ ØŒiˆØÔ"ð 	¨#×*@Ò*@Ñ*BÔ*Bð 	ØˆFÝ:ØŒJÔØØñ
ô 
Ðð
 Ð#Ý�LŠLØ:Ø-0¬ZÔ-@ÐO�”
Ô#Ô)Ð)ÀiØÝ3µC¸¸À2Ñ4FÔ4FÑGÔGÈÈÈÔMñ	ô ð ð ˆFÝ'Ý'¨Ô(;¸SÔ=PÐR\Ð^nÐpsô  qLñ  Mô  MØÔÝØJ¨JÐJÐJÐJð	
ñ 
ô 
ˆð ˆ<ØˆFØÔ ð 		5ð:ð :ð :ð :ð :ð :ð ×"Ò"Ð#3Ñ4Ô4Ð4Ð4Ð4ð		5ð 		5rM   c                 óæ7  ‡ ‡o‡p‡q‡r‡s‡t‡u‡v— ‰ j         Šv‰vj        j        t          j        k    rdn‰vj        j        j        }‰vj        pd}‰vj        pd                     ¦   «         }|r|dz   |z                        ¦   «         }‰ j	         
                    ‰vj        j        ‰vj        j        pdt          ‰vj        dd ¦  «        t          ‰vj        dd ¦  «        ¬¦  «        }|r|dz   |z                        ¦   «         }t          ¦   «         }	 ‰ j	                             ‰vj        ‰vj        ‰vj        ¬¦  «        \  }}t"                               d||                     d	¦  «        ‰vj        pd¦  «         n!# t(          $ r}d
|› �g dg dœcY d }~S d }~ww xY w‰ j	        j        }	‰ j	                             ‰vj        ‰vj        |¬¦  «        }
|
‰ j	        _        ‰ j	                             ‰vj        ‰vj        ¬¦  «        ‰ j	        _        d Štd }‰vj        d         Šut          t          ‰ j	        dd ¦  «        dd ¦  «        }|€ddlm}  |¦   «         }‰v                     ‰vj        |d¦  «        }|€|j        o
|j        dk    ntA          |¦  «        }|}‰vj!        }|}|s|rÖ	 ddl"m#} ‰ j	         $                    ‰vj        ¦  «        }|r{‰ j	         %                    ‰vj        ||d¬¦  «        \  }} ||‰vj        j        |‰vj&        ‰vj'        �ˆvfd„nd |‰vj(        ‰vj)        ¬¦  «        Št|rdtT          dd fˆtˆuˆvfd„}‰t‰vj+        d<   n2# t(          $ r%}t"                               d|¦  «         Y d }~nd }~ww xY w|€‰u�dtT          dd fˆuˆvfd„}ddœdtT          dt@          dd fˆtˆvfd „}‰ j	         ,                    ‰vj-        ||¦  «        }‰vj                             d!¦  «        pi                      d"¦  «        pi }|                     |¦  «        pi }|                     d#¦  «        }|�tA          |¦  «        nd}‰ j	         .                    |d$         |d%         ‰vj/        |‰ j	         0                    ‰vj        ¦  «        t          ‰vj        d&d ¦  «        t          ‰vj        d'd ¦  «        |¬(¦  «        }d }d} t          ‰ j	        d)d ¦  «        }!t          ‰ j	        d*d ¦  «        }"d }#|!rS|"�Q|!5  |"                     ‰vj        ¦  «        }$d d d ¦  «         n# 1 swxY w Y   |$rtc          |$¦  «        d+k    r|$d+         }#d}%|#�E‰vj2        �>|#‰vj2        k    r3	 ‰ j	        j3         4                    |#¦  «        }%n# t(          $ r d}%Y nw xY wd }&‰ j	        j5        �Z‰vj2        rS	 ‰ j	        j5        j6         7                    ‰vj2        ¦  «        }'|'r|'                     d,d¦  «        }&n# t(          $ r Y nw xY wd }(|!�r*|"��'|!5  |"                     ‰vj        ¦  «        })|)�rð|)d-         |k    �rãtc          |)¦  «        d.k    r|)d.         nd }*tc          |)¦  «        d+k    r|)d+         nd }+|+d uo‰vj2        d uo
|+‰vj2        k    },|,o|%o|+|#k    }-|-rvt"           8                    d/‰vj        |+¦  «         ‰ j	        j9         :                    ‰vj        d ¦  «        }.tw          |.tx          ¦  «        r
|.r|.d         nd }/|/r|/tz          ur|/}(�n|,s€|*�~|&�||&|*k    rvt"           8                    d0‰vj        |*|&¦  «         ‰ j	        j9         :                    ‰vj        d ¦  «        }.tw          |.tx          ¦  «        r
|.r|.d         nd }/|/r|/tz          ur|/}(n�|)d         }t}          |"d1¦  «        r,	 |" ?                    ‰vj        ¦  «         n# t€          $ r Y nw xY w‰ j	         A                    |‰vjB        ¦  «         ||_C        t"                               d2‰vj        ¦  «         d3} d d d ¦  «         n# 1 swxY w Y   | r4|�2‰ j	         D                    |‰ j	         E                    ¦   «         ¦  «         |(��	 t�          jG        ‰ j	        jH        |(fd3d4tU          ‰vj        ¦  «        d d5…         › �¬6¦  «         I                    ¦   «          n<# t(          $ r/ 	 ‰ j	         H                    |(¦  «         n# t(          $ r Y nw xY wY nw xY w|�€( ‰vjJ        d±d$|d$         i|d%         ¤t—          ‰vj        ¦  «        ¤i d7|“d8d3“d9d“d:‰vj/        “d;‰vjL        “d<|pd “d=‰ j	        jM        pd “d>|
“d?‰ j	        j        “d@|                     d@¦  «        “dA|	                     dB¦  «        “dC|	                     dD¦  «        “dE|	                     dF¦  «        “dG|	                     dH¦  «        “dI|	                     dJd¦  «        “dK|	                     dL¦  «        “dM‰vj2        “dN|“d&‰vj        jN        “d'‰vj        jO        “dO‰vj        jP        “dP‰vj        j        “dQ‰vj        jQ        “dR‰vj        jR        “d‰vj        jS        “dS‰vj        “dTt          ‰ j	        j5        dU‰ j	        j5        ¦  «        “dV‰ j	         E                    ¦   «         “d#|“dWd3“¤Ž}|!rH|"�F|!5  |||&‰vj2        f|"‰vj        <   ‰ j	         T                    ¦   «          d d d ¦  «         n# 1 swxY w Y   t"                               dX‰vj        |¦  «         ‰vjU        s‰vjV        s‰vjW        �‰vjX        nd |_Y        ‰vjZ        d         �‰vj[        nd |_\        ‰vj]        j^        r‰vj_        nd |_`        ||_a        |r|nd |_b        ‰vjc        |_d        d²ˆvˆ fdY„}0|0|_e        d |_f        ‰vjg        |_h        |
|_i        ‰ j	        j        |_j        |                     d@¦  «        pi |_k        d l                    ‰ j	         m                    ‰vj        ¦  «        ¦  «        |_n        t�          jo        ¦   «         Šrg Špt�          jp        ¦   «         ŠqdZtT          dd fˆvfd[„Šsd²ˆpˆqˆrˆsfd\„}1dZtT          dd fˆpˆqˆrˆsˆvfd]„}2|2|_q        ‰vjr        rt‰vj        rmt          tç          ‰vjr        ¦  «        d^d ¦  «        �(‰vjr         t                    ‰vj        |1‰vju        ¬_¦  «         n"t          ‰vjr        d`d ¦  «        }3|3�
|1|3‰vj        <   ‰vj                             dai ¦  «                             db¦  «        }4tw          |4t@          ¦  «        r|4rdcnd}4|4r!tU          |4¦  «         v                    ¦   «         ndc|_w        d³ddtT          det@          dtT          fˆvfdf„}5|5|_x        ‰vjy        |_z        |‰vj{        d<   ‰  |                    |‰v¦  «         ‰vj}        |_~        ‰vj        |_€        t}          |dg¦  «        r|j�        nd ‰vj‚        d<   �t          ‰vj„        ‰vj        �t          ‰vj        ¦  «        ¬h¦  «        \  }6}7| ržt          |dMd ¦  «        ‰vj2        k    r„�t          |6t          |did ¦  «        ¦  «        }8|8|6ur`t"           ‡                    dj‰vj        tc          |6¦  «        tc          |8¦  «        ¦  «         �t          |8�t          j‰        ¦   «         ¬k¦  «        }6�t          |6¦  «        }9ddll‹mŒ}:m�};mŽ}<m�}= dm�t           dd fˆoˆvfdn„}>‰vj‘        }?‰vj’        }@t          ‰ j	        doi ¦  «        }A‰vj        r|A :                    ‰vj        d ¦  «        nd }B|Br|Bdz   ‰vj-        z   ‰v_-        �t'          ¦   «         }C�t)          �t+          ‰vj„        ¦  «        |C¬p¦  «        }Dd }E‰vj        r=	 ‰ j	        j3        j–                             ‰vj        ¦  «        }En# t(          $ r d }EY nw xY wd}F|E�2t          |Edqd¦  «        r!�t)          t          |Edrd ¦  «        |C¬p¦  «        }FtA          |Ed uot          |Edqd¦  «        o|Dp|F¦  «        }GtA          |6o |6ds                              dt¦  «        duk    o|D¦  «        }H|Grut          |Edvd ¦  «        pdw}I‰vj-        }?‰ j	         $                    ‰vj        ¦  «        }JtA          t          |Jdxd3¦  «        ¦  «        }K�t/          |I‰vj-        |K¬y¦  «        ‰v_-        n|Hr‰vj-        }?dz‰vj-        z   ‰v_-        t          ‰ j	        d{d ¦  «        }A|Ar?‰vj        r8‰vj        |Av r/|A :                    ‰vj        d ¦  «        }L|Lr|Ldz   ‰vj-        z   ‰v_-        tw          ‰vj-        tT          ¦  «        r’‰vj-                             ¦   «         sy|E�wt          |Edqd¦  «        rft          |Edvd ¦  «        pdw}M‰ j	         $                    ‰vj        ¦  «        }N�t/          |MdtA          t          |Ndxd3¦  «        ¦  «        ¬y¦  «        ‰v_-        ‰vj        pdŠo |<‰o¦  «        }O |:‰o|>¦  «         	 ‰ j	         ˜                    ‰vj        ¦  «        }P|Pr¤	 dd|l™mš}Q  |Q‰vj-        |P¦  «        \  }R}S|Sr)t"           ‡                    d}tc          |S¦  «        |S¦  «         �t7          d~„ |RD ¦   «         ¦  «        r|R}Tn‰vj-        }Tn@# t(          $ r,}Ut"           ‡                    d|U¦  «         ‰vj-        }TY d }U~Und }U~Uww xY w‰vj-        }T�t9          |T|7¦  «        }V|6‰vj2        d€œ}W|?�|?|Wd�<   n|7r
‰vj-        |Wd�<   ‰vj�        �
‰vj�        |Wd‚<   |@�|@|Wdƒ<    |jž        |Vfi |W¤Ž}X |=‰o¦  «         	 dd„lŸm }Y  |Y‰o¦  «         n# t(          $ r Y nw xY w |;|O¦  «         n>#  |=‰o¦  «         	 dd„lŸm }Y  |Y‰o¦  «         n# t(          $ r Y nw xY w |;|O¦  «         w xY w|X‰vj¡        d<   ‰t�‰t ¢                    ¦   «          |X                     d…¦  «        }Zd}[d}\d}]d}^‰vj{        d         }_|_r`t}          |_d†¦  «        rPt          |_j£        d‡d¦  «        }[t          |_dˆd¦  «        }\t          |_d‰d¦  «        }]t          |_j£        dŠd¦  «        pd}^|_rt          |_d$d ¦  «        nd }`‰vj{        d         }d}a|rtA          t          |d‹d¦  «        ¦  «        nd}b|rt          |dM‰vj2        ¦  «        n‰vj2        }c|�r~‰vj        �rv|c‰vj2        k    �rjd3}at"           8                    dŒ‰vj2        |c¦  «         ‰ j	        j3        j–                             ‰vj        ¦  «        }dd}e|drÞt          |ddMd ¦  «        }f‰v )                    ¦   «         s)t"           8                    d�‰vj        pdŽ‰vju        ¦  «         n�|f|ck    rd3}en‡|f‰vj2        k    r*t"           8                    d�‰vj        pdŽ‰vj2        |f¦  «         nR|c|d_2        ‰ j	        j3         ¤                    ¦   «          ‰ j	        j3         ¥                    |c‰vj        ‰vj        ¦  «         d3}e|e�rt          ‰vj        dNd ¦  «        t          j¦        k    rñt          ‰vj        dRd ¦  «        d�k    r×t          ‰vj        dd ¦  «        €Á‰ j	        j5        �µ	 ‰ j	        j5        j6         §                    |c¬‘¦  «        }g|gr`|g                     d¦  «        rKtU          |gd         ¦  «        ‰vj        _S        t"                               d’‰vj        jS        ‰vj2        |c¦  «         n,# t(          $ r t"                               d“d3¬”¦  «         Y nw xY w|er"‰ j	         ¨                    ‰vj        |dd•¬–¦  «         |c}h‰ j	         ©                    |h|¦  «         |as|brdntc          |6¦  «        }i|Z�s‚�tU          |X|Zpdtc          |6¦  «        ¬—¦  «        }Z�tW          ‰vj        j        |Z¦  «        }Z|Zs"|X                     d˜¦  «        rd™|Xd˜         › �nd}Zi d…|Z“dš|X                     dšg ¦  «        “d›|X                     d›d¦  «        “dœ|X                     dœd¦  «        “d�|X                     d�¦  «        “dž|X                     džd¦  «        “dŸ|X                     dŸ¦  «        “d |X                     d d¦  «        “d¡|X                     d¡¦  «        “d˜|X                     d˜¦  «        “d¢|X                     d¢d¦  «        “d£|X                     d£d¦  «        “dg‰vj‚        d         pg “d¤|i“d¥|b“dM|h“d‡|[“|\|]|`|^d¦œ¥S d§|Zvr°�tY          |X                     dšg ¦  «        tc          |6¦  «        |9¬¨¦  «        \  }j}k|jrw�t[          ¦   «         }lg }m|jD ]0}n|n|lvr*|l ®                    |n¦  «         |m ¯                    |n¦  «         Œ1|kr|m °                    dd©¦  «         |Zdªz   dª l                    |m¦  «        z   }Zi d…|Z“d«|X                     d«¦  «        “dš‰vj¡        d         r!‰vj¡        d                              dšg ¦  «        ng “d›‰vj¡        d         r!‰vj¡        d                              d›d¦  «        nd“dœ‰vj¡        d         r!‰vj¡        d                              dœd¦  «        nd“d�‰vj¡        d         r ‰vj¡        d                              d�¦  «        nd “dŸ‰vj¡        d         r ‰vj¡        d                              dŸ¦  «        nd “d ‰vj¡        d         r!‰vj¡        d                              d d¦  «        nd“dž‰vj¡        d         r!‰vj¡        d                              džd¦  «        nd“d˜‰vj¡        d         r ‰vj¡        d                              d˜¦  «        nd “d¡‰vj¡        d         r ‰vj¡        d                              d¡¦  «        nd “d£‰vj¡        d         r!‰vj¡        d                              d£d¦  «        nd“dg‰vj‚        d         pg “d¤|i“d¥|b“d‡|[“d¬|\“|]|`|^|h|X                     d­d¦  «        |X                     d®d¦  «        ‰vj¡        d         r!‰vj¡        d                              d¯d3¦  «        nd3d°œ¥S )´Nrs  r®   r  r›  Úparent_chat_idrš  ©r(  r+   rA  z3run_agent resolved: model=%s provider=%s session=%sr  u'   âš ï¸� Provider authentication failed: r   ©rò  r(  rç  r»  ©r(  r+   r  ©r(  r+   rz   Ú	streaming©ÚStreamingConfigr  ©ÚGatewayStreamConsumerÚraise©Úon_missing_cursorc                  ó8   •— ‰ j                              d¦  «        S )N)r‹  )r8  rÏ  )r  s   €r>   rò   z%TurnRunner.run_sync.<locals>.<lambda>C  s   ø€  SÔ%7×%;Ò%;¸NÑ%KÔ%K€ rM   )r1  r2  rz   r¯   Úon_new_messageÚon_before_finalizeÚinitial_reply_to_idÚrun_still_currentrè   r-   c                 ó�   •— ‰                      ¦   «         r.‰                     | ¦  «         ‰�‰                     | ¦  «         d S d S d S r^   ©r3  Úon_delta)rè   Ú_stream_consumerÚ_stts_consumer_refr  s    €€€r>   Ú_stream_delta_cbz-TurnRunner.run_sync.<locals>._stream_delta_cbL  sa   ø€ Ø"×5Ò5Ñ7Ô7ð FØ 0× 9Ò 9¸$Ñ ?Ô ?Ð ?à#5Ð#AØ$6×$?Ò$?ÀÑ$EÔ$EÐ$EÐ$EÐ$Eð	Fð Fð $BÐ#ArM   z$Could not set up stream consumer: %sc                 ó^   •— ‰                      ¦   «         r‰                     | ¦  «         d S d S r^   rü  )rè   rÿ  r  s    €€r>   r   z-TurnRunner.run_sync.<locals>._stream_delta_cbZ  s;   ø€ Ø×)Ò)Ñ+Ô+ð 6Ø&×/Ò/°Ñ5Ô5Ð5Ð5Ð5ð6ð 6rM   F)Úalready_streamedr  c                óx  •— ‰                      ¦   «         sd S | }‰�.|r‰                     ¦   «          n‰                     |¦  «         d S |s*‰j        r#t	          |pd¦  «                             ¦   «         sd S t          ‰j                             ‰j        |‰j	        ¬¦  «        ‰j
        t          d¬¦  «         d S )Nr®   r.  z+interim_assistant_callback scheduling errorr¬  )r3  Úon_segment_breakÚon_commentaryrá  rw   rx   r   r0  râ  rã  r¾  r3   )rè   r  Údisplay_textrþ  r  s      €€r>   Ú_interim_assistant_cbz2TurnRunner.run_sync.<locals>._interim_assistant_cb^  sï   ø€ Ø×)Ò)Ñ+Ô+ð Ø�ØˆLØÐ+Ø#ð AØ$×5Ò5Ñ7Ô7Ð7Ð7à$×2Ò2°<Ñ@Ô@Ð@Ø�Øð  sÔ':ð Å#ÀlÐFXÐVXÑBYÔBY×B_ÒB_ÑBaÔBað Ø�Ý$ØÔ#×(Ò(ØÔ'Ø Ø Ô8ð )ñ ô ð
 Ô"ÝØIð	ñ 	ô 	ð 	ð 	ð 	rM   r9   rE  Úskip_context_filesr  r¿  r¹  Úuser_id_alt)Ú
cache_keysr¹  r	  r  Ú_agent_cache_lockÚ_agent_cacher)   Úmessage_countr(   r|  uÃ   Agent cache invalidated for session %s: cached agent's session_id %s is ended in state.db (stale self-heal artifact, #54878 x #54947) â€” discarding instead of reusing across the routing recoveryzfAgent cache invalidated for session %s: message_count changed (%s -> %s), possible cross-process writeÚmove_to_endz#Reusing cached agent for session %sTzagent-xproc-evict-é   ©Útargetr¸  ÚdaemonrÖ   Úmax_iterationsÚ
quiet_modeÚverbose_loggingÚenabled_toolsetsÚdisabled_toolsetsÚephemeral_system_promptÚprefill_messagesÚreasoning_configÚservice_tierÚrequest_overridesÚproviders_allowedÚonlyÚproviders_ignoredÚignoreÚproviders_orderÚorderÚprovider_sortÚsortÚprovider_require_parametersÚrequire_parametersÚprovider_data_collectionÚdata_collectionrN   r�   Ú	user_namer2  Ú	chat_namer´  Úgateway_session_keyrX   rS   Úfallback_modelÚload_soul_identityz)Created new agent for session %s (sig=%s)c                 ó<  •— ‰j         r‰                     ¦   «         sd S 	 t          | ¦  «        }n-# t          $ r  t                               dd¬¦  «         Y d S w xY w|sd S t          ‰j                             ‰j	        |¦  «        ‰j
        t          d¬¦  «         d S )Nzrender_notice_line failedTrß   z)notice_callback delivery scheduling errorr¬  )rá  r3  r+  r2   r3   r4   r   r  Ú_deliver_platform_noticer(  r¾  )r*  r[  r  r  s     €€r>   Ú_notice_callback_syncz2TurnRunner.run_sync.<locals>._notice_callback_sync³  sÆ   ø€ ØÔ&ð ¨c×.DÒ.DÑ.FÔ.Fð Ø�ðÝ)¨&Ñ1Ô1��øÝð ð ð Ý—’Ð8À4�ÑHÔHÐHØ��ðøøøð ð Ø�Ý$Ø”×5Ò5°c´jÀ$ÑGÔGØÔ"ÝØGð	ñ ô ð ð ð s    0 °&AÁAr$  c           
      óø   •— ‰j         r‰                     ¦   «         sd S t          ‰j                              ‰j        | t          ‰j        ‰j        j        ¬¦  «        ¬¦  «        ‰j	        t          d¬¦  «         d S )Nr…   r.  z+background_review_callback scheduling errorr¬  )rá  r3  r   r0  râ  r´   rã  r(  r�   r¾  r3   )r$  r  s    €r>   Ú_deliver_bg_review_messagez7TurnRunner.run_sync.<locals>._deliver_bg_review_message×  s“   ø€ ØÔ&ð ¨c×.DÒ.DÑ.FÔ.Fð Ø�Ý$ØÔ#×(Ò(ØÔ'ØÝ9¸#Ô:UÐ`cÔ`jÔ`sÐtÑtÔtð )ñ ô ð
 Ô"ÝØIð	ñ 	ô 	ð 	ð 	ð 	rM   c                  óÊ   •— ‰                      ¦   «          ‰5  t          ‰¦  «        } ‰                     ¦   «          d d d ¦  «         n# 1 swxY w Y   | D ]} ‰|¦  «         Œd S r^   )r•   r½  Úclear)ÚpendingÚqueuedÚ_bg_review_pendingÚ_bg_review_pending_lockÚ_bg_review_releaser2  s     €€€€r>   Ú_release_bg_review_messagesz8TurnRunner.run_sync.<locals>._release_bg_review_messageså  s¿   ø€ Ø×"Ò"Ñ$Ô$Ð$Ø(ð +ð +ÝÐ1Ñ2Ô2�Ø"×(Ò(Ñ*Ô*Ð*ð+ð +ð +ñ +ô +ð +ð +ð +ð +ð +ð +øøøð +ð +ð +ð +ð "ð 3ð 3�Ø*Ð*¨6Ñ2Ô2Ð2Ð2ð3ð 3s   ˜$AÁAÁAc                 ó$  •— ‰j         r‰                     ¦   «         sd S ‰                     ¦   «         sR‰5  ‰                     ¦   «         s#‰                     | ¦  «         	 d d d ¦  «         d S 	 d d d ¦  «         n# 1 swxY w Y    ‰| ¦  «         d S r^   )rá  r3  r8  r”   )r$  r7  r8  r9  r2  r  s    €€€€€r>   Ú_bg_review_sendz,TurnRunner.run_sync.<locals>._bg_review_sendî  s  ø€ ØÔ&ð ¨c×.DÒ.DÑ.FÔ.Fð Ø�Ø%×,Ò,Ñ.Ô.ð Ø,ð ð Ø-×4Ò4Ñ6Ô6ð Ø*×1Ò1°'Ñ:Ô:Ð:Øðð ð ñ ô ð ð ð ððð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð 'Ð& wÑ/Ô/Ð/Ð/Ð/s   µ+A:Á:A>ÂA>Úregister_post_delivery_callback©Ú
generationÚ_post_delivery_callbacksrD  Úmemory_notificationsrp   ÚquestionÚmulti_selectc           
      ó¸  •— ddl m} dd l}‰j        sdS |                     ¦   «         j        d d…         }|                     |‰j        pd| |rt          |¦  «        nd t          |¦  «        ¬¦  «         	 ‰j         
                    ‰j        ¦  «         n# t          $ r Y nw xY w	 ‰j        r‰j        d         nd }t          |dd ¦  «        }t          |¦  «        r |d¬¦  «         n,# t          $ r t                                d	d
¬¦  «         Y nw xY wd}t%          ‰j                             ‰j        | |rt          |¦  «        nd |‰j        pd‰j        ¬¦  «        ‰j        t           d¬¦  «        }	|	€d}nj	 |	                     d¬¦  «        }
t          t          |
dd¦  «        ¦  «        }n4# t          $ r'}t                                d|¦  «         d}Y d }~nd }~ww xY w|s|                     ‰j        pd¦  «         dS |                     ¦   «         }|                     |t7          |¦  «        ¬¦  «        }|�|dk    rdt9          |dz  ¦  «        › d�S |S )Nr   ©Úclarify_gatewayr®   é
   )Ú
clarify_idr+   rB  r  rC  Úflush_pending_syncg      @r  z2Stream-consumer flush before clarify prompt failedTrß   F)r2  rB  r  rH  r+   r¯   zClarify send failed to scheduler¬  é   r/  zClarify send failed: %sz'[clarify prompt could not be delivered]z[user did not respond within rø  zm])r»  rF  Úuuidrá  Úuuid4ÚhexÚregisterr+   r½  rº   Úpause_typing_for_chatrâ  r2   Ústream_consumer_holderrV   r/  r3   r4   r   Úsend_clarifyrã  r¾  r·  rã   Úclear_sessionÚget_clarify_timeoutÚwait_for_responseri  rh  )rB  r  rC  Ú_clarify_modÚ_uuidrH  Ú_scÚ_flushÚsend_okrÝ  r·  r<   rÓ  rJ  r  s                 €r>   Ú_clarify_callback_syncz3TurnRunner.run_sync.<locals>._clarify_callback_sync  sö  ø€ Ø=Ð=Ð=Ð=Ð=Ð=Ø Ð Ð Ð àÔ&ð Ø�ràŸš™œÔ*¨3¨B¨3Ô/ˆJØ×!Ò!Ø%ØœOÐ1¨rØ!Ø)0Ð:�˜W™œ˜°dÝ! ,Ñ/Ô/ð "ñ ô ð ðØÔ#×9Ò9¸#Ô:MÑNÔNÐNÐNøÝð ð ð Ø�ðøøøð	Ø7:Ô7QÐ[�cÔ0°Ô3Ð3ÐW[�Ý  Ð&:¸DÑAÔA�Ý˜FÑ#Ô#ð (Ø�F 3Ð'Ñ'Ô'Ð'øøÝð ð ð Ý—’ØHØ!ð ñ ô ð ð ð ðøøøð ˆGÝ*ØÔ#×0Ò0ØÔ/Ø%Ø-4Ð>�D ™MœM˜M¸$Ø)Ø #¤Ð 5°2Ø Ô8ð 1ñ ô ð Ô"ÝØ=ðñ ô ˆCð ˆ{Ø��ð$Ø ŸZšZ°˜ZÑ3Ô3�FÝ"¥7¨6°9¸eÑ#DÔ#DÑEÔE�G�GøÝ ð $ð $ð $Ý—N’NÐ#<¸cÑBÔBÐBØ#�G�G�G�G�G�Gøøøøð$øøøð ð Að ×*Ò*¨3¬?Ð+@¸bÑAÔAÐAØ@Ð@à"×6Ò6Ñ8Ô8ˆGØ#×5Ò5°jÍ%ÐPWÉ.Ì.Ð5ÑYÔYˆHØÐ 8¨r¢> >àLµs¸7ÀR¹<Ñ7HÔ7HÐLÐLÐLÐLØˆOs=   Á6B Â
B#Â"B#Â'AC* Ã*&DÄDÅ;4F0 Æ0
G!Æ:GÇG!r»  r×  Ú_session_messagesz™Persisted transcript lagged live cached history for session %s (disk=%d, memory=%d); preserving live conversation context (possible FTS write corruption)rî  )Úregister_gateway_notifyÚreset_current_session_keyÚset_current_session_keyÚunregister_gateway_notifyÚapproval_datac                 ó   •— ‰
j                              ‰
j        ¦  «         |                      dd¦  «        }|                      dd¦  «        }t	          |¦  «        }t          t          ‰
j         ¦  «        dd¦  «        ��	 t          ‰
j                              ‰
j        |‰	|‰
j	        |                      dd¦  «        |                      d	d¦  «        |                      d
d¦  «        ¬¦  «        ‰
j
        t          d¬¦  «        }|€t          d¦  «        ‚|                     d¬¦  «        }|j        rdS t                               d|j        ¦  «         n2# t"          $ r%}t                               d|¦  «         Y d}~nd}~ww xY wt          ‰
j         dd¦  «        }t%          ||||                      dd¦  «        |                      d	d¦  «        |                      d
d¦  «        ¬¦  «        }	 t          ‰
j                              ‰
j        |‰
j	        ¬¦  «        ‰
j
        t          d¬¦  «        }|�|                     d¬¦  «         dS dS # t"          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w)aY  Send the approval request to the user from the agent thread.

                If the adapter supports interactive button-based approvals
                (e.g. Discord's ``send_exec_approval``), use that for a richer
                UX.  Otherwise fall back to a plain text message with
                ``/approve`` instructions.
                r   r®   r  zdangerous commandÚsend_exec_approvalNrý   Trþ   rÿ   F)r2  r   r+   r  r¯   rý   rþ   rÿ   z#send_exec_approval scheduling errorr¬  z$send_exec_approval: loop unavailablerJ  r  zLButton-based approval failed (send returned error), falling back to text: %sz6Button-based approval failed, falling back to text: %sÚtyped_command_prefixr]  rü   r.  z#Approval text-send scheduling errorz#Failed to send approval request: %s)rá  rO  râ  rv   rû   rV   rÎ   r   rb  rã  r¾  r3   r¾  r·  r/  rã   rP   r2   r  r0  )r`  rù   r…  Ú_approval_futÚ_approval_resultrÄ  Ú_pr§  Ú_approval_send_futÚ_approval_session_keyr  s            €€r>   Ú_approval_notify_syncz2TurnRunner.run_sync.<locals>._approval_notify_syncÀ  sû  ø€ ð Ô×5Ò5°cÔ6IÑJÔJÐJà×#Ò# I¨rÑ2Ô2ˆCØ ×$Ò$ ]Ð4GÑHÔHˆDõ +¨3Ñ/Ô/ˆCõ
 •t˜CÔ/Ñ0Ô0Ð2FÈÑMÔMÑYðÝ$<ØÔ+×>Ò>Ø$'Ô$7Ø$'Ø(=Ø(,Ø%(Ô%@Ø,9×,=Ò,=Ð>OÐQUÑ,VÔ,VØ*7×*;Ò*;¸OÈTÑ*RÔ*RØ)6×):Ò):¸>È5Ñ)QÔ)Qð ?ñ 	ô 	ð Ô*Ý%Ø$Ið%ñ %ô %�Mð %Ð,Ý*Ð+QÑRÔRÐRØ'4×';Ò';ÀBÐ';Ñ'GÔ'GÐ$Ø'Ô/ð Ø˜Ý—N’NØfØ(Ô.ñô ð ð øõ !ð ð ð Ý—N’NØPÐRTñô ð ð ð ð ð ð øøøøðøøøõ ˜Ô,Ð.DÀcÑJÔJˆBÝ0ØØØØ -× 1Ò 1Ð2CÀTÑ JÔ JØ+×/Ò/°ÀÑFÔFØ*×.Ò.¨~¸uÑEÔEðñ ô ˆCðHÝ%=ØÔ'×,Ò,ØÔ+ØØ!$Ô!<ð -ñ ô ð
 Ô&Ý!Ø Eð	&ñ 	&ô 	&Ð"ð &Ð1Ø&×-Ò-°bÐ-Ñ9Ô9Ð9Ð9Ð9ð 2Ð1øåð Hð Hð HÝ—’ÐBÀBÑGÔGÐGÐGÐGÐGÐGÐGÐGøøøøðHøøøs8   ÂB1E Ä4 E Å
FÅE?Å?FÇ/AI É
I=ÉI8É8I=r§  )r�  Úresume_pendingÚlast_resume_marked_atr	  r¦  rå  Úresume_reasonr—  Úinteractive_resumer“  zù[System note: A new message has arrived. The conversation history contains pending tool outputs from an interrupted turn. IGNORE those pending results. Address the user's NEW message below FIRST. Do NOT re-execute old tool calls from the history.]

Ú_pending_skills_reload_notes)Úbuild_native_content_partsz:Native image attachment: skipped %d unreadable path(s): %sc              3   óH   K  — | ]}|                      d ¦  «        dk    V — ŒdS )rÎ   Ú	image_urlN©rv   r:  s     r>   rd   z&TurnRunner.run_sync.<locals>.<genexpr>¿  s1   è è € ÐHÐH¸A˜1Ÿ5š5 ™=œ=¨KÒ7ÐHÐHÐHÐHÐHÐHrM   z8Native image attachment failed, falling back to text: %s)Úconversation_historyr'  Úpersist_user_messageÚ
moa_configÚpersist_user_timestamp©rR  rò  Úcontext_compressorÚlast_prompt_tokensÚsession_prompt_tokensÚsession_completion_tokensÚcontext_lengthÚ_last_compaction_in_placeu/   Session split detected: %s â†’ %s (compression)uS   Skipping session split sync for stale run %s â€” generation %s is no longer currentr¿  znSkipping session split sync for %s because the session binding moved from %s to %s before compression finishedrµ  ©rN   uG   Restored source.thread_id=%s from binding after session split %s â†’ %sz<Failed to restore thread_id from binding after session splitrß   zagent-run-compression©r•  rÖ  rP   u   âš ï¸� r(  rç  rÚ  rÜ  ré  rõ  rè  Úinterrupt_messageÚcompression_exhaustedÚcompression_deferredr)  Úcompacted_in_place)Úinput_tokensÚoutput_tokensr  r|  r.  )r)  r*  r1  r  Úlast_reasoningr„  Úresponse_previewedÚresponse_transformedÚagent_persisted)r…  r  r|  rN   r‡  rˆ  r‰  rN  rŽ  ©F)±r  r(  r�   rÄ  rt  r­   Úcontext_promptr´  rx   r  Ú_get_system_prompt_for_channelr2  rV   r¢  Ú_resolve_session_agent_runtimer+   rA  r3   r4   rv   r2   Ú_provider_routingÚ!_resolve_session_reasoning_configÚ_reasoning_configÚ_resolve_session_service_tierÚ_service_tierÚstreaming_tts_consumer_holderrÆ  rð  rS  rÓ  Ú	transportrº   Ú"interim_assistant_messages_enabledÚgateway.stream_consumerrò  r@  Ú_build_stream_consumer_configrã  r8  r:  r3  rw   rP  Ú_resolve_turn_agent_configr$  Ú_agent_config_signaturer  Ú_extract_cache_busting_configr7   rN   Úsession_storeÚ_is_session_ended_in_dbrR   rS   Úget_sessionrz  r  rU  rt   r€  Ú_AGENT_PENDING_SENTINELrá   r  ÚKeyErrorÚ_init_cached_agent_for_turnÚ_interrupt_depthr  Ú_apply_fallback_chain_to_agentÚ_refresh_fallback_modelÚ	threadingÚThreadÚ_release_evicted_agent_softÚstartÚAIAgentr”  r  Ú_prefill_messagesr¹  r	  r)  r*  r´  r›  Ú_enforce_agent_cache_capÚneeds_progress_queueÚlog_mode_enabledr1  r\  Útool_progress_callbackr¯  rµ  Útool_start_callbackr¼  Úloaded_hooksrÁ  Ústep_callbackÚstream_delta_callbackÚinterim_assistant_callbackrç  Ústatus_callbackÚnotice_callbackÚnotice_clear_callbackrÅ  Úevent_callbackr  r  r  rf   Ú#_consume_pending_turn_sidecar_notesÚ_gateway_turn_context_notesÚEventÚLockÚbackground_review_callbackrá  rÎ   r=  Úrun_generationry   rA  Úclarify_callbackr=  Úthinking_progressr:  rÙ  Úprocess_task_idÚ_gateway_turn_process_task_idr/  Ú_gateway_turn_process_baseliner»  Útools_holderr  rÙ  rÖ  r  rã   rõ  rU   rP  Útools.approvalr\  r]  r^  r_  ru   rt  rv  rs  r’  r  Ú_entriesrž  Ú#_consume_pending_native_image_pathsÚagent.image_routingro  r
  r  ru  Úrun_conversationÚtools.clarify_gatewayrR  Úresult_holderÚfinishrx  Ú_saveÚ_record_gateway_session_peerÚTELEGRAMÚ%get_telegram_topic_binding_by_sessionÚ_sync_telegram_topic_bindingÚ_sync_session_model_from_agentrð  r"  rB  r•   r—   r”   rš   )wr  r?  Úcombined_ephemeralÚevent_channel_promptÚcfg_channel_promptr  r  Úruntime_kwargsr<   Úprr  r   Ú_scfgrð  Ú_plat_streamingÚ_streaming_enabledÚ_want_stream_deltasÚ_want_interim_messagesÚ_want_interim_consumerrò  r³  Ú_consumer_cfgÚ_pause_typing_before_finalizeÚ_sc_errr  Ú
turn_routeÚ_platforms_gw_cfgÚ_plat_gw_cfgÚ_skip_contextr  Ú_sigrµ   Úreused_cached_agentÚ_cache_lockÚ_cacheÚ_peek_cached_sidÚ_peek_entryÚ_cached_sid_is_deadÚ_current_msg_countÚ	_sess_rowÚ_xproc_evicted_agentÚcachedÚ
_cached_mcÚ_cached_sidÚ_session_id_mismatchÚ_stale_dead_sid_reuseÚevictedÚ	_ev_agentr0  r:  r<  Ú_pdcÚ
_mem_notifrZ  rù  rú  Ú	_selectedÚ_history_media_pathsr\  r]  r^  r_  ri  Ú_persist_user_message_overrideÚ _persist_user_timestamp_overrideÚ_pending_notesÚ_msnÚ_freshness_windowÚ_interruption_is_freshÚ_resume_entryÚ_resume_mark_is_freshÚ_is_resume_pendingÚ_has_fresh_tool_tailÚ_reasonÚ_resume_adapterÚ_interactive_resumeÚ_srnÚ
_sn_reasonÚ_sn_adapterÚ_approval_session_tokenÚ_native_imgsro  Ú_partsÚ_skippedÚ_run_messageÚ_img_excÚ_api_run_messageÚ_conversation_kwargsr·  Ú_clear_clarify_sessionrò  Ú_last_prompt_toksÚ_input_toksÚ_output_toksÚ_context_lengthÚ_agentÚ_resolved_modelÚ_session_was_splitÚ_compacted_in_placeÚagent_session_idr®  Ú_session_split_entry_persistedÚentry_session_idÚ_bindingÚeffective_session_idÚ_effective_history_offsetr=  r>  r¢   Úunique_tagsÚtagrh  r7  r8  r9  r2  rþ  rÿ  r  sw   `                                                                                                              @@@@@@@@r>   Úrun_synczTurnRunner.run_syncÊ  s%  øøøøøøøøø€ ØŒiˆð6 !$¤
Ô 3µx´~Ò EÐ E�u�uÈ3Ì:ÔK^ÔKdˆð
 !Ô/Ð5°2ÐØ #Ô 2Ð 8°b×?Ò?ÑAÔAÐØð 	^Ø"4°vÑ"=Ð@TÑ"T×![Ò![Ñ!]Ô!]ÐØ!œ\×HÒHØŒJÔØŒJÔÐ$ "Ý˜cœj¨+°tÑ<Ô<Ý˜cœjÐ*:¸DÑAÔAð	 Iñ 
ô 
Ðð ð 	\Ø"4°vÑ"=Ð@RÑ"R×!YÒ!YÑ![Ô![Ðå0Ñ2Ô2ˆð	Ø$(¤L×$OÒ$OØ”zØœOØœOð %Pñ %ô %Ñ!ˆE�>õ
 �LŠLØEØ�~×)Ò)¨*Ñ5Ô5°s´Ð7LÈ"ñô ð ð øõ ð 	ð 	ð 	à"QÈCÐ"QÐ"QØØØð	ð ð ð ð ð ð ð øøøøð	øøøð Œ\Ô+ˆØœ<×IÒIØ”:ØœØð Jñ 
ô 
Ðð
 *:ˆŒÔ&Ø%)¤\×%OÒ%OØ”:¨3¬?ð &Pñ &
ô &
ˆŒÔ"ð  ÐØÐð
 !Ô>¸qÔAÐÝ� ¤¨h¸Ñ=Ô=¸{ÈDÑQÔQˆØˆ=Ø6Ð6Ð6Ð6Ð6Ð6Ø#�OÑ%Ô%ˆEð
 ×5Ò5ØŒO˜\¨;ñ
ô 
ˆð Ð&ð ŒMÐ6˜eœo°Ò6øå�oÑ&Ô&ð 	ð
 1ÐØ!$Ô!GÐØ!7ÐØð "	NÐ"8ð "	Nð!NØIÐIÐIÐIÐIÐIØœ<×;Ò;¸C¼JÑGÔG�Øð Eàœ×BÒBØœJ¨¨xØ.5ð Cñ ô ñ A�MÐ#@ð (=Ð'<Ø (Ø #¤
Ô 2Ø,Ø!$Ô!<ð  #Ô1Ð=ð LÐKÐKÐKÐKà!%à+HØ,/Ô,@Ø*-Ô*@ð(ñ (ô (Ð$ð +ð FðFµ3ð F¸4ð Fð Fð Fð Fð Fð Fð Fð Fð 5E�CÔ.¨qÑ1øøÝð Nð Nð NÝ—’ÐCÀWÑMÔMÐMÐMÐMÐMÐMÐMøøøøðNøøøð Ð#Ð(:Ð(Fð6¥sð 6¨tð 6ð 6ð 6ð 6ð 6ð 6ð 6ð JOð 	ð 	ð 	­ð 	Å$ð 	ÐSWð 	ð 	ð 	ð 	ð 	ð 	ð 	ð. ”\×<Ò<¸S¼[È%ÐQ_Ñ`Ô`ˆ
ð !œ_×0Ò0°Ñ;Ô;ÐA¸r×FÒFÀ{ÑSÔSÐYÐWYÐØ(×,Ò,¨\Ñ:Ô:Ð@¸bˆØ$×(Ò(Ð)=Ñ>Ô>ˆØ4AÐ4M�T -Ñ0Ô0Ð0ÐSXÐð
 Œ|×3Ò3Ø�wÔØ�yÔ!ØÔ ØØ”|×AÒAÀ#Ä/ÑRÔRÝ˜CœJ¨	°4Ñ8Ô8Ý ¤
¨M¸4Ñ@Ô@Ø1ð 4ñ 	
ô 	
ˆð ˆØ#ÐÝ˜dœlÐ,?ÀÑFÔFˆÝ˜œ ~°tÑ<Ô<ˆð   ÐØð 	2˜6Ð-Øð :ð :Ø$Ÿjšj¨¬Ñ9Ô9�ð:ð :ð :ñ :ô :ð :ð :ð :ð :ð :ð :øøøð :ð :ð :ð :àð 2�s ;Ñ/Ô/°!Ò3Ð3Ø#.¨q¤>Ð Ø#ÐàÐ(Ø”Ð*Ø  C¤NÒ2Ð2ð,Ø&*¤lÔ&@×&XÒ&XØ$ñ'ô 'Ð#Ð#øõ ð ,ð ,ð ,Ø&+Ð#Ð#Ð#ð,øøøð "ÐØŒ<Ô#Ð/°C´NÐ/ðà œLÔ4Ô8×DÒDÀSÄ^ÑTÔT�	Øð KØ)2¯ª°ÈÑ)JÔ)JÐ&øøÝð ð ð Ø�ðøøøð  $ÐØñ n	3˜6Ñ-Øð m3ð m3ØŸš C¤OÑ4Ô4�Øñ k3˜f Qœi¨4Ò/Ñ/õ /2°&©k¬k¸Aªo¨o ¨¤ À4�JÝ/2°6©{¬{¸Qª¨ &¨¤) )ÀD�Kð $¨4Ð/ð :ØœN°$Ð6ð:à'¨3¬>Ò9ð )ð -ð <Ø/ð<à'Ð+;Ò;ð *ð
 -ð M3õ  ŸšðBð
  œO¨[ñô ð ð #'¤,Ô";×"?Ò"?ÀÄÐQUÑ"VÔ"V˜Ý2<¸WÅeÑ2LÔ2LÐ$bÐQXÐ$b G¨A¤J JÐ^b˜	Ø$ð =¨Õ:QÐ)QÐ)Qð
 4=Ð0ùà0ð-3à&Ð2Ø.Ð:Ø.°*Ò<Ð<õ Ÿšð;ð  œO¨ZÐ9Kñ	ô ð ð #'¤,Ô";×"?Ò"?ÀÄÐQUÑ"VÔ"V˜Ý2<¸WÅeÑ2LÔ2LÐ$bÐQXÐ$b G¨A¤J JÐ^b˜	Ø$ð =¨Õ:QÐ)QÐ)Qð 4=Ð0øà & q¤	˜õ # 6¨=Ñ9Ô9ð %ð%Ø &× 2Ò 2°3´?Ñ CÔ CÐ CÐ CøÝ#+ð %ð %ð %Ø $ ð%øøøàœ×@Ò@ÀÈÔH\Ñ]Ô]Ð]ð 0>˜Ô,ÝŸšÐ%JÈCÌOÑ\Ô\Ð\Ø.2Ð+ð[m3ð m3ð m3ñ m3ô m3ð m3ð m3ð m3ð m3ð m3ð m3øøøð m3ð m3ð m3ð m3ðl ð 	 5Ð#4ØŒL×7Ò7Ø�t”|×;Ò;Ñ=Ô=ñô ð ð  Ð+ðÝÔ Øœ<ÔCØ.Ð0ØØI­c°#´/Ñ.BÔ.BÀ3ÀBÀ3Ô.GÐIÐIð	ñ ô ÷
 ’%‘'”'�'�'øÝð ð ð ðØ”L×<Ò<Ð=QÑRÔRÐRÐRøÝ ð ð ð Ø�Dðøøøøøðøøøð ‰=à�C”Kð %ð %Ø  Ô)ð%à˜YÔ'ð%õ +¨3¬?Ñ;Ô;ð%ð %ð %ð  .˜~ð	%ð
  ˜4ð%ð !& ð%ð "%Ô!5Ð!5ð%ð #&Ô"7Ð"7ð%ð );Ð(B¸døð%ð "&¤Ô!?Ð!GÀ4øð%ð "2Ð!1ð%ð "œ\Ô7Ð7ð%ð #-§.¢.Ð1DÑ"EÔ"EÐ"Eð%ð #%§&¢&¨¡.¤. .ð%ð #%§&¢&¨Ñ"2Ô"2Ð"2ð%ð  !#§¢ w¡¤ ð!%ð" !Ÿfšf V™nœn˜nð#%ð$ -/¯FªFÐ3GÈÑ,OÔ,OÐ,Oð%%ð& *,¯ªÐ0AÑ)BÔ)BÐ)Bð'%ð( œ>˜>ð)%ð* &˜ð+%ð, œ
Ô*Ð*ð-%ð.  œJÔ2Ð2ð/%ð0 œ*Ô.Ð.ð1%ð2 œ
Ô*Ð*ð3%ð4 œ*Ô.Ð.ð5%ð6 œ*Ô.Ð.ð7%ð8 œ*Ô.Ð.ð9%ð: %(¤O Oð;%õ< # 4¤<Ô#;¸UÀDÄLÔD\Ñ]Ô]Ð]ð=%ð@  $œ|×CÒCÑEÔEÐEðA%ðB $6Ð#5ðC%ðH $( 4ðI%ð %ˆEðL ð 
<˜vÐ1Ø ð 	<ð 	<ð ˜tÐ%7¸¼ð/�F˜3œ?Ñ+ð ”L×9Ò9Ñ;Ô;Ð;ð	<ð 	<ð 	<ñ 	<ô 	<ð 	<ð 	<ð 	<ð 	<ð 	<ð 	<øøøð 	<ð 	<ð 	<ð 	<õ �LŠLÐDÀcÄoÐW[Ñ\Ô\Ð\ð Ô(ðð Ô'ðð Ô+Ð7ð	 Ô!Ð!ð ð 	Ô$ð '*Ô&:¸1Ô&=Ð&IˆCÔ"Ð"Ètð 	Ô!ð :=¼Ô9TÐ^˜cÔ5Ð5ÐZ^ˆÔØ&6ˆÔ#ØDZÐ+dÐ+@Ð+@Ð`dˆÔ(Ø #Ô 9ˆÔð	ð 	ð 	ð 	ð 	ð 	ð 	ð" !6ˆÔØ&*ˆÔ#Ø"Ô7ˆÔØ!1ˆÔØ!œ\Ô7ˆÔØ",§.¢.Ð1DÑ"EÔ"EÐ"KÈˆÔð -3¯KªKØŒL×<Ò<¸S¼_ÑMÔMñ-
ô -
ˆÔ)õ 'œ_Ñ.Ô.ÐØ(*ÐÝ"+¤.Ñ"2Ô"2Ðð	µð 	¸ð 	ð 	ð 	ð 	ð 	ð 	ð	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð	0¥Sð 	0¨Tð 	0ð 	0ð 	0ð 	0ð 	0ð 	0ð 	0ð 	0ð 	0ð 	0ð ,;ˆÔ(ð Ôð 
	H 3¤?ð 
	HÝ•t˜CÔ/Ñ0Ô0Ð2SÐUYÑZÔZÐfØÔ#×CÒCØ”OØ/Ø"Ô1ð Dñ ô ð ð õ ˜sÔ2Ð4NÐPTÑUÔU�ØÐ#Ø,G�D˜œÑ)ð
 ”_×(Ò(¨°BÑ7Ô7×;Ò;Ð<RÑSÔSˆ
Ý�j¥$Ñ'Ô'ð 	7Ø!+Ð6˜˜°ˆJØ@JÐ%T¥S¨¡_¤_×%:Ò%:Ñ%<Ô%<Ð%<ÐPTˆÔ"ðP	ð P	­Sð P	Íð P	ÕZ]ð P	ð P	ð P	ð P	ð P	ð P	ðd "8ˆÔð
 #&Ô"7ˆÔà#ˆÔ˜Ñð 	×+Ò+¨E°3Ñ7Ô7Ð7ð /2Ô.AˆÔ+Ø/2Ô/CˆÔ,å-4°U¸GÑ-DÔ-DÐN˜eœk˜kÈ$ˆÔ˜Ñö  1MØŒKØÔ-Þ9¸#¼/ÑJÔJð1
ñ 1
ô 1
Ñ-ˆÐ-ð ð 	¥7¨5°,ÀÑ#EÔ#EÈÌÒ#WÐ#WÞ4Ø�w uÐ.AÀ4ÑHÔHñô ˆIð  Ð-Ð-Ý—’ðKð ”O¥S¨Ñ%7Ô%7½¸Y¹¼ñ	ô ð ö !DØ¦4¤9¡;¤;ð!ñ !ô !�ö %AÀÑ$OÔ$OÐð	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ðY	H¶ð Y	H¸$ð Y	Hð Y	Hð Y	Hð Y	Hð Y	Hð Y	Hð Y	Hð| 9<Ô8PÐ&Ø<?Ô<VÐ(õ ! ¤Ð/EÀrÑJÔJˆØ<?¼OÐUˆ~×!Ò! #¤/°4Ñ8Ô8Ð8ÐQUˆØð 	6Ø ™-¨#¬+Ñ5ˆCŒKö0 <Ñ=Ô=ÐÞ!?Þ& s¤{Ñ3Ô3Ø)ð"
ñ "
ô "
Ðð
 ˆØŒ?ð 	%ð%Ø $¤Ô :Ô C× GÒ GÈÌÑ XÔ X��øÝð %ð %ð %Ø $���ð%øøøð  !&ÐØÐ$­°Ð@PÐRWÑ)XÔ)XÐ$Þ$BÝ˜Ð'>ÀÑEÔEØ-ð%ñ %ô %Ð!õ "Ø Ð%ð BÝ˜Ð'7¸Ñ?Ô?ðBà'Ð@Ð+@ñ
ô 
Ðõ
  $Øð 'Ø˜bÔ!×%Ò% fÑ-Ô-°Ò7ð'à&ñ 
ô  
Ðð ð 	Ý˜m¨_¸dÑCÔCÐXÐGXˆGØ-0¬[Ð*ð #œl×>Ò>¸s¼zÑJÔJˆOÝ"&Ý˜Ð)=¸tÑDÔDñ#ô #Ðö 5Ø˜œÐ2Eðñ ô ˆCŒKˆKð "ð 	Ø-0¬[Ð*ðWð ”+ñ	ð ŒKõ ! ¤Ð/MÈtÑTÔTˆØð 	:˜cœoð 	:°#´/À^Ð2SÐ2SØ!×%Ò% c¤o°tÑ<Ô<ˆDØð :Ø" V™m¨c¬kÑ9�”õ �s”{¥CÑ(Ô(ð	à”K×%Ò%Ñ'Ô'ð	ð Ð)Ý˜Ð'7¸Ñ?Ô?ð *õ ˜ ¸Ñ=Ô=ÐRÐARð ð œ,×:Ò:¸3¼:ÑFÔFˆKÞ4ØØÝ Ý˜KÐ)=¸tÑDÔDñô ðñ ô ˆCŒKð !$¤Ð 5°2ÐØ"9Ð"9Ð:OÑ"PÔ"PÐØÐÐ 5Ð7LÑMÔMÐMð;	?ð
  œ<×KÒKÈCÌOÑ\Ô\ˆLØð +ð/ØNÐNÐNÐNÐNÐNØ'AÐ'AØœØ$ñ(ô (Ñ$�F˜Hð  ð ÝŸšØXÝ ™MœM¨8ñô ð ö ÐHÐHÀÐHÑHÔHÑHÔHð 3Ø,2˜˜ð (+¤{˜øøÝ ð /ð /ð /Ý—N’NØRØ ñô ð ð $'¤;�L�L�L�L�L�Løøøøð/øøøð  #œ{�æJØØ&ñ ô  Ðð
 )6Øœ>ð$ð $Ð ð .Ð9Ø?]Ð$Ð%;Ñ<Ð<Ø'ð KØ?B¼{Ð$Ð%;Ñ<ØŒ~Ð)Ø58´^Ð$ \Ñ2Ø/Ð;ØAaÐ$Ð%=Ñ>Ø+�UÔ+Ð,<ÐUÐUÐ@TÐUÐUˆFà%Ð%Ð&;Ñ<Ô<Ð<ðØYÐYÐYÐYÐYÐYØ&Ð&Ð'<Ñ=Ô=Ð=Ð=øÝð ð ð Ø�ðøøøà%Ð%Ð&=Ñ>Ô>Ð>Ð>øð &Ð%Ð&;Ñ<Ô<Ð<ðØYÐYÐYÐYÐYÐYØ&Ð&Ð'<Ñ=Ô=Ð=Ð=øÝð ð ð Ø�ðøøøà%Ð%Ð&=Ñ>Ô>Ð>Ð>øøøØ%ˆÔ˜!Ñð Ð'Ø×#Ò#Ñ%Ô%Ð%ð  ŸšÐ$4Ñ5Ô5ˆð ÐØˆØˆØˆØÔ! !Ô$ˆØð 	[•g˜fÐ&:Ñ;Ô;ð 	[Ý '¨Ô(AÐCWÐYZÑ [Ô [ÐÝ! &Ð*AÀ1ÑEÔEˆKÝ" 6Ð+FÈÑJÔJˆLÝ% fÔ&?ÐAQÐSTÑUÔUÐZÐYZˆOØ<BÐL�' &¨'°4Ñ8Ô8Ð8Èˆð
 Ô  Ô#ˆØ"Ðð [`Ðj�d¥7¨5Ð2MÈuÑ#UÔ#UÑVÔVÐVÐejÐØKPÐd�7 5¨,¸¼ÑGÔGÐGÐVYÔVdÐØñ J	�S”_ñ J	Ð)9¸S¼^Ò)KÑ)KØ!%ÐÝ�KŠKØAØ”Ð 0ñô ð ð ”LÔ.Ô7×;Ò;¸C¼OÑLÔLˆEØ-2Ð*Øð :Ý#*¨5°,ÀÑ#EÔ#EÐ Ø×-Ò-Ñ/Ô/ð :Ý—K’Kð=àœÐ.¨3ØÔ*ñ	ô ð ð ð &Ð)9Ò9Ð9Ø59Ð2Ð2Ø%¨¬Ò7Ð7Ý—K’Kð/ð œÐ.¨3ØœØ(ñô ð ð ð (8�EÔ$Ø”LÔ.×4Ò4Ñ6Ô6Ð6Ø”LÔ.×KÒKØ(ØœØœ
ñô ð ð
 6:Ð2ð .ñ Ý˜œ
 J°Ñ5Ô5½Ô9JÒJÐJÝ˜CœJ¨°TÑ:Ô:¸dÒBÐBÝ˜CœJ¨°TÑ:Ô:ÐBØ”LÔ,Ð8ðà#œ|Ô7Ô;×aÒaØ#3ð  bñ  ô  �Hð  ð  H§L¢L°Ñ$=Ô$=ð Ý/2°8¸KÔ3HÑ/IÔ/I˜œ
Ô,ÝŸšØeØœJÔ0ØœNØ,ñ	ô ð øøõ !ð ð ð Ý—L’LØVØ!%ð !ñ ô ð ð ð ðøøøð
 .ð Ø”×9Ò9Ø”J Ð.Eð :ñ ô ð ð  0ÐØŒ×3Ò3Ð4HÈ%ÑPÔPÐPð %ÐTÐ(;ÐTˆAˆAÅ#ÀmÑBTÔBTð 	"ð ñ #	Þ<Ø˜Ð,¨"½#¸mÑ:LÔ:Lðñ ô ˆNö >¸c¼jÔ>QÐSaÑbÔbˆNØ!ð \Ø@FÇ
Â
È7Ñ@SÔ@SÐ![Ð!<¨6°'¬?Ð!<Ð!<Ð!<ÐY[�ðØ  .ðà˜FŸJšJ z°2Ñ6Ô6ðð ˜VŸZšZ¨°QÑ7Ô7ðð ˜&Ÿ*š* X¨uÑ5Ô5ð	ð ! &§*¢*Ð-=Ñ">Ô">ðð ˜6Ÿ:š: i°Ñ7Ô7ðð ˜VŸZšZ¨Ñ4Ô4ðð ˜vŸzšz¨-¸Ñ?Ô?ðð $ V§Z¢ZÐ0CÑ%DÔ%Dðð  ˜Ÿš GÑ,Ô,ð!ð" (¨¯ªÐ4KÈUÑ)SÔ)Sð#ð$ '¨¯
ª
Ð3IÈ5Ñ(QÔ(Qð%ð& ˜Ô)¨!Ô,Ð2°ð'ð( !Ð";ð)ð* %Ð&9ð+ð, Ð2ð-ð. %Ð&7ð/ð0 !,Ø!-Ø(Ø"1ð7ð ð ð ðd ˜>Ð)Ð)Þ.MØ—
’
˜: rÑ*Ô*Ý" =Ñ1Ô1Ø$8ð/ñ /ô /Ñ+ˆJÐ+ð ð 	PÞ‘u”u�Ø �Ø%ð 0ð 0�CØ $��ØŸš ™œ˜Ø#×*Ò*¨3Ñ/Ô/Ð/øØ&ð @Ø×&Ò& qÐ*>Ñ?Ô?Ð?Ø!/°$Ñ!6¸¿ºÀ;Ñ9OÔ9OÑ!O�ð%
Ø˜nð%
à˜fŸjšjÐ)9Ñ:Ô:ð%
ð ÀCÔDUÐVWÔDXÐ`˜Ô)¨!Ô,×0Ò0°¸RÑ@Ô@Ð@Ð^`ð%
ð ÀSÔEVÐWXÔEYÐ`˜Ô*¨1Ô-×1Ò1°+¸qÑAÔAÐAÐ_`ð	%
ð
 À3ÔCTÐUVÔCWÐb�cÔ'¨Ô*×.Ò.¨x¸Ñ?Ô?Ð?Ð]bð%
ð Ø>AÔ>OÐPQÔ>RÐ\�Ô! !Ô$×(Ò(Ð)9Ñ:Ô:Ð:ÐX\ð%
ð À#ÔBSÐTUÔBVÐ`˜Ô*¨1Ô-×1Ò1°+Ñ>Ô>Ð>Ð\`ð%
ð ÈSÔM^Ð_`ÔMaÐl˜3Ô,¨QÔ/×3Ò3°MÀ5ÑIÔIÐIÐglð%
ð ÀSÔEVÐWXÔEYÐd�sÔ(¨Ô+×/Ò/°	¸5ÑAÔAÐAÐ_dð%
ð ¸#Ô:KÈAÔ:NÐX�SÔ& qÔ)×-Ò-¨gÑ6Ô6Ð6ÐTXð%
ð  ÐRUÔRcÐdeÔRfÐ!p Ô!2°1Ô!5×!9Ò!9Ð:MÑ!NÔ!NÐ!NÐlpð%
ð" #àÔ$ QÔ'ð3�Ô! !Ô$×(Ò(Ð)?ÀÑGÔGÐGØ-2ð'%
ð* �SÔ% aÔ(Ð.¨Bð+%
ð, Ð7ð-%
ð. !Ð"5ð/%
ð0 !Ð"3ð1%
ð2 ˜Kð3%
ð4 *Ø$Ø-Ø.Ø"(§*¢*Ð-AÀ5Ñ"IÔ"IØ$*§J¢JÐ/EÀuÑ$MÔ$Mð
 VYÔUfÐghÔUiÐ s Ô 1°!Ô 4× 8Ò 8Ð9JÈDÑ QÔ QÐ QÐosðI%
ð %
ð %
ð %	
s­  ÄA&E, Å,
F
Å6	FÅ?F
ÆF
ÊB"L6 Ì6
M%Í M Í M%ÓS>Ó>TÔTÔ=U ÕU,Õ+U,ÖAW ×
W×W×!F_;Ý;^Þ_;Þ
^#Þ _;Þ"^#Þ#A_;ß;_?à_?à?Ab â
câb8â7câ8
cãcãcãcã
cê-këkëký%)~ þ~þ~ÁG !AL; ÁHA)AI, ÁI+AL; ÁI,
AJ"ÁI6"AJÁJAL; ÁJAJ"ÁJ"AAL; ÁLAL ÁL
AL,ÁL+AL,ÁL;AM6ÁMAMÁMAM6ÁM
AM'ÁM$AM6ÁM&AM'ÁM'AM6ÁX3BAZ; ÁZ;&A[$Á[#A[$©NNNrŽ  )rÏ   r©  rª  r«  rp  r  rw   ru   r\  r©  rµ  rh  r½  rÁ  rÅ  rÙ  rç  r!  rN  rM   r>   r  r  »  sV  € € € € € ð	ð 	ð˜ð °[ð ÀTð ð ð ð ðC$ð C$¨Cð C$¸Cð C$ÐQTð C$Ðcgð C$ð C$ð C$ð C$ðJa'ð a'ð a'ðFDð Dð Dð*
¨Sð 
¸dð 
Àtð 
ð 
ð 
ð 
ð6>¨sð >¸Tð >Àdð >ð >ð >ð >ð7Sð 7Sð 7Sð 7Sðr"5°ð "5¸cð "5Àdð "5ð "5ð "5ð "5ðHV
ð V
ð V
ð V
ð V
rM   r  c            !       óv,  — e Zd ZU dZdZeed<   dZeed<   eZ	e
ed<   eZe
ed<   dZee         ed<   d	Zeed
<   d	Zeed<   d	Zeed<   d	Zeed<   d	Zeed<   d	Zeed<   d	Zeed<   dZee         ed<   dZeej                 ed<   dZeej                 ed<   dZeeeee ej        f         f                  ed<   dZ!ee"         ed<   d	Z#eed<    e$d¦  «        Z% e$d¦  «        Z& e$d¦  «        Z' e$d¦  «        Z( e)¦   «         Z* e$d¦  «        Z+ e$d¦  «        Z, e$d¦  «        Z- e$d¦  «        Z. e$d¦  «        Z/ e$d ¦  «        Z0 e$d!¦  «        Z1 e$d"¦  «        Z2 e$d#¦  «        Z3 e$d$¦  «        Z4 e$d%¦  «        Z5 e$d&¦  «        Z6 e$d'¦  «        Z7 e$d(¦  «        Z8d)eed*f         fd+„Z9d,ed)d*fd-„Z:d,ed)ed*         fd.„Z;d,ed)efd/„Z<d)e=e>         fd0„Z?dZ@ed1         ed2<   dZAee"         ed3<   dZBee"         ed4<   d5ZCe
ed6<   dZDed7         ed8<   d	ZEeed9<   dZFed1         ed:<   �d+d;eeG         fd<„ZH�d,d=„ZI�d,d>„ZJd)efd?„ZKeLd@z  ZMdAe dBed)efdC„ZNd)eeef         fdD„ZO�d,dE„ZPdBedFed)dfdG„ZQdBedHed)dfdI„ZR�d,dJ„ZSdKeTe"         dLe
d)efdM„ZU�d,dN„ZVddOœdPee         d)dfdQ„ZWd)e
fdR„ZX�d+d)e
fdS„ZYd	dTœdUed)efdV„ZZd)efdW„Z[e\d)efdX„¦   «         Z]e\d)efdY„¦   «         Z^e\d)ee         fdZ„¦   «         Z_e\d)ee         fd[„¦   «         Z`d\ed)efd]„Zad\ed)efd^„Zb ecd_d`h¦  «        Zdd\ed)efda„Zed\ed)efdb„ZfdcZgd\ed)efdd„Zhd)efde„Zid)efdf„Zjd\ed)ee         fdg„Zkd\ed)dfdh„Zld\edied)dfdj„Zmd\ed)ee         fdk„Znd\ed)efdl„Zoddddmœd\ee         d,ee         dneep         d)e>eepf         fdo„Zqdpedqedrepd)epfds„Zrdtedue"d)dfdv„Zsdweee"f         d)dfdx„Ztdyeud)dfdz„Zvdyeud)efd{„Zwdyeud)dfd|„Zxdyeud)dfd}„Zydied)dfd~„Zzd)efd„Z{d)efd€„Z|d)efd�„Z}d)efd‚„Z~died)efdƒ„Zd)efd„„Z€d)e
fd…„Z�d)e>fd†„Z‚d)efd‡„Zƒ�d,dˆ„Z„d)efd‰„Z…�d,dŠ„Z†d‹„ Z‡�d-dŒe
d)dfd�„Zˆd)efdŽ„Z‰d)efd�„ZŠd)efd�„Z‹d,ed‘d’dye"d)dfd“„ZŒd,edye"d”ed’         d)ed’         fd•„Z�dd–œd,edye"d)efd—„ZŽe�d˜e"d)efd™„¦   «         Z�d,edye"d)efdš„Z‘dted)efd›„Z’�d.dœee         d�ee         d)dfdž„Z“�d,dŸ„Z”�d,d „Z•�d,d¡„Z–�d/dŒe
d)dfd£„Z—dddd¤œdAed¥ee         d¦ee         d§ee         d)df
d¨„Z˜d_d©œdied)dfdª„Z™d)efd«„Zše�d)e=eee"f                  fd¬„¦   «         Z›e�d)efd­„¦   «         Zœdddd®œdAe dBedneep         d¯ee         d°ee         d)efd±„Z�ddd²œdAe dBed¯ee         d°ee         d)ef
d³„Zže��d0dqed)epdz  fd´„¦   «         ZŸe�dµed)e>eef         fd¶„¦   «         Z ddd_d·œd\ee         d,ee         dqed)epdz  fd¸„Z¡d,ed¹eep         d)dfdº„Z¢	 	 �d.d,ee         d)ee         fd»„Z£	 �d1d,ed¼ed)dfd½„Z¤e�d)edz  fd¾„¦   «         Z¥e�d)efd¿„¦   «         Z¦e�d)efdÀ„¦   «         Z§e�d)efdÁ„¦   «         Z¨e�d)e
fdÂ„¦   «         Z©e�d)e
fdÃ„¦   «         Zªe�d)efdÄ„¦   «         Z«e�d)epfdÅ„¦   «         Z¬e�d)e­dz  fdÆ„¦   «         Z®d)e­dz  fdÇ„Z¯e�due"dÈe­dz  d)dfdÉ„¦   «         Z°d)eee"f         fdÊ„Z±d)ee         fdË„Z²d,ed)ee         fdÌ„Z³d,ed\ed)e>e"ee         f         fdÍ„Z´e�dÎe"d)efdÏ„¦   «         Zµd,ed)efdÐ„Z¶e�d,efdÑ„¦   «         Z·dÒZ¸d,edÓe¹d)dfdÔ„ZºdÓe¹d)efdÕ„Z»dÓe¹d,ed)efdÖ„Z¼dLe
d)e>eee"f         ef         fd×„Z½died)dfdØ„Z¾�d,dÙ„Z¿dÚeee"f         d)dfdÛ„ZÀd,ee         due"dÜee"         d)efdÝ„ZÁdcZÂdÞejÃ        due"dßed)dfdà„ZÄd_dáœdue"dßed)dfdâ„ZÅdue"d)dfdã„ZÆdäZÇdåZÈdæeÉd)dfdç„ZÊd)efdè„ZËd,ed)dfdé„ZÌ�d,dê„ZÍ�d,dë„ZÎd)efdì„ZÏd	d	díœdîedïed)efdð„ZÐ ech dñ£¦  «        ZÑdyeudÓe¹d,ed)dfdò„ZÒdÓe¹d)dfdó„ZÓd)efdô„ZÔ�d,dõ„ZÕe��d2d÷„¦   «         ZÖd)efdø„Z×�d+d)efdù„ZØd)efdú„ZÙ	 	 �d.dyeeu         dAee          d)efdû„ZÚdüejÛ        d)dfdý„ZÜ�d,dþ„ZÝd)efdÿ„ZÞd)e>eef         f�d „Zßd)ef�d„Zà�dZá�dZâ�d�dd�dœ�d„Zã�d3dŒe
d)df�d	„Zä�d
eee"f         d)df�d„Zå�d4dŒef�d„Zæd)e
f�d„Zç�d„ Zèd,ed)eep         f�d„Zé�de
d)ef�d„Zê�d-dŒe
f�d„Zëd)ef�d„Zì�d,�d„Zí�d,�d„Zî�d,�d„Zïd)ef�d„Zð�d,�d„Zñd	d	d	�dœ�de�de�ded)df�d„Zò�d,�d„Zód)ef�d„Zô�d e�d!�d"�d#ee>ef         d)ef�d$„Zõdyeu�d edAe d)df�d%„Zö�d edAe d)df�d&„Z÷�d edAe dyeud)df�d'„Zø�d edAe d)eùeugeTd         f         f�d(„Zú�d edAe dyeud)df�d)„Zû�d ef�d*„Zü�d+„ Zý�d,„ Zþe�dAe dye"d)ee>         f�d-„¦   «         Zÿe�dAe dye"d)ee>         f�d.„¦   «         �Z e�dye"d)ee         f�d/„¦   «         �ZdAe d;e"d)eeu         f�d0„�Z	 �d+dAe �d ee         d)eùeee         ee         gef         f�d1„�Z�d2ed)df�d3„�Z�d4�e�d5ed)e�e         f�d6„�Z�d7�d8�d9�d:œ�Zeeef         e�d;<   dÓe¹�d<ef�d=„�ZdÓe¹f�d>„�Z	dÓe¹�d<ef�d?„�Z
dÓe¹�d<ef�d@„�ZdÓe¹�d<ef�dA„�ZdÓe¹�d<ef�dB„�ZdÓe¹�d<ef�dC„�ZdÓe¹�d<ef�dD„�ZdÓe¹�d<ef�dE„�ZdÓe¹d)ee         f�dF„�ZdÓd’�d<ed)df�dG„�Zd,ed)df�dH„�Zd�dIœdÓe¹d\e�dJe=eee"f                  d,ee         d)ee         f
�dK„�Zd�dIœdÓe¹d\e�dJe=eee"f                  d,ee         d)ee         f
�dL„�Zd)ef�dM„�Zd,ed)e=e         f�dN„�Zd,ed)df�dO„�Ze\d)�ef�dP„¦   «         �ZdÓd’d,ed)ef�dQ„�ZdÓd’d)ef�dR„�Zd,ef�dS„�Z�dTe�dUef�dV„�Zd\ed)ef�dW„�Zd)ef�dX„�Z d\e�dYed)ee         f�dZ„�Z!d\e�d[ed)e­f�d\„�Z"dÓe¹d)ef�d]„�Z#dÓe¹d)ef�d^„�Z$dÓe¹f�d_„�Z%d)ef�d`„�Z&�d5�da„�Z'�d5�db„�Z(�d<ed\e"dted)df�dc„�Z)�d<ed)df�dd„�Z*�d,�de„�Z+d\e"�dfed)df�dg„�Z,d\e"�dfed)df�dh„�Z-�d4e"d\e"�died)df�dj„�Z.e�dÓe¹d)ee         f�dk„¦   «         �Z/dÓe¹d)ef�dl„�Z0dÓe¹d)ef�dm„�Z1dBed)df�dn„�Z2�doe�dpe�dqed)ef�dr„�Z3�doe�dpe�dqef�ds„�Z4	 �d1dÓe¹�dte�due­�dved)ef
�dw„�Z5d)ef�dx„�Z6dÓe¹�dyed)df�dz„�Z7	 �d+�dtedÓe¹�d{eeee"f                  d)df�d|„�Z8	 	 	 	 �d6�dted\e�d}eeee"f                  �d~ee         �de�d€ed)df�d�„�Z9	 	 	 �d7�d‚ed\�dƒ�d„e�d~ee         �d…ee=e                  �d†ee=e                  d)df�d‡„�Z:	 	 	 �d7�d‚ed\�dƒ�d„e�d~ee         �d…ee=e                  �d†ee=e                  d)df�dˆ„�Z;d\ed)epf�d‰„�Z<d\ed)df�dŠ„�Z=d\ed)df�d‹„�Z>�dŒed)ef�d�„�Z?d\ed)ef�dŽ„�Z@d\ed)ef�d�„�ZAd\ed)e�eBeef                  f�d�„�ZCd\ed)e�eBeef                  f�d‘„�ZD�dŒed)ef�d’„�ZE	 �d+d\edte�dŒe�d“e�eBeef                  d)df
�d”„�ZFd\edte�dŒed)df�d•„�ZGd\edte�dŒed)df�d–„�ZHd\ed)ef�d—„�ZId\edte�dŒed)df�d˜„�ZJ�d™�ZKd\ed)ef�dš„�ZLd)ef�d›„�ZMd\ed)ef�dœ„�ZNd\ed)ef�d�„�ZOdÓe¹�džed)ef�dŸ„�ZPdÓe¹d)ef�d „�ZQdÓe¹�d¡e�dŒe�d¢ed)�eRe�d£df         f
�d¤„�ZSdÓe¹�d¡e�dŒe�dfed)ee         f
�d¥„�ZTd)eee"f         f�d¦„�ZU	 �d+�d§ee         d)eeee"f                  f�d¨„�ZVddd�d©œdAee          dBee         d¯ee         �dªee         �d§ee         dyee"         d)eeee"f                  f�d«„�ZWe�dd�d¬œdAee          dBee         d¯ee         �dªee         dyee"         d)ef�d­„¦   «         �ZXe�dÓe¹d)ee         f�d®„¦   «         �ZY�d�ZZ ece �j[        e �j\        e �j]        e �j^        e �j_        e �j`        e �ja        e �jb        e �jc        e �jd        e �je        e �jf        e �jg        e �jh        e �ji        h¦  «        �Zj�d,�d¯„�Zk	 	 	 �d8�d²e
�d³e
dLe
d)df�d´„�Zld)ef�dµ„�Zmd)ee>eeee         f                  f�d¶„�Znd�d·œ�d¸eeÉe>eeee         f                           d)eÉe>eeee         f                  f�d¹„�Zodß�epd)e­f�dº„�Zq�d»e­d)df�d¼„�Zr�d½„ �Zsd)�et�ju        �jv        f�d¾„�Zw�d,�d¿„�Zxddddd�dÀœd\ee         d,ee         dneep         �dÁee         dqee         d)ef�dÂ„�Zy�dÃe�dÄe=e         d)ef�dÅ„�Zz�dÃe�dÆe=e         d)e>ee=e         f         f�dÇ„�Z{d)e=e         f�dÈ„�Z|	 �d+�dÃee         d)e>edz  e=e         f         f�dÉ„�Z}d�dÊ�dËœ�dÌe=e         �dÍed)df�dÎ„�Z~�e�dÏœ�dye�dÍed)e>ee=e         f         f�dÐ„�Z€�dÑepf�dÒ„�Z��dÓe�dÑepd)ee         f�dÔ„�Z‚e��dÑepd)ee>ee�eƒf                  f�dÕ„¦   «         �Z„�dÖed)ef�d×„�Z…�dÓe�dÑepd)ee         f�dØ„�Z†�dÑepd)df�dÙ„�Z‡�d3dŒe
d)df�dÚ„�Zˆ�dÛepd)df�dÜ„�Z‰dä�ZŠ�dÝ�Z‹e>e�dÞ<   �dß�ZŒi �Z�epe>eedz  f         epee"f         f         e�dà<   �eŽd)epee"f         f�dá„¦   «         �Z��eŽd)epee"f         f�dâ„¦   «         �Z��eŽdnepdz  d)epf�dã„¦   «         �Z‘e�	 	 	 	 �d9dqe�däep�dåe­�dæe�dçepdz  �dpedz  �dèedz  �déed)ef�dê„¦   «         �Z’d,ed)df�dë„�Z“d,edqedrepd)e>f�dì„�Z”d,ed)epf�dí„�Z•d,e�dîepd)df�dï„�Z–d,e�dðed)ef�dñ„�Z—d�dòœd,e�dUee         d)ef�dó„�Z˜d,e�dUed)ef�dô„�Z™d,e�dUe�dõed)ef�dö„�Zšd,edied)df�d÷„�Z›d,ed)df�dø„�Zœd,ed)ef�dù„�Z�d_d©œd,edied)ef�dú„�Zžd,e�dûed)ef�dü„�ZŸdye"d,e�dûedz  d)df�dý„�Z �d�dþœd,ed\e�dÿe�d e�ded)df�d„�Z¡d,edtee         d)df�d„�Z¢d,e�de=e         d)df�d„�Z£d,ed)e=e         f�d„�Z¤d\ed,ed)ee         f�d„�Z¥�ded,ee         d)ef�d	„�Z¦e��ded)ef�d
„¦   «         �Z§d,ed)df�d„�Z¨e�due"�ded)df�d„¦   «         �Z©due"�ded)df�d„�Zªdue"�ded)df�d„�Z«due"d)df�d„�Z¬�d„ �Z­d)ef�d„�Z®d)e
f�d„�Z¯d)ef�d„�Z°�de=e>         d)df�d„�Z±�d,�d„�Z²d)ef�d„�Z³d)ee         f�d„�Z´d\�dƒ�de"dye"�ded)�df
�d„�Zµ	 	 	 �d7�dfe�de�dJe=eee"f                  d\�dƒdted,e�dUee         �d~ee         d)eee"f         f�d „�Z¶	 	 	 	 	 	 	 	 	 �d:�dfe�de�dJe=eee"f                  d\edted,e�dUee         �d!e�d~ee         �d"ee         �d#eep         �d$ee"         �d%ee
         �d&ee         d)eee"f         f�d'„�Z·d\ed)ee         f�d(„�Z¸d\ed)�d"f�d)„�Z¹	 	 	 	 	 	 	 	 	 �d:�dfe�de�dJe=eee"f                  d\edted,e�dUee         �d!e�d~ee         �d"ee         �d#eep         �d$ee"         �d%ee
         �d&ee         d)eee"f         f�d*„�ZºdS (;  r
  z�
    Main gateway controller.

    Manages the lifecycle of all platform adapters and routes
    messages to/from the agent.
    Ú	interruptÚ_busy_input_modeÚ_busy_text_modeÚ_restart_drain_timeoutÚ_restart_after_turn_timeoutNÚ
_exit_codeFÚ	_drainingÚ_external_drain_activeÚ_restart_requestedÚ_restart_task_startedÚ_restart_detachedÚ_restart_via_serviceÚ _detached_restart_helper_startedÚ_restart_command_sourceÚ
_stop_taskÚ_restart_taskÚ_profile_failed_platformsÚ_systemd_watchdogÚ_startup_restore_in_progressÚ_running_agentsÚ_running_agents_tsÚ_active_session_leasesÚ_busy_ack_tsÚ_session_run_generationr£  r¤  r¥  r¦  r¨  r©  r«  Ú_pending_messagesÚ&_pending_native_image_paths_by_sessionÚ_session_ephemeral_pinÚ_session_vc_lastÚ_pending_approvalsÚ_update_prompt_pendingr-   rj  c                 óV   — | j                              d¦  «        }|€i }|| j         d<   |S )z~The per-session state map; lazily created so bare test runners
        built via ``object.__new__`` work without ``__init__``.Ú	_sessions©Ú__dict__rv   )r  r“  s     r>   Ú_sessions_mapzGatewayRunner._sessions_map$  s5   € ð ”=×$Ò$ [Ñ1Ô1ˆØÐØˆHØ)1ˆDŒM˜+Ñ&ØˆrM   r+   c                 ó‚   — |                       ¦   «         }|                     |¦  «        }|€t          ¦   «         }|||<   |S )z<Get-or-create the :class:`SessionState` for ``session_key``.)rF  rv   rj  )r  r+   r“  r;   s       r>   r/   zGatewayRunner._session_state-  sA   € à×%Ò%Ñ'Ô'ˆØ—’˜[Ñ)Ô)ˆØˆ=Ý ‘N”NˆEØ$)ˆH�[Ñ!ØˆrM   c                 óh   — | j                              d¦  «        }|sdS |                     |¦  «        S )zAReturn the SessionState for ``session_key`` without creating one.rC  NrD  )r  r+   r“  s      r>   rA   z!GatewayRunner._peek_session_state6  s6   € à”=×$Ò$ [Ñ1Ô1ˆØð 	Ø�4Ø�|Š|˜KÑ(Ô(Ð(rM   c                 óP   — |                       |¦  «        }|duo|j        j        duS )zDTrue when the session holds a running-turn slot (agent or sentinel).N)rA   Úturnrµ   )r  r+   r;   s      r>   Ú_is_session_runningz!GatewayRunner._is_session_running=  s/   € à×(Ò(¨Ñ5Ô5ˆØ˜DÐ ÐA U¤ZÔ%5¸TÐ%AÐArM   c                 ób   — d„ |                       ¦   «                              ¦   «         D ¦   «         S )zž(session_key, agent) pairs for sessions with a running turn
        (including pending sentinels), matching the old ``_running_agents``
        dict contents.c                 óH   — g | ]\  }}|j         j        ®||j         j        f‘Œ S r^   )rJ  rµ   )rb   r  r;   s      r>   r  z6GatewayRunner._running_agent_items.<locals>.<listcomp>F  s;   € ð 
ð 
ð 
á��UØŒzÔÐ+ð �%”*Ô"Ð#à+Ð+Ð+rM   )rF  rñ  ©r  s    r>   Ú_running_agent_itemsz"GatewayRunner._running_agent_itemsB  s;   € ð
ð 
à"×0Ò0Ñ2Ô2×8Ò8Ñ:Ô:ð
ñ 
ô 
ð 	
rM   úasyncio.TaskÚ_loop_heartbeat_taskÚ_loop_floor_timer_handleÚ_loop_liveness_watchdogr@  Ú_gateway_started_atzthreading.EventÚ_shutdown_watchdog_doneÚ _platform_lock_takeover_on_startÚ_reconnect_watcher_taskrz   c                 óâ  ‡‡— |�|nt          ¦   «         | _        	 ddlm}  |t	          t          | j        dd¦  «        ¦  «        ¦  «         n,# t          $ r t                               dd¬¦  «         Y nw xY wi | _	        i | _
        |                      ¦   «          t          j        | ¦  «        a|                      ¦   «         | _        |                      ¦   «         | _        |                      ¦   «         | _        |                      ¦   «         | _        |                      ¦   «         | _        |                      ¦   «         | _        |                      ¦   «         | _        |                      ¦   «         | _        |                      ¦   «         | _         |  !                    ¦   «         | _"        |  #                    ¦   «         | _$        ddl%m&Š t          | j        j'        d	d
¦  «        }|r|dk    r|dz  nd ŠtQ          | j        j)        | j        ˆˆfd„¬¦  «        | _*        tW          | j*        ¦  «        | _,        t[          | j        ¦  «        | _.        d| _/        d | _0        tc          j2        ¦   «         | _3        d| _4        d| _5        d | _6        d | _7        d| _8        i | _9        d | _:        d| _;        d| _<        d| _=        d| _>        d| _?        d| _@        d| _A        d | _B        t‡          jC        ¦   «         | _D        d| _E        d | _F        d | _G        t‘          jI        ¦   «         | _J        d | _K        d| _L        i | _M        t�          ¦   «         | _O        i | _P        d| _Q        d| _R        g | _S        g | _T        t«          ¦   «         | _V        d| _W        t‘          jI        ¦   «         | _X        t³          ¦   «         | _Z        t«          ¦   «         | _[        d| _\        dd lH}t«          ¦   «         | _]        | I                    ¦   «         | _^        |  _                    ¦   «         | _`        d | _a        d | _b        i | _c        t³          ¦   «         | _d        dd le}| f                    d¦  «        | _g        	 ddlhmi}  |d¬¦  «         n# t          $ r Y nw xY w	 ddljmk}  |¦   «         }tÙ          tÛ          |ddd¬¦  «        pd¦  «         n                    ¦   «          o                    ¦   «         }	t	          tÛ          |ddd¬¦  «        ¦  «        }
tÛ          |ddd ¬¦  «        }|	dk    r|
s|st           p                    d¦  «         n,# t          $ r t                               dd¬¦  «         Y nw xY wd | _q        	 ddlrms}mt}  | |¦   «         ¦  «        | _q        n2# t          $ r%}t           p                    d|¦  «         Y d }~nd }~ww xY w| jq        ��š	 ddljmk}  |¦   «          u                    d ¦  «        pi }| u                    d!d¦  «        rc| jq        jv         w                    tñ          | u                    d"d#¦  «        ¦  «        tó          | u                    d$d
¦  «        ¦  «        ¬%¦  «         | u                    d&d¦  «        r²| jq        jv         z                    tó          | u                    d'd(¦  «        ¦  «        tó          | u                    d$d
¦  «        ¦  «        tó          | u                    d)d*¦  «        ¦  «        t	          | u                    d+d¦  «        ¦  «        | j        j)        ¬,¦  «         n2# t          $ r%}t                               d-|¦  «         Y d }~nd }~ww xY w	 ddljmk}  |¦   «          u                    d.¦  «        pi }| u                    d&d¦  «        rxdd/l{m|}  |tó          | u                    d'd0¦  «        ¦  «        tó          | u                    d$d
¦  «        ¦  «        dtó          | u                    d1d2¦  «        ¦  «        ¬3¦  «         n2# t          $ r%}t                               d4|¦  «         Y d }~nd }~ww xY wdd5l}m~}  |¦   «         | _        i | _€        dd6l�m‚}  |¦   «         | _ƒ        |  „                    ¦   «         | _…        i | _†        t³          ¦   «         | _‡        t‡          jC        ¦   «         | _ˆ        d | _‰        d | _Š        d | _‹        t‡          jC        ¦   «         | _Œ        d7| _�        d S )8Nr   )Úset_multiplex_activer½  Fz#could not set multiplex-active flagTrß   r*  Úbg_process_max_age_hoursr  rd  c                 ó2   •— ‰                      | ‰¬¦  «        S )N)Úmax_active_age)Úhas_active_for_session)r  Ú_bg_max_age_secondsr+  s    €€r>   rò   z(GatewayRunner.__init__.<locals>.<lambda>Œ  s$   ø€ Ð0@×0WÒ0WØÐ$7ð 1Xñ 1ô 1€ rM   )Úhas_active_processes_fné   i   r(   )Úensure_installed)Úlog_failures©Úload_configÚ	approvalsÚmodeÚmanualrx  r1  Útirith_enabledr  r  a6  Gateway approvals.mode=manual with no automated risk assessor (security.tirith_enabled is false and auxiliary.approval is unset): dangerous commands and execute_code scripts will BLOCK until a human approves them in chat. Enable security.tirith_enabled or configure auxiliary.approval for unattended operation.z$approvals.mode startup check skipped)ÚAsyncSessionDBÚ	SessionDBz&SQLite session store not available: %sr“  Úauto_archiveÚauto_archive_daysr)   Úmin_interval_hours©Ú	idle_daysrm  Ú
auto_pruneÚretention_dayséZ   Úmin_vacuum_interval_daysr  Úvacuum_after_prune)rq  rm  rs  ÚvacuumÚsessions_dirz%state.db auto-maintenance skipped: %srŠ  )Úmaybe_auto_prune_checkpointsé   rŒ  r¡  )rq  rm  Údelete_orphansrŒ  z'checkpoint auto-maintenance skipped: %s©ÚPairingStore)ÚHookRegistryr@  )Žr¿  rz   r…  rY  rº   rV   r2   r3   r4   r°  Ú_profile_adaptersÚ'_warn_if_docker_media_delivery_is_riskyÚ_weakrefÚrefrÕ  Ú_load_prefill_messagesr©  Ú_load_ephemeral_system_promptÚ_ephemeral_system_promptÚ_load_reasoning_configr�  Ú_load_service_tierr’  Ú_load_show_reasoningÚ_show_reasoningÚ_load_busy_input_moder%  Ú_load_busy_text_moder&  Ú_load_restart_drain_timeoutr'  Ú _load_restart_after_turn_timeoutr(  Ú_load_provider_routingrŽ  Ú_load_fallback_modelÚ_fallback_modelr-  r+  Údefault_reset_policyrZ  rv  r›  rX  Ú_async_session_storerc  Údelivery_routerÚ_runningÚ_gateway_loopr  r¹  Ú_shutdown_eventÚ_exit_cleanlyÚ_exit_with_failureÚ_exit_reasonr)  r*  r4  r5  r+  r,  Ú_signal_initiated_shutdownr-  r.  r/  r0  r1  rU   Ú_startup_timeÚ_booted_from_restartr2  r3  r¤  rº  Ú_executor_lockÚ	_executorÚ_executor_closingrC  rg  Ú_turn_leasesrª  r6  rV  Ú_startup_restore_queueÚ_startup_restore_tasksr   Ú_session_sourcesÚ_session_sources_maxÚ_completion_delivery_lockr•   Ú_completion_deliveries_inflightÚ _completion_deliveries_deliveredÚ_completion_delivery_retentionr  r  Ú_active_profile_nameÚ_kanban_notifier_profileÚ_teams_pipeline_runtimeÚ_teams_pipeline_runtime_errorÚ_failed_platformsÚ_fatal_handler_tasksÚ	itertoolsr  Ú_slash_confirm_counterÚtools.tirith_securityra  r˜  rd  rw   r!   rx   ry   rã   rR   Úhermes_stateri  rj  rv   rS   Úmaybe_auto_archiveri  rh  Úmaybe_auto_prune_and_vacuumÚtools.checkpoint_managerrw  Úgateway.pairingr{  Úpairing_storeÚpairing_storesÚgateway.hooksr|  ÚhooksÚ_load_voice_modesÚ_voice_modeÚ_recent_voice_transcriptsÚ_background_tasksrT  rQ  rR  rS  Ú_last_inbound_atÚ_scale_to_zero_cooldown_until)r  rz   rY  Ú_bg_max_age_hoursÚ
_threadingÚ
_itertoolsra  Ú_load_full_configÚ	_appr_cfgÚ
_appr_modeÚ
_tirith_onÚ_aux_approvalri  rj  r¨  Ú	_sess_cfgr<   Ú	_ckpt_cfgrw  r{  r|  r^  r+  s                        @@r>   r  zGatewayRunner.__init__V  sâ	  øø€ ð !'Ð 2�f�fÕ8VÑ8XÔ8XˆŒð
	OØ?Ð?Ð?Ð?Ð?Ð?Ø Ð ¥¥g¨d¬kÐ;OÐQVÑ&WÔ&WÑ!XÔ!XÑYÔYÐYÐYøÝð 	Oð 	Oð 	OÝ�LŠLÐ>ÈˆLÑNÔNÐNÐNÐNð	Oøøøà=?ˆŒð RTˆÔØ×4Ò4Ñ6Ô6Ð6Ý&œl¨4Ñ0Ô0Ðð "&×!<Ò!<Ñ!>Ô!>ˆÔØ(,×(JÒ(JÑ(LÔ(LˆÔ%Ø!%×!<Ò!<Ñ!>Ô!>ˆÔØ!×4Ò4Ñ6Ô6ˆÔØ#×8Ò8Ñ:Ô:ˆÔØ $× :Ò :Ñ <Ô <ˆÔØ#×8Ò8Ñ:Ô:ˆÔØ&*×&FÒ&FÑ&HÔ&HˆÔ#Ø+/×+PÒ+PÑ+RÔ+RˆÔ(Ø!%×!<Ò!<Ñ!>Ô!>ˆÔØ#×8Ò8Ñ:Ô:ˆÔð 	<Ð;Ð;Ð;Ð;Ð;Ý#ØŒKÔ,Ð.HÈ"ñ
ô 
Ðð ):Ð]Ð>OÐRSÒ>SÐ>SÐ Ñ$Ð$ÐY]ð 	õ *ØŒKÔ$ d¤kð%ð %ð %ð %ð %ð
ñ 
ô 
ˆÔõ %6°dÔ6HÑ$IÔ$IˆÔ!Ý-¨d¬kÑ:Ô:ˆÔØˆŒØBFˆÔÝ&œ}™œˆÔØ"ˆÔØ"'ˆÔØ+/ˆÔØ)-ˆŒØˆŒØRTˆÔ&Ø!%ˆÔð ',ˆÔ#Ø"'ˆÔð +0ˆÔ'Ø%*ˆÔ"Ø!&ˆÔØ$)ˆÔ!Ø05ˆÔ-Ø@DˆÔ$õ %)¤I¡K¤KˆÔð +0ˆÔ!Ø26ˆŒØ59ˆÔÝ'œnÑ.Ô.ˆÔØJNˆŒð "'ˆÔð
 35ˆŒõ 5Ñ6Ô6ˆÔðF 9;ˆÔ$ð
 -2ˆÔ)ð 16ˆÔ-Ø:<ˆÔ#Ø:<ˆÔ#õ DOÁ=Ä=ˆÔØ$'ˆÔ!õ *3¬Ñ)9Ô)9ˆÔ&ÝMPÉUÌUˆÔ,Ý^iÑ^kÔ^kˆÔ-Ø.2ˆÔ+ð 	'Ð&Ð&Ð&Ý7B±}´}ˆÔØ!+§¢Ñ!2Ô!2ˆÔð )-×(AÒ(AÑ(CÔ(CˆÔ%à'+ˆÔ$Ø<@ˆÔ*ð
 BDˆÔõ *-©¬ˆÔ!ð 	'Ð&Ð&Ð&Ø&0×&6Ò&6°qÑ&9Ô&9ˆÔ#ð	Ø>Ð>Ð>Ð>Ð>Ð>ØÐ¨%Ð0Ñ0Ô0Ð0Ð0øÝð 	ð 	ð 	ØˆDð	øøøð	PØJÐJÐJÐJÐJÐJØ)Ð)Ñ+Ô+ˆIÝÝ˜	 ;°ÀÐIÑIÔIÐUÈXñô çŠe‰gŒg—e’e‘g”gð õ �g i°Ð=MÐW[Ð\Ñ\Ô\Ñ]Ô]ˆJÝ# I¨{¸JÐPTÐUÑUÔUˆMØ˜XÒ%Ð%¨jÐ%ÀÐ%Ý—’ðCñô ð øøõ ð 	Pð 	Pð 	PÝ�LŠLÐ?È$ˆLÑOÔOÐOÐOÐOð	Pøøøð  ˆÔð
	HØ>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ø-˜~¨i¨i©k¬kÑ:Ô:ˆDÔÐøÝð 	Hð 	Hð 	Hõ �NŠNÐCÀQÑGÔGÐGÐGÐGÐGÐGÐGøøøøð	Høøøð ÔÑ'ðKØNÐNÐNÐNÐNÐNØ.Ð.Ñ0Ô0×4Ò4°ZÑ@Ô@ÐFÀB�	à—=’= °Ñ7Ô7ð ØÔ$Ô(×;Ò;Ý"'¨	¯ªÐ6IÈ1Ñ(MÔ(MÑ"NÔ"NÝ+.¨y¯}ª}Ð=QÐSUÑ/VÔ/VÑ+WÔ+Wð <ñ ô ð ð —=’= ¨uÑ5Ô5ð 
àÔ$Ô(×DÒDÝ'*¨9¯=ª=Ð9IÈ2Ñ+NÔ+NÑ'OÔ'OÝ+.¨y¯}ª}Ð=QÐSUÑ/VÔ/VÑ+WÔ+WÝ14Ø%ŸMšMÐ*DÀbÑIÔIñ2ô 2õ  $ I§M¢MÐ2FÈÑ$MÔ$MÑNÔNØ%)¤[Ô%=ð Eñ ô ð øøõ ð Kð Kð KÝ—’ÐDÀcÑJÔJÐJÐJÐJÐJÐJÐJøøøøðKøøøð	IØJÐJÐJÐJÐJÐJØ*Ð*Ñ,Ô,×0Ò0°Ñ?Ô?ÐEÀ2ˆIØ�}Š}˜\¨5Ñ1Ô1ð ØQÐQÐQÐQÐQÐQð -Ð,Ý#& y§}¢}Ð5EÀqÑ'IÔ'IÑ#JÔ#JÝ'*¨9¯=ª=Ð9MÈrÑ+RÔ+RÑ'SÔ'SØ#(Ý&)¨)¯-ª-Ð8KÈSÑ*QÔ*QÑ&RÔ&Rð	ñ ô ð øøõ ð 	Ið 	Ið 	IÝ�LŠLÐBÀCÑHÔHÐHÐHÐHÐHÐHÐHøøøøð	Iøøøð 	1Ð0Ð0Ð0Ð0Ð0Ø)˜\™^œ^ˆÔØ9;ˆÔð 	/Ð.Ð.Ð.Ð.Ð.Ø!�\‘^”^ˆŒ
ð ,0×+AÒ+AÑ+CÔ+CˆÔð Z\ˆÔ&õ '*¡e¤eˆÔõ
 +/¬)©+¬+ˆÔ Ø<@ˆÔ!Ø(,ˆÔ%Ø'+ˆÔ$õ (,¤y¡{¤{ˆÔð 58ˆÔ*Ð*Ð*s€   ›2A Á&A7Á6A7ÑQ0 Ñ0
Q=Ñ<Q=ÒB-T/ Ô/&UÕUÕ# V Ö
V3ÖV.Ö.V3Ö?E&\& Ü&
]Ü0]Ý]ÝB3` à
`<à`7à7`<c                 ó  — t           j        | j        vrdS t          ¦   «         st                               d¦  «         dS 	 ddlm} n3# t          $ r&}t           	                    d|¦  «         Y d}~dS d}~ww xY w	  || ¦  «        }n3# t          $ r&}t           	                    d|¦  «         Y d}~dS d}~ww xY w|rt           
                    d¦  «         dS | j        r"t           	                    d| j        ¦  «         dS dS )	u  Bind the Teams meeting pipeline runtime to Graph webhook ingress.

        No-op when the msgraph_webhook adapter isn't running or the
        teams_pipeline plugin isn't enabled â€” lets the gateway start cleanly
        whether or not the user has opted into the pipeline.
        Nz:Teams pipeline plugin is disabled; skipping runtime wiringr   )Úbind_gateway_runtimez(Teams pipeline runtime import failed: %sz(Teams pipeline runtime wiring failed: %sz7Teams pipeline runtime bound to msgraph webhook ingressz&Teams pipeline runtime unavailable: %s)rÄ  ÚMSGRAPH_WEBHOOKr°  rz  r3   r4   Úplugins.teams_pipeline.runtimerÊ  r2   rã   rz  rª  )r  rÊ  r<   Úbounds       r>   Ú_wire_teams_pipeline_runtimez*GatewayRunner._wire_teams_pipeline_runtime×  sS  € õ Ô#¨4¬=Ð8Ð8ØˆFÝ-Ñ/Ô/ð 	Ý�LŠLÐUÑVÔVÐVØˆFð	ØKÐKÐKÐKÐKÐKÐKøÝð 	ð 	ð 	Ý�NŠNÐEÀsÑKÔKÐKØˆFˆFˆFˆFˆFøøøøð	øøøð	Ø(Ð(¨Ñ.Ô.ˆEˆEøÝð 	ð 	ð 	Ý�NŠNÐEÀsÑKÔKÐKØˆFˆFˆFˆFˆFøøøøð	øøøð ð 	Ý�KŠKÐQÑRÔRÐRÐRÐRØÔ/ð 	Ý�NŠNØ8ØÔ2ñô ð ð ð ð	ð 	s0   ÁA Á
A8ÁA3Á3A8Á<B Â
B8ÂB3Â3B8c                 óº  — t          j        dd¦  «                             ¦   «                              ¦   «         dk    rdS | j                             ¦   «         }d„ |D ¦   «         }|sdS t          j        dd¦  «                             ¦   «         }g }|rc	 t          j        |¦  «        }t          |t          ¦  «        rd„ |D ¦   «         }n,# t          $ r t                               dd	¬
¦  «         Y nw xY wd}|D ]A}t                               |¦  «        }|sŒ|                     d¦  «        }	|	t           v rd	} nŒB|rdS t                               d¦  «         dS )a�  Warn when Docker-backed gateways lack an explicit export mount.

        MEDIA delivery happens in the gateway process, so paths emitted by the model
        must be readable from the host. A plain container-local path like
        `/workspace/report.txt` or `/output/report.txt` often exists only inside
        Docker, so users commonly need a dedicated export mount such as
        `host-dir:/output`.
        rÎ  r®   ÚdockerNc                 ó\   — g | ])}|t           j        t           j        t           j        hv¯'|‘Œ*S rN  )rÄ  rt  Ú
API_SERVERÚWEBHOOKr:  s     r>   r  zIGatewayRunner._warn_if_docker_media_delivery_is_risky.<locals>.<listcomp>  s3   € ÐxÐxÐx Q°qÅÄÕQYÔQdÕfnÔfvÐ@wÐ7wÐ7w˜qÐ7wÐ7wÐ7wrM   rò  c                 óV   — g | ]&}t          |t          ¦  «        ¯t          |¦  «        ‘Œ'S rN  r~  ©rb   ré  s     r>   r  zIGatewayRunner._warn_if_docker_media_delivery_is_risky.<locals>.<listcomp>  s-   € ÐLÐLÐL¨!½ÀAÅsÑ9KÔ9KÐL�s 1™vœvÐLÐLÐLrM   zACould not parse TERMINAL_DOCKER_VOLUMES for gateway media warningTrß   FÚ	containeraF  Docker backend is enabled for the messaging gateway but no explicit host-visible output mount (for example '/home/user/.hermes/cache/documents:/output') is configured. This is fine if the model already emits host-visible paths, but MEDIA file delivery can fail for container-local paths like '/workspace/...' or '/output/...'.)r’   rÆ  rx   ry   rz   Úget_connected_platformsr3  r4  rt   r½  r2   r3   r4   Ú_DOCKER_VOLUME_SPEC_REr[  rð   Ú$_DOCKER_MEDIA_OUTPUT_CONTAINER_PATHSrã   )
r  Ú	connectedÚmessaging_platformsÚraw_volumesÚvolumesÚparsedÚhas_explicit_output_mountÚspecr[  Úcontainer_paths
             r>   r~  z5GatewayRunner._warn_if_docker_media_delivery_is_riskyö  s©  € õ Œ9�^ RÑ(Ô(×.Ò.Ñ0Ô0×6Ò6Ñ8Ô8¸HÒDÐDØˆFà”K×7Ò7Ñ9Ô9ˆ	ØxÐx¨)ÐxÑxÔxÐØ"ð 	ØˆFå”iÐ 9¸2Ñ>Ô>×DÒDÑFÔFˆØˆØð 	qðqÝœ KÑ0Ô0�Ý˜f¥dÑ+Ô+ð MØLÐL¨vÐLÑLÔL�GøøÝð qð qð qÝ—’Ð`Ðko�ÑpÔpÐpÐpÐpðqøøøð %*Ð!Øð 	ð 	ˆDÝ*×0Ò0°Ñ6Ô6ˆEØð ØØ"Ÿ[š[¨Ñ5Ô5ˆNØÕ!EÐEÐEØ,0Ð)Ø�ð Fð %ð 	ØˆFå�ŠðPñ	
ô 	
ð 	
ð 	
ð 	
s   Â5C Ã&C4Ã3C4c                 óL   — 	 ddl m}  |d¦  «        duS # t          $ r Y dS w xY w)z3Check if the hermes-agent-setup skill is installed.r   )Ú_find_skillzhermes-agent-setupNF)Útools.skill_manager_toolrã  r2   )r  rã  s     r>   Ú_has_setup_skillzGatewayRunner._has_setup_skill)  sQ   € ð	Ø<Ð<Ð<Ð<Ð<Ð<Ø�;Ð3Ñ4Ô4¸DÐ@Ð@øÝð 	ð 	ð 	Ø�5�5ð	øøøs   ‚ •
#¢#zgateway_voice_mode.jsonr�   r2  c                 ó   — |j         › d|› �S )z6Return a platform-namespaced key for voice mode state.rÉ  ©r­   )r  r�   r2  s      r>   Ú
_voice_keyzGatewayRunner._voice_key5  s   € à”.Ð,Ð, 7Ð,Ð,Ð,rM   c                 óŒ  — 	 t          j        | j                             d¬¦  «        ¦  «        }n$# t          t           j        t          f$ r i cY S w xY wt          |t          ¦  «        si S h d£}i }| 	                    ¦   «         D ]>\  }}||vrŒ
t          |¦  «        }d|vrt                               d|¦  «         Œ9|||<   Œ?|S )NrQ  r‚  >   r�  r  Ú
voice_onlyrÉ  z}Skipping legacy unprefixed voice mode key %r during migration. Re-enable voice mode on that chat to rebuild the prefixed key.)r3  r4  Ú_VOICE_MODE_PATHrX  ÚFileNotFoundErrorÚJSONDecodeErrorr–   rt   ru   rñ  rw   r3   rã   )r  ÚdataÚvalid_modesr·  r2  rf  r  s          r>   r¹  zGatewayRunner._load_voice_modes9  sô   € ð	Ý”:˜dÔ3×=Ò=ÀwÐ=ÑOÔOÑPÔPˆDˆDøÝ!¥4Ô#7½ÐAð 	ð 	ð 	ØˆIˆIˆIð	øøøõ ˜$¥Ñ%Ô%ð 	ØˆIà2Ð2Ð2ˆØˆØ!ŸZšZ™\œ\ð 	ð 	‰MˆG�TØ˜;Ð&Ð&ØÝ�g‘,”,ˆCà˜#ˆ~ˆ~Ý—’ðUàñô ð ð
 ØˆF�3‰KˆKØˆs   ‚-0 °AÁAc                 ó  — 	 | j         j                             dd¬¦  «         | j                              t	          j        | j        d¬¦  «        d¬¦  «         d S # t          $ r&}t           	                    d|¦  «         Y d }~d S d }~ww xY w)NT©r‡  Úexist_okr|  ©ÚindentrQ  r‚  zFailed to save voice modes: %s)
rë  r‘   ÚmkdirÚ
write_textr3  rB  rº  r–   r3   rã   )r  r¨  s     r>   Ú_save_voice_modeszGatewayRunner._save_voice_modesS  s´   € ð	@ØÔ!Ô(×.Ò.°tÀdÐ.ÑKÔKÐKØÔ!×,Ò,Ý”
˜4Ô+°AÐ6Ñ6Ô6Àð -ñ ô ð ð ð øõ ð 	@ð 	@ð 	@Ý�NŠNÐ;¸QÑ?Ô?Ð?Ð?Ð?Ð?Ð?Ð?Ð?øøøøð	@øøøs   ‚AA Á
B
Á$BÂB
rj  c                 ó,  — t          |dd¦  «        }t          |t          ¦  «        sdS |rT|                     |¦  «         t          |dd¦  «        }t          |t          ¦  «        r|                     |¦  «         dS dS |                     |¦  «         dS )zBUpdate an adapter's in-memory auto-TTS suppression set if present.Ú_auto_tts_disabled_chatsNÚ_auto_tts_enabled_chats©rV   rt   r•   r—   Údiscard)r  r1  r2  rj  Údisabled_chatsÚenabled_chatss         r>   Ú_set_adapter_auto_tts_disabledz,GatewayRunner._set_adapter_auto_tts_disabled\  s«   € å  Ð*DÀdÑKÔKˆÝ˜.­#Ñ.Ô.ð 	ØˆFØð 	,Ø×Ò˜wÑ'Ô'Ð'å# GÐ-FÈÑMÔMˆMÝ˜-­Ñ-Ô-ð /Ø×%Ò% gÑ.Ô.Ð.Ð.Ð.ð/ð /ð ×"Ò" 7Ñ+Ô+Ð+Ð+Ð+rM   rÓ  c                 ó,  — t          |dd¦  «        }t          |t          ¦  «        sdS |rT|                     |¦  «         t          |dd¦  «        }t          |t          ¦  «        r|                     |¦  «         dS dS |                     |¦  «         dS )zÕUpdate an adapter's per-chat auto-TTS opt-in set if present.

        Used for ``/voice on``/``/voice tts`` where the user explicitly wants
        auto-TTS even when ``voice.auto_tts`` is False globally.
        rú  Nrù  rû  )r  r1  r2  rÓ  rþ  rý  s         r>   Ú_set_adapter_auto_tts_enabledz+GatewayRunner._set_adapter_auto_tts_enabledj  s­   € õ   Ð)BÀDÑIÔIˆÝ˜-­Ñ-Ô-ð 	ØˆFØð 	+Ø×Ò˜gÑ&Ô&Ð&å$ WÐ.HÈ$ÑOÔOˆNÝ˜.­#Ñ.Ô.ð 0Ø×&Ò& wÑ/Ô/Ð/Ð/Ð/ð0ð 0ð ×!Ò! 'Ñ*Ô*Ð*Ð*Ð*rM   c                 óv  ‡— t          |dd¦  «        }t          |t          ¦  «        sdS t          |dd¦  «        }t          |dd¦  «        }t          |t          ¦  «        st          |t          ¦  «        sdS 	 ddlm}  |¦   «         }t          |                     d¦  «        pi                      dd	¦  «        ¦  «        }n# t          $ r d	}Y nw xY wt          |d
¦  «        r||_
        |j        › d�Št          |t          ¦  «        rL|                     ¦   «          |                     ˆfd„| j                             ¦   «         D ¦   «         ¦  «         t          |t          ¦  «        rN|                     ¦   «          |                     ˆfd„| j                             ¦   «         D ¦   «         ¦  «         dS dS )ae  Restore persisted /voice state into a live platform adapter.

        Populates three fields from config + ``self._voice_mode``:
          - ``_auto_tts_default``: global default from ``voice.auto_tts``
          - ``_auto_tts_enabled_chats``: chats with mode ``voice_only``/``all``
          - ``_auto_tts_disabled_chats``: chats with mode ``off``
        r�   Nrù  rú  r   rc  ÚvoiceÚauto_ttsFÚ_auto_tts_defaultrÉ  c              3   ó‚   •K  — | ]9\  }}|d k    ¯|                      ‰¦  «        ¯ |t          ‰¦  «        d…         V — Œ:dS )r  N©r!  r7   ©rb   r  rf  r  s      €r>   rd   zBGatewayRunner._sync_voice_mode_state_to_adapter.<locals>.<genexpr>�  sX   øè è € ð "ð "Ù&/ c¨4Ø˜5’=�= S§^¢^°FÑ%;Ô%;�=ð •C˜‘K”K�L�LÔ!Ø �=�=�=ð"ð "rM   c              3   ó~   •K  — | ]7\  }}|d v ¯	|                      ‰¦  «        ¯|t          ‰¦  «        d…         V — Œ8dS )>   r�  rê  Nr  r  s      €r>   rd   zBGatewayRunner._sync_voice_mode_state_to_adapter.<locals>.<genexpr>£  s_   øè è € ð !ð !Ù&/ c¨4ØÐ0Ð0Ð0°S·^²^ÀFÑ5KÔ5KÐ0ð •C˜‘K”K�L�LÔ!Ø0Ð0Ð0Ð0ð!ð !rM   )rV   rt   rÄ  r•   r˜  rd  rº   rv   r2   rá   r  r­   r4  rI  rº  rñ  )	r  r1  r�   rý  rþ  rÂ  Ú	_full_cfgr  r  s	           @r>   Ú!_sync_voice_mode_state_to_adapterz/GatewayRunner._sync_voice_mode_state_to_adapter|  s"  ø€ õ ˜7 J°Ñ5Ô5ˆÝ˜(¥HÑ-Ô-ð 	ØˆFå  Ð*DÀdÑKÔKˆÝ Ð)BÀDÑIÔIˆÝ˜.­#Ñ.Ô.ð 	µzÀ-ÕQTÑ7UÔ7Uð 	ØˆFð	&ØJÐJÐJÐJÐJÐJØ)Ð)Ñ+Ô+ˆIÝ $Ø—’˜wÑ'Ô'Ð-¨2×2Ò2°:¸uÑEÔEñ!ô !ÐÐøõ ð 	&ð 	&ð 	&Ø %ÐÐÐð	&øøøå�7Ð/Ñ0Ô0ð 	:Ø(9ˆGÔ%à”NÐ%Ð%Ð%ˆÝ�n¥cÑ*Ô*ð 	Ø× Ò Ñ"Ô"Ð"Ø×!Ò!ð "ð "ð "ð "Ø37Ô3C×3IÒ3IÑ3KÔ3Kð"ñ "ô "ñ ô ð õ �m¥SÑ)Ô)ð 	Ø×ÒÑ!Ô!Ð!Ø× Ò ð !ð !ð !ð !Ø37Ô3C×3IÒ3IÑ3KÔ3Kð!ñ !ô !ñ ô ð ð ð ð	ð 	s   Á9AC ÃCÃCÚ	awaitablerÓ  c              ƒ   ó’  K  — |dk    r
|ƒ d{V —† dS t          j        |¦  «        }	 t          j        |h|¬¦  «        ƒ d{V —†\  }}nB# t           j        $ r0 |                     ¦   «          |                     t          ¦  «         ‚ w xY w||v r
|ƒ d{V —† dS |                     ¦   «          |                     t          ¦  «         dS )a~  Wait for adapter cleanup without letting cancellation swallowing hang us.

        ``asyncio.wait_for`` cancels an overdue child but then waits for it to
        exit. An adapter close path that catches ``CancelledError`` can therefore
        block recovery forever. Keep ownership of the old task through its done
        callback, but release the runner at the deadline.
        r   NTr  F)r  Úensure_futurerB  r›  Úcancelrä  r   )r  r  rÓ  rÝ   ÚdoneÚ_pendings         r>   Ú#_await_adapter_cleanup_with_timeoutz1GatewayRunner._await_adapter_cleanup_with_timeout¨  sõ   è è € ð �aŠ<ˆ<ØˆOˆOˆOˆOˆOˆOˆOØ�4åÔ$ YÑ/Ô/ˆð	Ý#*¤<°°ÀÐ#HÑ#HÔ#HÐHÐHÐHÐHÐHÐH‰NˆD�(�(øÝÔ%ð 	ð 	ð 	Ø�KŠK‰MŒMˆMØ×"Ò"Õ#?Ñ@Ô@Ð@Øð	øøøð �4ˆ<ˆ<ØˆJˆJˆJˆJˆJˆJˆJØ�4à�Š‰ŒˆØ×ÒÕ;Ñ<Ô<Ð<Øˆus   ¨ A	 Á	?Bc              ƒ   ó\  K  — |                       ¦   «         }	 |                      |                     ¦   «         |¦  «        ƒ d{V —†}|s't                               d||�|j        nd¦  «         dS dS # t          $ r0}t                               d|�|j        nd|¦  «         Y d}~dS d}~ww xY w)uÓ  Call adapter.disconnect() defensively, swallowing any error.

        Used when adapter.connect() failed or raised â€” the adapter may
        have allocated partial resources (aiohttp.ClientSession, poll
        tasks, child subprocesses) that would otherwise leak and surface
        as "Unclosed client session" warnings at process exit.

        Must tolerate partial-init state and never raise, since callers
        use it inside error-handling blocks.
        NzITimed out after %.1fs while disconnecting %s adapter; continuing shutdownr1  z7Defensive %s disconnect after failed connect raised: %s)Ú _adapter_disconnect_timeout_secsr  rÿ  r3   rã   r­   r2   r4   )r  r1  r�   rÓ  rõ  r¨  s         r>   Ú_safe_adapter_disconnectz&GatewayRunner._safe_adapter_disconnectÅ  s  è è € ð ×7Ò7Ñ9Ô9ˆð	Ø"×FÒFØ×"Ò"Ñ$Ô$ gñô ð ð ð ð ð ð ˆIð ð Ý—’Ø_ØØ&.Ð&:�H”N�NÀ	ñô ð ð ð ðð øõ ð 	ð 	ð 	Ý�LŠLØIØ"*Ð"6�”�¸IØñô ð ð ð ð ð ð ð øøøøð	øøøs   ˜AA1 Á1
B+Á;%B&Â&B+©Úprofiler  c             ƒ   ó:  K  — |                       ¦   «         }|rd|› d�nd}t          j        ¦   «         }	 |                      |                     ¦   «         |¦  «        ƒ d{V —†}|s"t
                               d|j        ||¦  «         n9# t          $ r,}t
           	                    d|j        ||¦  «         Y d}~nd}~ww xY w	 |                      | 
                    ¦   «         |¦  «        ƒ d{V —†}	|	r8t
                               d|j        t          j        ¦   «         |z
  |¦  «         dS t
                               d|j        ||¦  «         dS # t          $ rB}t
                               d	|j        t          j        ¦   «         |z
  ||¦  «         Y d}~dS d}~ww xY w)
a>  Tear down one adapter on the shutdown path with bounded awaits.

        Both ``cancel_background_tasks()`` and ``disconnect()`` can block
        indefinitely when a platform's network state is half-dead (e.g. a
        wedged Feishu/Lark WebSocket thread waiting on I/O). An unbounded
        await here stalls the entire shutdown sequence past systemd's
        ``TimeoutStopSec``; the resulting SIGKILL skips ``atexit`` PID-file
        cleanup, so the next start dies with "PID file race lost" (#14128).

        Each await uses the existing per-adapter timeout budget
        (``HERMES_GATEWAY_ADAPTER_DISCONNECT_TIMEOUT``). On timeout the old
        task is cancelled and detached, then teardown forces forward progress;
        the loop never hangs even if an adapter swallows cancellation. Never
        raises.
        z (profile: rŠ  r®   NuH   âœ— %s background-task cancel timed out after %.1fs - forcing continue%su)   âœ— %s background-task cancel error%s: %su   âœ“ %s disconnected (%.2fs)%su<   âœ— %s disconnect timed out after %.1fs - forcing continue%su)   âœ— %s disconnect error after %.2fs%s: %s)r  rU   r—  r  Úcancel_background_tasksr3   rã   r­   r2   r4   rÿ  rz  rP   )
r  r1  r�   r  rÓ  ÚsuffixÚ
started_atÚ	cancelledr¨  Údisconnecteds
             r>   Ú_bounded_adapter_teardownz'GatewayRunner._bounded_adapter_teardownâ  s3  è è € ð$ ×7Ò7Ñ9Ô9ˆØ-4Ð<Ð)˜wÐ)Ð)Ð)Ð)¸"ˆÝ”^Ñ%Ô%ˆ
ð
	aØ"×FÒFØ×/Ò/Ñ1Ô1°7ñô ð ð ð ð ð ð ˆIð ð Ý—’Ø^Ø”N G¨Vñô ð øøõ ð 	að 	að 	aÝ�LŠLÐDÀhÄnÐV\Ð^_Ñ`Ô`Ð`Ð`Ð`Ð`Ð`Ð`øøøøð	aøøøð	Ø!%×!IÒ!IØ×"Ò"Ñ$Ô$ gñ"ô "ð ð ð ð ð ð ˆLð ð 	Ý—’Ø3Ø”N¥D¤NÑ$4Ô$4°zÑ$AÀ6ñô ð ð ð õ
 —’ØRØ”N G¨Vñô ð ð ð øõ ð 	ð 	ð 	Ý�LŠLØ;Ø”¥¤Ñ 0Ô 0°:Ñ =¸vÀqñô ð ð ð ð ð ð ð øøøøð	øøøs7   µAB Â
B>Â"B9Â9B>ÃA&E Ä*"E Å
FÅ7FÆFc                 óø   — t          j        dd¦  «                             ¦   «         }|rK	 t          |¦  «        }t	          d|¦  «        S # t
          $ r t                               d|¦  «         Y nw xY wt          S )z?Return the per-adapter disconnect timeout used during shutdown.Ú)HERMES_GATEWAY_ADAPTER_DISCONNECT_TIMEOUTr®   r@  z=Ignoring invalid HERMES_GATEWAY_ADAPTER_DISCONNECT_TIMEOUT=%r)	r’   rÆ  rx   ri  rC  rj  r3   rã   Ú(_ADAPTER_DISCONNECT_TIMEOUT_SECS_DEFAULT)r  rx  rÓ  s      r>   r  z.GatewayRunner._adapter_disconnect_timeout_secs  s•   € åŒiÐCÀRÑHÔH×NÒNÑPÔPˆØð 		)ð)Ý ™*œ*�õ ˜3 Ñ(Ô(Ð(øõ ð ð ð Ý—’ØSØñô ð ð ð ðøøøõ 8Ð7ó   «A
 Á
%A2Á1A2c                 ó&  — t          j        dd¦  «                             ¦   «         }|rK	 t          |¦  «        }t	          d|¦  «        S # t
          $ r t                               d|¦  «         Y nw xY w|t          j	        k    rt          S t          S )zBReturn the per-platform connect timeout used during startup/retry.rB  r®   r@  z;Ignoring invalid HERMES_GATEWAY_PLATFORM_CONNECT_TIMEOUT=%r)r’   rÆ  rx   ri  rC  rj  r3   rã   rÄ  rÍ  Ú&_TELEGRAM_CONNECT_TIMEOUT_SECS_DEFAULTÚ&_PLATFORM_CONNECT_TIMEOUT_SECS_DEFAULT)r  r�   rx  rÓ  s       r>   Ú_platform_connect_timeout_secsz,GatewayRunner._platform_connect_timeout_secs%  s©   € åŒiÐAÀ2ÑFÔF×LÒLÑNÔNˆØð 		)ð)Ý ™*œ*�õ ˜3 Ñ(Ô(Ð(øõ ð ð ð Ý—’ØQØñô ð ð ð ðøøøð •xÔ(Ò(Ð(Ý9Ð9Ý5Ð5r"  ©Úis_reconnectr(  c             ƒ   óT  K  — |                       |¦  «        }|dk    r|                     |¬¦  «        ƒ d{V —†S t          j        |                     |¬¦  «        ¦  «        }	 t          j        |h|¬¦  «        ƒ d{V —†\  }}nB# t          j        $ r0 |                     ¦   «          |                     t          ¦  «         ‚ w xY w||v r|ƒ d{V —†}t          |¦  «        S |                     ¦   «          |                     t          ¦  «         t          |j        › d|d›d�¦  «        ‚)u¥  Connect an adapter without allowing one platform to block others.

        ``is_reconnect`` is forwarded to ``adapter.connect()`` so platform
        adapters can distinguish a cold first boot (drop any stale
        server-side queue) from a watcher reconnect after a prolonged outage
        (preserve the queue so messages sent during the outage are delivered
        rather than silently dropped â€” #46621).
        r   r'  Nr  z connect timed out after Úgr¾  )r&  Úconnectr  r  rB  r›  r  rä  r   rº   ÚTimeoutErrorr­   )	r  r1  r�   r(  rÓ  rÝ   r  r  r·  s	            r>   Ú_connect_adapter_with_timeoutz+GatewayRunner._connect_adapter_with_timeout6  sZ  è è € ð ×5Ò5°hÑ?Ô?ˆØ�aŠ<ˆ<Ø Ÿš°l˜ÑCÔCÐCÐCÐCÐCÐCÐCÐCõ Ô$Ø�OŠO¨ˆOÑ6Ô6ñ
ô 
ˆð	Ý#*¤<°°ÀÐ#HÑ#HÔ#HÐHÐHÐHÐHÐHÐH‰NˆD�(�(øÝÔ%ð 	ð 	ð 	Ø�KŠK‰MŒMˆMØ×"Ò"Õ#?Ñ@Ô@Ð@Øð	øøøð �4ˆ<ˆ<Ø�Z�Z�Z�Z�Z�ZˆFÝ˜‘<”<ÐØ�Š‰ŒˆØ×ÒÕ;Ñ<Ô<Ð<ÝØŒ~ÐDÐD¸ÐDÐDÐDÐDñ
ô 
ð 	
s   Á# B Â?Cc              ƒ   óš   K  — t          | j        ¦  «        |_        	 |                      ||¦  «        ƒ d{V —†	 d|_        S # d|_        w xY w)aT  Connect one cold-start adapter with tightly scoped replace intent.

        The capability is visible only while this initial connect is awaited.
        Reconnects call ``_connect_adapter_with_timeout`` directly and adapters
        also default to deny, so a later network recovery can never evict a
        healthy token holder.
        NF)rº   rV  Ú_platform_lock_takeover_allowedr-  )r  r1  r�   s      r>   Ú%_connect_initial_adapter_with_timeoutz3GatewayRunner._connect_initial_adapter_with_timeout\  sl   è è € õ 37ØÔ1ñ3
ô 3
ˆÔ/ð	<Ø×;Ò;¸GÀXÑNÔNÐNÐNÐNÐNÐNÐNÐNà6;ˆGÔ3Ð3ø°eˆGÔ3Ð;Ð;Ð;Ð;s   �A Á	A
c                 ó   — | j         S r^   )r•  rN  s    r>   Úshould_exit_cleanlyz!GatewayRunner.should_exit_cleanlyl  s   € àÔ!Ð!rM   c                 ó   — | j         S r^   )r–  rN  s    r>   Úshould_exit_with_failurez&GatewayRunner.should_exit_with_failurep  s   € àÔ&Ð&rM   c                 ó   — | j         S r^   )r—  rN  s    r>   Úexit_reasonzGatewayRunner.exit_reasont  s   € àÔ Ð rM   c                 ó   — | j         S r^   )r)  rN  s    r>   Ú	exit_codezGatewayRunner.exit_codex  s
   € àŒÐrM   r(  c           	      óÎ  — t          | d¦  «        rL| j        �E	 | j                             |¦  «        }t          |t          ¦  «        r|r|S n# t
          $ r Y nw xY wt          | dd¦  «        }d}t          |dd¦  «        r5|j        r|j        }n&	 ddlm	}  |¦   «         pd}n# t
          $ r d}Y nw xY wt          |t          |d	d
¦  «        t          |dd¦  «        |¬¦  «        S )zUResolve the current session key for a source, honoring gateway config when available.r›  Nrz   r½  Fr   ©Úget_active_profile_namerJ  Úgroup_sessions_per_userTÚthread_sessions_per_user)r<  r=  r  )rá   r›  Ú_generate_session_keyrt   rw   r2   rV   r  Úhermes_cli.profilesr;  r`  )r  r(  r+   rz   Ú_profiler;  s         r>   Ú_session_key_for_sourcez%GatewayRunner._session_key_for_source|  sE  € å�4˜Ñ)Ô)ð 	¨dÔ.@Ð.LðØ"Ô0×FÒFÀvÑNÔN�Ý˜k­3Ñ/Ô/ð '°Kð 'Ø&Ð&øøÝð ð ð Ø�ðøøøå˜˜x¨Ñ.Ô.ˆð ˆÝ�6Ð/°Ñ7Ô7ð 	$ØŒ~ð $Ø!œ>��ð$ØKÐKÐKÐKÐKÐKØ6Ð6Ñ8Ô8ÐE¸I�H�HøÝ ð $ð $ð $Ø#�H�H�Hð$øøøå ØÝ$+¨FÐ4MÈtÑ$TÔ$TÝ%,¨VÐ5OÐQVÑ%WÔ%WØð	
ñ 
ô 
ð 	
s#   ™2A Á
AÁAÂB$ Â$B3Â2B3c                 ón  — |j         t          j        k    s|j        dk    rdS t	          | dd¦  «        }|€dS t	          |d|¦  «        }	 |                     t          |j        ¦  «        t          |j        ¦  «        ¬¦  «        }n-# t          $ r  t                               dd¬	¦  «         Y dS w xY w|du S )
z>Return whether Telegram DM topic mode is active for this chat.rµ  FrR   NrS   ©r2  r¹  z(Failed to read Telegram topic mode stateTrß   )r�   rÄ  rÍ  r´  rV   Úis_telegram_topic_mode_enabledrw   r2  r¹  r2   r3   r4   )r  r(  rX   rx  s       r>   Ú_telegram_topic_mode_enabledz*GatewayRunner._telegram_topic_mode_enabledš  sÓ   € àŒ?�hÔ/Ò/Ð/°6Ô3CÀtÒ3KÐ3KØ�5Ý˜T =°$Ñ7Ô7ˆ
ØÐØ�5å˜Z¨°
Ñ;Ô;ˆ
ð	Ø×;Ò;Ý˜FœNÑ+Ô+Ý˜FœNÑ+Ô+ð <ñ ô ˆCˆCøõ ð 	ð 	ð 	Ý�LŠLÐCÈdˆLÑSÔSÐSØ�5�5ð	øøøð �dˆ{Ðs   Á
;B Â&B0Â/B0r®   ro   c                 ó²   — |j         t          j        k    s|j        dk    rdS |                      |¦  «        sdS t          |j        pd¦  «        }|| j        v S )zUTrue for the main Telegram DM (or General topic) when topic mode has made it a lobby.rµ  Fr®   ©r�   rÄ  rÍ  r´  rE  rw   r›  Ú_TELEGRAM_GENERAL_TOPIC_IDS©r  r(  Útids      r>   Ú_is_telegram_topic_root_lobbyz+GatewayRunner._is_telegram_topic_root_lobbyµ  sb   € àŒ?�hÔ/Ò/Ð/°6Ô3CÀtÒ3KÐ3KØ�5Ø×0Ò0°Ñ8Ô8ð 	Ø�5Ý�&Ô"Ð( bÑ)Ô)ˆØ�dÔ6Ð6Ð6rM   c                 ó¾   — |j         t          j        k    s|j        dk    rdS |                      |¦  «        sdS t          |j        pd¦  «        }|r	|| j        v rdS dS )z9True for a user-created Telegram private-chat topic lane.rµ  Fr®   TrG  rI  s      r>   rÕ  z%GatewayRunner._is_telegram_topic_lane¾  ss   € àŒ?�hÔ/Ò/Ð/°6Ô3CÀtÒ3KÐ3KØ�5Ø×0Ò0°Ñ8Ô8ð 	Ø�5Ý�&Ô"Ð( bÑ)Ô)ˆØð 	�c˜TÔ=Ð=Ð=Ø�5ØˆtrM   r%   c                 ó  — t          | d¦  «        si | _        t          |j        pd¦  «        }|sdS ddl}|                     ¦   «         }| j                             |d¦  «        }||z
  | j        k     rdS || j        |<   dS )a+  Rate-limit root-DM lobby reminders to one message per cooldown window.

        A user who forgets multi-session mode is enabled and types several
        prompts in the root DM would otherwise get a reminder for every
        message. Cap it so the first one lands and the rest stay quiet.
        Ú_telegram_lobby_reminder_tsr®   Tr   Nr@  F)rá   rN  rw   r2  rU   r—  rv   Ú#_TELEGRAM_LOBBY_REMINDER_COOLDOWN_S©r  r(  r2  rW   rŒ  Úlasts         r>   Ú$_should_send_telegram_lobby_reminderz2GatewayRunner._should_send_telegram_lobby_reminderË  sœ   € õ �tÐ:Ñ;Ô;ð 	2Ø/1ˆDÔ,Ý�f”nÐ*¨Ñ+Ô+ˆØð 	Ø�4ØÐÐÐØ�oŠoÑÔˆØÔ/×3Ò3°G¸SÑAÔAˆØ�‰:˜Ô@Ò@Ð@Ø�5Ø47ˆÔ(¨Ñ1ØˆtrM   c                 ó   — 	 dS )Na  This main chat is reserved for system commands.

To start a new Hermes chat, open the All Messages topic at the top of this bot interface and send any message there. Telegram will create a new topic for that message; each topic works as an independent Hermes session.rN  rN  s    r>   Ú"_telegram_topic_root_lobby_messagez0GatewayRunner._telegram_topic_root_lobby_messageß  s   € ð*ð	
ð 	
rM   c                 ó   — 	 dS )Na0  To start a new parallel Hermes chat, open the All Messages topic at the top of this bot interface and send any message there. Telegram will create a new topic for it.

Each topic is an independent Hermes session. Use /new inside an existing topic only if you want to replace that topic's current session.rN  rN  s    r>   Ú _telegram_topic_root_new_messagez.GatewayRunner._telegram_topic_root_new_messageè  s   € ðWð	
ð 	
rM   c                 ó6   — |                       |¦  «        sd S 	 dS )NzßStarted a new Hermes session in this topic.

Tip: for parallel work, open All Messages and send a message there to create a separate topic instead of using /new here. /new replaces the session attached to the current topic.)rÕ  ©r  r(  s     r>   Ú_telegram_topic_new_headerz(GatewayRunner._telegram_topic_new_headerñ  s,   € Ø×+Ò+¨FÑ3Ô3ð 	Ø�4ð9ð	
ð 	
rM   c                 ó&  — t          | dd¦  «        }|�|j        r|j        sdS t          |d|¦  «        }|                     t	          |j        ¦  «        t	          |j        ¦  «        t	          |j        pd¦  «        |j        |j        ¬¦  «         dS )zEPersist the Telegram topic -> Hermes session binding for topic lanes.rR   NrS   r®   )r2  r›  r¹  r+   rN   )rV   r2  r›  Úbind_telegram_topicrw   r¹  r+   rN   )r  r(  Úsession_entryrX   s       r>   Ú_record_telegram_topic_bindingz,GatewayRunner._record_telegram_topic_bindingû  s    € õ ˜T =°$Ñ7Ô7ˆ
ØÐ V¤^Ð¸6Ô;KÐØˆFå˜Z¨°
Ñ;Ô;ˆ
Ø×&Ò&Ý˜œÑ'Ô'Ý˜&Ô*Ñ+Ô+Ý˜œÐ,¨"Ñ-Ô-Ø%Ô1Ø$Ô/ð 	'ñ 	
ô 	
ð 	
ð 	
ð 	
rM   r•  c                ó¾   — |                       |¦  «        sdS 	 |                      ||¦  «         dS # t          $ r! t                               d|d¬¦  «         Y dS w xY w)u4  Update the topic binding to point at ``session_entry.session_id``.

        Telegram topic lanes persist a (chat_id, thread_id) -> session_id row
        so reopening a topic in a fresh process resumes the right Hermes
        session. When compression rotates ``session_entry.session_id`` mid-turn,
        the binding goes stale and the next inbound message in that topic
        reloads the oversized parent transcript instead of the compressed
        child, retriggering preflight compression â€” sometimes in a loop
        (#20470, #29712, #33414).
        Nz*telegram topic binding refresh failed (%s)Trß   )rÕ  r]  r2   r3   r4   )r  r(  r\  r•  s       r>   rÏ  z*GatewayRunner._sync_telegram_topic_binding  sŒ   € ð" ×+Ò+¨FÑ3Ô3ð 	ØˆFð	Ø×/Ò/°¸ÑFÔFÐFÐFÐFøÝð 	ð 	ð 	Ý�LŠLØ<¸fÈtð ñ ô ð ð ð ð ð	øøøs   ™1 ±'AÁAc                 óÆ  — |j         t          j        k    s.|j        dk    s#|j        r|j        r|                      |¦  «        sdS t          |j        pd¦  «        }| p|| j	        v }|sdS t          | dd¦  «        }|€dS t          |d|¦  «        }	 |                     t          |j        ¦  «        ¬¦  «        }n-# t          $ r  t                               dd¬	¦  «         Y dS w xY w|sdS t          |j        ¦  «        }|D ]]}t          |                     d
¦  «        pd¦  «        |k    r3t          |                     d¦  «        pd¦  «        }|r
||k    r|c S  dS Œ^dS )aO  Pin DM-topic routing to the user's last-active topic.

        Telegram can omit ``message_thread_id`` or surface General (``1``)
        for some topic-mode DM replies. In those lobby-shaped cases, keep the
        conversation attached to the user's most-recent bound topic.

        Do not rewrite a non-lobby, previously-unbound thread id: a newly
        created Telegram DM topic is also "unknown" until the first inbound
        message is recorded, and rewriting it would send that brand-new topic's
        answer into an older lane. Returns None to leave the source alone.
        rµ  Nr®   rR   rS   rÊ  ztopic-recover: read failedTrß   r¹  r›  )r�   rÄ  rÍ  r´  r2  r¹  rE  rw   r›  rH  rV   Ú%list_telegram_topic_bindings_for_chatr2   r3   r4   rv   )	r  r(  ÚinboundÚis_lobbyrX   Úbindingsr¹  ÚbÚ	recovereds	            r>   Ú!_recover_telegram_topic_thread_idz/GatewayRunner._recover_telegram_topic_thread_id(  sÄ  € ð  ŒO�xÔ0Ò0Ð0ØÔ 4Ò'Ð'Ø”>ð (à”>ð (ð ×4Ò4°VÑ<Ô<ð (ð
 �4Ý�fÔ&Ð,¨"Ñ-Ô-ˆØ�;ÐM '¨TÔ-MÐ"MˆØð 	ð
 �4Ý˜T =°$Ñ7Ô7ˆ
ØÐØ�4å˜Z¨°
Ñ;Ô;ˆ
ð	Ø!×GÒGÝ˜FœNÑ+Ô+ð Hñ ô ˆHˆHøõ ð 	ð 	ð 	Ý�LŠLÐ5ÀˆLÑEÔEÐEØ�4�4ð	øøøð ð 	Ø�4Ý�f”nÑ%Ô%ˆØð 	ð 	ˆAÝ�1—5’5˜Ñ#Ô#Ð) rÑ*Ô*¨gÒ5Ð5Ý §¢ kÑ 2Ô 2Ð 8°bÑ9Ô9�	Øð % ¨gÒ!5Ð!5Ø$Ð$Ð$Ð$Ø�t�tð	 6ð
 ˆts   Â(B< Â<&C&Ã%C&c                 óˆ   — 	 |                       |¦  «        }n# t          $ r |cY S w xY w|€|S t          j        ||¬¦  «        S )uÂ  Apply Telegram DM topic recovery to a source for session-key purposes.

        ``_handle_message_with_agent`` rewrites ``source.thread_id`` via
        ``_recover_telegram_topic_thread_id`` *before* deriving the session
        key for a normal message turn (a lobby/stripped reply gets pinned to
        the user's last-active topic).  Session-scoped command handlers like
        ``/model`` and ``/reasoning`` derive their override key from the raw
        inbound ``event.source``, which skips that recovery â€” so the override
        is stored under a different key than the next message turn reads,
        and the override is silently dropped on Telegram forum topics and
        after compression session splits (#30479).

        Returns a recovery-normalized copy when a rewrite applies, otherwise
        the original source unchanged.  Always derive the override storage key
        from the result so storage and read use an identical key.
        N©r›  )rf  r2   Údataclassesrl  )r  r(  re  s      r>   Ú!_normalize_source_for_session_keyz/GatewayRunner._normalize_source_for_session_key^  sa   € ð(	Ø×>Ò>¸vÑFÔFˆIˆIøÝð 	ð 	ð 	ØˆMˆMˆMð	øøøàÐØˆMÝÔ" 6°YÐ?Ñ?Ô?Ð?s   ‚ ˜'¦'rê  rA  c          
      ó	  — |}|s+|�)	 |                       |¦  «        }n# t          $ r d}Y nw xY wt          |¦  «        }|r|                      |¦  «         |r|                      |¦  «        nd}|r|j        j        nd}|�r7|                     d|¦  «        }|                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        d	œ}	|	                     d¦  «        rq|	                     d¦  «        €%t          |                     d¦  «        ¦  «        |	d<   t           
                    d
|pd|||	                     d¦  «        ¦  «         ||	fS t           
                    d|pd||¦  «         ndt           
                    d|pd|d„ t          |                      ¦   «                              ¦   «         ¦  «        D ¦   «         dd…         pd¦  «         t          ¦   «         }
|
                     dd¦  «        }|rt                               d||¦  «         |}t#          | dd¦  «        }|rÒ|�Ð|j        rt'          |j        ¦  «        nd}t#          |dd¦  «        rt'          |j        ¦  «        nd}t#          |dd¦  «        rt'          |j        ¦  «        nd}t-          ||j        |||¬¦  «        }|rJ|j        r|j        }|j        r5t5          |j        ¦  «        }
|
                     dd¦  «        }|r	|j        s|}|r|r|                      |||
¦  «        \  }}
|sb|
                     d¦  «        rM	 ddlm}  ||
d         ¦  «        }|r"t                               d||
d         ¦  «         n# t          $ r Y nw xY w|sq|r|                      |¦  «        nd}|                      d¦  «        }|r|j        j        ndp|r|j        j        nd}|r t                               d|pd|¦  «         |}nB|r@|r||                       |¦  «        j        _        ||                       d¦  «        j        _        ||
fS )uî   Resolve model/runtime for a session.

        Priority (highest first): session ``/model`` â†’ ``channel_overrides`` â†’
        global config/env (``_resolve_gateway_model(user_config)`` and default
        provider resolution).
        Nr  r  rÅ  r  r·  r´  r¹  )r  rÅ  r  r·  r´  r¹  zZSession model override (fast): session=%s config_model=%s -> override_model=%s provider=%sr®   z[Session model override (no api_key, fallback): session=%s config_model=%s override_model=%szFNo session model override: session=%s config_model=%s override_keys=%sc                 ó0   — g | ]\  }}|j         j        ®|‘ŒS r^   )ÚconversationÚmodel_override)rb   Ú_keyÚ_sts      r>   r  z@GatewayRunner._resolve_session_agent_runtime.<locals>.<listcomp>¸  s2   € ð ð ð á!˜˜cØÔ'Ô6ÐBð àBÐBÐBrM   r²  z[]z;Runtime provider supplied explicit model override: %s -> %srz   r›  ré  rš  r   )Úget_default_model_for_provideru8   No model configured â€” defaulting to %s for provider %srÍ  u{   Empty model resolved for session=%s â€” recovering last-known-good model %s (config read likely returned empty; see #35314))!rA  r2   r™  Ú!_rehydrate_session_model_overriderA   rm  rn  rv   rÊ  r3   r4   r½  rF  rñ  rÅ  rU  rz  rV   r2  rw   r›  ré  r¥  r�   r  r  rÈ  Ú_apply_session_model_overrideÚhermes_cli.modelsrq  Úlast_resolved_modelrã   r/   )r  r(  r+   rA  Úresolved_session_keyr  Ú_override_stater|  Úoverride_modelÚoverride_runtimerÔ  Úruntime_modelrœ  r2  r›  rœ  ÚchÚch_runtime_modelrq  Ú	_lr_stateÚ_lr_starÚ
_recovereds                         r>   r�  z,GatewayRunner._resolve_session_agent_runtimez  sÏ  € ð  +ÐØ#ð 	,¨Ð(:ð,Ø'+×'CÒ'CÀFÑ'KÔ'KÐ$Ð$øÝð ,ð ,ð ,Ø'+Ð$Ð$Ð$ð,øøøõ ' {Ñ3Ô3ˆØð 	IØ×2Ò2Ð3GÑHÔHÐHð $ðˆD×$Ò$Ð%9Ñ:Ô:Ð:àð 	ð <KÐTˆOÔ(Ô7Ð7ÐPTð 	ð ñ $	Ø%Ÿ\š\¨'°5Ñ9Ô9ˆNà$ŸLšL¨Ñ4Ô4Ø#Ÿ<š<¨	Ñ2Ô2Ø$ŸLšL¨Ñ4Ô4Ø$ŸLšL¨Ñ4Ô4Ø&Ÿlšl¨<Ñ8Ô8Ø#+§<¢<Ð0AÑ#BÔ#Bð ð  Ðð  ×#Ò# IÑ.Ô.ð 
8Ø#×'Ò'Ð(9Ñ:Ô:ÐBÝ:WØ Ÿš ZÑ0Ô0ñ;ô ;Ð$Ð%6Ñ7õ —’ØpØ(Ð.¨B°°~Ø$×(Ò(¨Ñ4Ô4ñô ð ð
 &Ð'7Ð7Ð7õ �LŠLØmØ$Ð*¨¨E°>ñô ð ð õ
 �LŠLØXØ$Ð*¨¨Eðð å%)¨$×*<Ò*<Ñ*>Ô*>×*DÒ*DÑ*FÔ*FÑ%GÔ%Gðñ ô ð �1�"ô	ð ð ñô ð õ 7Ñ8Ô8ˆØ&×*Ò*¨7°DÑ9Ô9ˆØð 	"Ý�KŠKØMØØñô ð ð
 "ˆEå�d˜H dÑ+Ô+ˆØð 	1�6Ð%Ø-3¬^ÐC•c˜&œ.Ñ)Ô)Ð)ÀˆGå)0°¸ÀdÑ)KÔ)KÐU•�FÔ$Ñ%Ô%Ð%ÐQUð õ
 ˜6Ð#3°TÑ:Ô:ð•�FÔ)Ñ*Ô*Ð*àð õ
 'ØØ”ØØ#Ø#ðñ ô ˆBð ð 1Ø”8ð %ØœH�EØ”;ð 1Ý%OØœñ&ô &�Nð (6×'9Ò'9¸'À4Ñ'HÔ'HÐ$ð (ð 1°´ð 1Ø 0˜àð 	Ð,ð 	Ø$(×$FÒ$FØ$ e¨^ñ%ô %Ñ!ˆE�>ð ð 
	˜×+Ò+¨JÑ7Ô7ð 
	ð	ØLÐLÐLÐLÐLÐLØ6Ð6°~ÀjÔ7QÑRÔR�Øð Ý—K’KØRØ˜~¨jÔ9ñô ð øøõ ð ð ð Ø�ðøøøð ð 	Nð (ð�×(Ò(Ð)=Ñ>Ô>Ð>àð ð
 ×/Ò/°Ñ4Ô4ˆHà?HÐP�Ô'Ô;Ð;Èbð SØAIÐQ�HÔ)Ô=Ð=Èrð ð ð #Ý—’ð)ð )Ð.¨B°
ñ	ô ð ð #�øØð 	Nà#ð ;ð 6;ð ×#Ò#Ø(ñô äÔ2ØHMˆD×Ò Ñ$Ô$Ô1ÔEà�nÐ$Ð$s   ˆ ž-¬-Í<;N8 Î8
OÏOÚuser_messager  rÔ  c                 ó¦  — ddl m} |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        |                     d¦  «        t          |                     d	¦  «        pg ¦  «        |                     d
¦  «        |                     d¦  «        dœ	}||||d         |d         |d         |d         |d         t	          |d	         ¦  «        fdœ}t          | dd¦  «        }|si |d<   |S 	  ||d         ¦  «        }n# t          $ r d}Y nw xY w|pi |d<   |S )a2  Build the effective model/runtime config for a single turn.

        Always uses the session's primary model/provider.  If `/fast` is
        enabled and the model supports Priority Processing / Anthropic fast
        mode, attach `request_overrides` so the API call is marked
        accordingly.
        r   )Úresolve_fast_mode_overridesrÅ  r  r  r¶  r·  r   r¸  r¹  r´  rº  )r  r¿  r“  r’  Nr  r  )rt  r‚  rv   r½  r€  rV   r2   )	r  r€  r  rÔ  r‚  r¿  Úrouter  r£  s	            r>   r˜  z(GatewayRunner._resolve_turn_agent_config"  sŸ  € ð 	BÐAÐAÐAÐAÐAð &×)Ò)¨)Ñ4Ô4Ø&×*Ò*¨:Ñ6Ô6Ø&×*Ò*¨:Ñ6Ô6Ø"0×"4Ò"4Ð5IÑ"JÔ"JØ&×*Ò*¨:Ñ6Ô6Ø%×)Ò)¨)Ñ4Ô4Ý˜×+Ò+¨FÑ3Ô3Ð9°rÑ:Ô:Ø-×1Ò1Ð2CÑDÔDØ(×,Ò,¨\Ñ:Ô:ð

ð 

ˆð ØàØ˜
Ô#ØÐ,Ô-Ø˜
Ô#Ø˜
Ô#Ø˜	Ô"Ý�g˜f”oÑ&Ô&ðð
ð 
ˆõ ˜t _°dÑ;Ô;ˆØð 	Ø)+ˆEÐ%Ñ&ØˆLð	Ø3Ð3°E¸'´NÑCÔCˆIˆIøÝð 	ð 	ð 	ØˆIˆIˆIð	øøøà%. _°"ˆÐ!Ñ"Øˆs   Ä&D8 Ä8EÅErN   rµ   c           
      ó¸  ‡
— |r	|�| j         €dS t          |dd¦  «        }|sdS t          |dd¦  «        t          |dd¦  «        t          |dd¦  «        t          t          |dd¦  «        ¦  «        dœ}d	„ |                     ¦   «         D ¦   «         }	 | j         j        }|                     |¦  «        }|sdS |                     d¦  «        }|                     d
¦  «        }	 |rt          j        |¦  «        ni }	n# t          $ r i }	Y nw xY wt          |	t          ¦  «        si }	t          |	                     d¦  «        pi ¦  «        Š
||k    r/t          ˆ
fd„|                     ¦   «         D ¦   «         ¦  «        rdS ||	d<   |                     |t          j        |	¦  «        |¬¦  «         dS # t          $ r  t                               dd¬¦  «         Y dS w xY w)uf  Persist the runtime model/provider actually used by a gateway turn.

        Provider fallback can switch ``agent.model``/``agent.provider`` after the
        session row was created. Keep the session DB metadata in sync so session
        lists, desktop/dashboard details, and follow-up session tooling report the
        backend that actually answered the latest turn.

        Called from the ``run_sync`` closure, which executes off the event loop
        in the executor thread â€” so the synchronous ``SessionDB`` (``_db``) is
        used directly rather than awaiting the AsyncSessionDB forwarder.
        Nr  r  r  r·  Ú_fallback_activatedF)r  r  r·  Úfallback_activec                 ó"   — i | ]\  }}|d v¯	||“ŒS ))Nr®   rN  rç  s      r>   rê  z@GatewayRunner._sync_session_model_from_agent.<locals>.<dictcomp>h  s(   € ÐKÐKÐK™D˜A˜q°qÀ
Ð7JÐ7J�1�aÐ7JÐ7JÐ7JrM   Úmodel_configÚgateway_runtimec              3   óP   •K  — | ] \  }}‰                      |¦  «        |k    V — Œ!d S r^   rr  )rb   rè  ré  r‰  s      €r>   rd   z?GatewayRunner._sync_session_model_from_agent.<locals>.<genexpr>x  sK   øè è € ð .ð .Ù04°°1�×#Ò# AÑ&Ô&¨!Ò+ð.ð .ð .ð .ð .ð .rM   )r  z-Failed to sync gateway session model metadataTrß   )rR   rV   rº   rñ  rS   r�  rv   r3  r4  r2   rt   ru   r�  Úupdate_session_metarB  r3   r4   )r  rN   rµ   r  r¿  ÚdbÚrowÚcurrent_modelÚ
raw_configrz   r‰  s             @r>   rÐ  z,GatewayRunner._sync_session_model_from_agentQ  s;  ø€ ð ð 	˜U˜]¨dÔ.>Ð.FØˆFÝ˜˜w¨Ñ-Ô-ˆØð 	ØˆFå  z°4Ñ8Ô8Ý  z°4Ñ8Ô8Ý  z°4Ñ8Ô8Ý#¥G¨EÐ3HÈ%Ñ$PÔ$PÑQÔQð	
ð 
ˆð LÐK G§M¢M¡O¤OÐKÑKÔKˆð	YØÔ!Ô%ˆBØ—.’. Ñ,Ô,ˆCØð Ø�ØŸGšG GÑ,Ô,ˆMØŸš Ñ0Ô0ˆJðØ3=ÐE�œ JÑ/Ô/Ð/À2��øÝð ð ð Ø���ðøøøå˜f¥dÑ+Ô+ð Ø�Ý" 6§:¢:Ð.?Ñ#@Ô#@Ð#FÀBÑGÔGˆOØ Ò%Ð%­#ð .ð .ð .ð .Ø8?¿º¹¼ð.ñ .ô .ñ +ô +Ð%ð �Ø(/ˆFÐ$Ñ%Ø×"Ò" :­t¬z¸&Ñ/AÔ/AÈÐ"ÑOÔOÐOÐOÐOøÝð 	Yð 	Yð 	YÝ�LŠLÐHÐSWˆLÑXÔXÐXÐXÐXÐXð	YøøøsC   Â#F/ Â8*F/ Ã#C< Ã;F/ Ã<DÄF/ Ä
DÄA1F/ Å>/F/ Æ/&GÇGr  c              ƒ   óð   K  — t          |                     d¦  «        pd¦  «        }	 | j                             ||¦  «        ƒ d{V —† dS # t          $ r  t
                               dd¬¦  «         Y dS w xY w)uî  Fan a normalised platform reaction event out to the HookRegistry.

        Adapters call this via ``set_reaction_handler`` for every
        platform-native reaction event they surface. The adapter-supplied
        ``event_name`` ("reaction:added" / "reaction:removed") becomes the
        hook event so user hooks subscribe with the same name scheme as the
        existing ``agent:*`` family. Errors never block the adapter's event
        loop â€” the hook contract is non-blocking.
        Ú
event_namezreaction:addedNz#[Gateway] reaction hook emit failedTrß   )rw   rv   r¸  r½  r2   r3   r4   )r  r  r‘  s      r>   Ú_handle_reaction_eventz$GatewayRunner._handle_reaction_event�  sš   è è € õ ˜Ÿš Ñ.Ô.ÐBÐ2BÑCÔCˆ
ð	OØ”*—/’/ *¨cÑ2Ô2Ð2Ð2Ð2Ð2Ð2Ð2Ð2Ð2Ð2øÝð 	Oð 	Oð 	OÝ�LŠLÐ>ÈˆLÑNÔNÐNÐNÐNÐNð	Oøøøs   ¨!A Á&A5Á4A5r1  c              ƒ   ó:  K  — t          | dd¦  «        }|€t          ¦   «         x}| _        t          j        |                      |¦  «        ¦  «        }|                     |¦  «         |                     |j        ¦  «         t          j	        |¦  «        ƒ d{V —† dS )a#  React to an adapter failure after startup.

        If the error is retryable (e.g. network blip, DNS failure), queue the
        platform for background reconnection instead of giving up permanently.

        The notification arrives on the failing adapter's own polling task,
        and the disconnect inside the handler can cancel that task mid-flight:
        disconnect()'s current-task guard misses it because
        _safe_adapter_disconnect runs the close in a wrapper task. A cancelled
        handler dies between the fatal log and the reconnect queue, silently
        stranding the platform (observed 2026-07-21: telegram popped from
        adapters but never queued after a travel network outage). Run the real
        work in a detached task that adapter teardown cannot cancel.
        r¬  N)
rV   r•   r¬  r  Úcreate_taskÚ$_handle_adapter_fatal_error_detachedr—   rä  rü  Úshield)r  r1  ÚtasksrÝ   s       r>   Ú_handle_adapter_fatal_errorz)GatewayRunner._handle_adapter_fatal_error‘  s�   è è € õ ˜Ð4°dÑ;Ô;ˆØˆ=Ý03±´Ð5ˆE�DÔ-ÝÔ" 4×#LÒ#LÈWÑ#UÔ#UÑVÔVˆØ�	Š	�$‰ŒˆØ×Ò˜uœ}Ñ-Ô-Ð-õ Œn˜TÑ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"Ð"Ð"Ð"rM   c                 ó¦  — |j         sdS | j        j                             |j        ¦  «        }|r|j        | j        v rdS |dt          j        ¦   «         |                      |j        |¦  «        |  	                    |j        |¦  «        dœ| j        |j        <   t                               d|j        j        ¦  «         |                      ¦   «          dS )a&  Queue a retryable fatal adapter for background reconnection.

        Returns True when the platform was newly queued. Idempotent if already
        queued. Must not await: callers invoke this *before* any disconnect
        await so a wedged close cannot strand the platform (#80598).
        Fr   ©rz   ÚattemptsÚ
next_retryÚcredential_claimÚlistener_claimz%%s queued for background reconnectionT)Úfatal_error_retryablerz   rE  rv   r�   r«  rU   r—  Ú_adapter_credential_claimÚ_adapter_listener_claimr3   rz  r­   Ú!_ensure_reconnect_watcher_running)r  r1  rÀ  s      r>   Ú_queue_retryable_fatal_platformz-GatewayRunner._queue_retryable_fatal_platform­  sé   € ð Ô,ð 	Ø�5Øœ+Ô/×3Ò3°GÔ4DÑEÔEˆØð 	 'Ô"2°dÔ6LÐ"LÐ"LØ�5à%ØÝœ.Ñ*Ô*Ø $× >Ò >ØÔ  'ñ!ô !ð #×:Ò:ØÔ  'ñô ð
4
ð 
4
ˆÔ˜wÔ/Ñ0õ 	�ŠØ3ØÔÔ"ñ	
ô 	
ð 	
ð 	×.Ò.Ñ0Ô0Ð0ØˆtrM   c              ƒ   óü  K  — 	 |                       ¦   «         }|dk    r|                      |¦  «        ƒ d{V —† n�|t          dt          d|¦  «        ¦  «        z   }|                      |                      |¦  «        |¦  «        ƒ d{V —†}|s;t
                               d|j        j        |¦  «         |  	                    |¦  «         nà# t          j        $ rP 	 |  	                    |¦  «         n7# t          $ r* t
                               d|j        j        d¬¦  «         Y nw xY w‚ t          $ rv t
                               d	|j        j        ¦  «         	 |  	                    |¦  «         n7# t          $ r* t
                               d
|j        j        d¬¦  «         Y nw xY wY nw xY w|j        }t          | dd¦  «        }|j        o4|| j        vo+|t          | di ¦  «        vo|duo|                     ¦   «          }|rRt
                               d|j        ¦  «         |j        › d�| _        d| _        |                      ¦   «         ƒ d{V —† dS dS # |j        }t          | dd¦  «        }|j        o4|| j        vo+|t          | di ¦  «        vo|duo|                     ¦   «          }|rQt
                               d|j        ¦  «         |j        › d�| _        d| _        |                      ¦   «         ƒ d{V —† w w xY w)zýRun the fatal handler; if the platform still ends up stranded
        (not reconnected, not queued, not intentionally disabled), exit the
        gateway with failure so the service manager restarts it instead of
        leaving a silent partial outage.r   Nç       @çš™™™™™©?zXFatal-error handling for %s timed out after %.1fs; ensuring reconnect queue is populatedz3Failed to queue %s after fatal-handler cancellationTrß   z/Fatal-error handling for %s raised unexpectedlyz0Failed to queue %s after fatal-handler exceptionr”  r«  zp%s adapter was lost without entering the reconnection queue; exiting gateway so the service manager restarts it.z( adapter lost without reconnection queue)r  Ú _handle_adapter_fatal_error_implr6   rC  r  r3   rP   r�   r­   r£  r  r›  r2   r4   rÛ   rV   rŸ  r°  r8  r—  r–  Ústop)r  r1  rÓ  Úouterrõ  r�   Úshutdown_eventÚstrandeds           r>   r•  z2GatewayRunner._handle_adapter_fatal_error_detachedÎ  s  è è € ðG	"ð
 ×;Ò;Ñ=Ô=ˆGØ˜!Š|ˆ|Ø×;Ò;¸GÑDÔDÐDÐDÐDÐDÐDÐDÐDÐDð
  ¥# c­3¨t°WÑ+=Ô+=Ñ">Ô">Ñ>�Ø"&×"JÒ"JØ×9Ò9¸'ÑBÔBØñ#ô #ð ð ð ð ð ð �	ð !ð BÝ—L’Lð@àÔ(Ô.Øñ	ô ð ð ×8Ò8¸ÑAÔAÐAøøÝÔ%ð 	ð 	ð 	ðØ×4Ò4°WÑ=Ô=Ð=Ð=øÝð ð ð Ý—’ØIØÔ$Ô*Ø!ð ñ ô ð ð ð ðøøøð Ýð 	ð 	ð 	Ý×ÒØAØÔ Ô&ñô ð ðØ×4Ò4°WÑ=Ô=Ð=Ð=øÝð ð ð Ý—’ØFØÔ$Ô*Ø!ð ñ ô ð ð ð ðøøøøøð	øøøð  Ô'ˆHÝ$ TÐ+<¸dÑCÔCˆNàÔ-ð QØ D¤MÐ1ðQà¥G¨DÐ2EÀrÑ$JÔ$JÐJðQð (¨tÐ3ÐO¸×8MÒ8MÑ8OÔ8OÐPð	 ð ð 
"Ý—’ðQà”Nñô ð ð  ”~ÐOÐOÐOð Ô!ð +/�Ô'Ø—i’i‘k”kÐ!Ð!Ð!Ð!Ð!Ð!Ð!Ð!Ð!ð
"ð 
"øð Ô'ˆHÝ$ TÐ+<¸dÑCÔCˆNàÔ-ð QØ D¤MÐ1ðQà¥G¨DÐ2EÀrÑ$JÔ$JÐJðQð (¨tÐ3ÐO¸×8MÒ8MÑ8OÔ8OÐPð	 ð ð 
"Ý—’ðQà”Nñô ð ð  ”~ÐOÐOÐOð Ô!ð +/�Ô'Ø—i’i‘k”kÐ!Ð!Ð!Ð!Ð!Ð!Ð!Ð!ð
"øøøss   „CC ÃI ÃF%ÃC.Ã-F%Ã.1D"ÄF%Ä!D"Ä"2F%ÅE+Å*F%Å+1FÆF%ÆFÆF%Æ"I Æ$F%Æ%I ÉB)K;c              ƒ   óü  K  — | j                              |j        ¦  «        }|�3||ur/t                               d|j        j        |j        pd¦  «         d S t                               d|j        j        |j        pd|j        pd¦  «         |j        dk    rd}n|j	        rd}nd}|  
                    |j        j        ||j        |j        ¬	¦  «         ||u r1| j                              |j        d ¦  «         | j         | j        _         |                      |¦  «         ||u r!|                      ||j        ¦  «        ƒ d {V —† | j         st| j        sm|j        pd
| _        |j	        r"d| _        t                               d¦  «         nt                               d¦  «         |                      ¦   «         ƒ d {V —† d S | j         s6| j        r1t                               dt)          | j        ¦  «        ¦  «         d S d S d S )NzDIgnoring stale fatal error from a superseded %s adapter instance: %sr¼  zFatal %s adapter error (%s): %srÛ  Úrelay_disabledrj  ÚretryingÚfatal©Úplatform_stateÚ
error_codeÚerror_messagez#All messaging adapters disconnectedTzSNo connected messaging platforms remain. Shutting down gateway for service restart.zGNo connected messaging platforms remain. Shutting down gateway cleanly.u�   No connected messaging platforms remain, but %d platform(s) queued for reconnection â€” gateway staying alive, watcher will retry in background.)r°  rv   r�   r3   r4   r­   Úfatal_error_coderP   Úfatal_error_messagerŸ  Ú_update_platform_runtime_statusrU  r‘  r£  r  r«  r—  r–  r¨  rã   r7   )r  r1  Úexistingr±  s       r>   r§  z.GatewayRunner._handle_adapter_fatal_error_impl  sl  è è € ð ”=×$Ò$ WÔ%5Ñ6Ô6ˆØÐ H°GÐ$;Ð$;Ý�LŠLØVØÔ Ô&ØÔ(Ð5¨Iñô ð ð
 ˆFå�ŠØ-ØÔÔ"ØÔ$Ð1¨	ØÔ'Ð:¨?ñ		
ô 	
ð 	
ð Ô#Ð'7Ò7Ð7Ø'ˆNˆNØÔ*ð 	%Ø'ˆNˆNà$ˆNØ×,Ò,ØÔÔ"Ø)ØÔ/Ø!Ô5ð	 	-ñ 	
ô 	
ð 	
ð �wÐÐð ŒM×Ò˜gÔ.°Ñ5Ô5Ð5Ø,0¬MˆDÔ Ô)ð 	×,Ò,¨WÑ5Ô5Ð5à�wÐÐð ×/Ò/°¸Ô9IÑJÔJÐJÐJÐJÐJÐJÐJÐJàŒ}ð 	 TÔ%;ð 	Ø 'Ô ;Ð dÐ?dˆDÔØÔ,ð hØ*.�Ô'Ý—’ÐrÑsÔsÐsÐså—’ÐfÑgÔgÐgØ—)’)‘+”+ÐÐÐÐÐÐÐÐÐØ”ð 	 4Ô#9ð 	õ �NŠNð'õ �DÔ*Ñ+Ô+ñ	ô ð ð ð ð	ð 	ð 	ð 	rM   c                 óT   — d| _         || _        | j                             ¦   «          d S ©NT)r•  r—  r”  r•   )r  r•  s     r>   Ú_request_clean_exitz!GatewayRunner._request_clean_exitx  s-   € Ø!ˆÔØ"ˆÔØÔ× Ò Ñ"Ô"Ð"Ð"Ð"rM   c                 ó*   — t          | j        ¦  «        S r^   )r7   r7  rN  s    r>   Ú_running_agent_countz"GatewayRunner._running_agent_count}  s   € Ý�4Ô'Ñ(Ô(Ð(rM   c                 ó~   — |                       ¦   «         |                      ¦   «         z   |                      ¦   «         z   S )z>All agent work the gateway must expose and drain as one total.)r¼  Ú_active_cron_job_countÚ_active_api_run_countrN  s    r>   Ú_active_work_countz GatewayRunner._active_work_count€  s@   € ð ×%Ò%Ñ'Ô'Ø×)Ò)Ñ+Ô+ñ,à×(Ò(Ñ*Ô*ñ+ð	
rM   c                 ó`   — 	 ddl m} t           |¦   «         ¦  «        S # t          $ r Y dS w xY w)u9  Count of cron jobs currently executing, from the cron scheduler's
        own in-flight tracking (``cron.scheduler._running_job_ids``).

        Cron jobs run through a standalone ``AIAgent`` on the scheduler's own
        thread pool (``cron/scheduler.py::run_job``), entirely outside
        ``self._running_agents`` â€” the dict every OTHER active-work check on
        this class (``_running_agent_count``, ``_drain_active_agents``) reads.
        Without this, the shutdown drain is structurally blind to in-flight
        cron work: it can report ``active_at_start=0`` and proceed straight
        to killing tool subprocesses while a cron job's terminal command is
        still running (#60432). Best-effort: returns 0 if the cron module
        can't be imported (e.g. a minimal test double for this class).
        r   )Úget_running_job_ids)rc  rÂ  r7   r2   )r  rÂ  s     r>   r¾  z$GatewayRunner._active_cron_job_countˆ  sS   € ð	Ø:Ð:Ð:Ð:Ð:Ð:ÝÐ*Ð*Ñ,Ô,Ñ-Ô-Ð-øÝð 	ð 	ð 	Ø�1�1ð	øøøs   ‚ Ÿ
-¬-c                 ó  — 	 t          | di ¦  «                             t          j        ¦  «        }t          |dd¦  «        }t	          |¦  «        r%t          dt           |¦   «         ¦  «        ¦  «        ndS # t          $ r Y dS w xY w)a/  Count API-server work that is outside ``_running_agents``.

        The primary API server owns the sole HTTP listener. Secondary multiplex
        profiles cannot create an ``api_server`` adapter because it binds a port,
        so only the primary registry is a supported source of this work.
        r°  Úactive_agent_work_countNr   )rV   rv   rÄ  rÒ  r/  rC  rh  r2   )r  r1  Úhelpers      r>   r¿  z#GatewayRunner._active_api_run_countœ  s‹   € ð	Ý˜d J°Ñ3Ô3×7Ò7½Ô8KÑLÔLˆGÝ˜WÐ&?ÀÑFÔFˆFÝ,4°VÑ,<Ô,<ÐC•3�q�#˜f˜f™hœh™-œ-Ñ(Ô(Ð(À!ÐCøÝð 	ð 	ð 	Ø�1�1ð	øøøs   ‚A4A7 Á7
BÂBc                 óV  — 	 t          | di ¦  «                             t          j        ¦  «        }t          |dd¦  «        }t	          |¦  «        r&t          dt           ||¦  «        ¦  «        ¦  «        ndS # t          $ r&}t           	                    d|¦  «         Y d}~dS d}~ww xY w)a¾  Interrupt API-server agents that are not in ``_running_agents``.

        Counterpart of ``_active_api_run_count()``: that method folds
        adapter-owned API work into the shutdown drain, so this one must reach
        the same agents when the drain times out. Duck-typed on the adapter so
        an older adapter (or a minimal test double for this class) without the
        hook is simply skipped rather than raising mid-shutdown.
        r°  Úinterrupt_active_runsNr   z7Failed interrupting api_server runs during shutdown: %s)
rV   rv   rÄ  rÒ  r/  rC  rh  r2   r3   r4   )r  r•  r1  rÅ  r<   s        r>   Ú_interrupt_api_server_runsz(GatewayRunner._interrupt_api_server_runsª  s¯   € ð	Ý˜d J°Ñ3Ô3×7Ò7½Ô8KÑLÔLˆGÝ˜WÐ&=¸tÑDÔDˆFÝ2:¸6Ñ2BÔ2BÐI•3�q�#˜f˜f V™nœnÑ-Ô-Ñ.Ô.Ð.ÈÐIøÝð 	ð 	ð 	Ý�LŠLÐRÐTWÑXÔXÐXØ�1�1�1�1�1øøøøð	øøøs   ‚A5A8 Á8
B(ÂB#Â#B(c                 ót  — t          d„ | j        D ¦   «         ¦  «        rdS 	 ddlm}  |¦   «         dk    rdS n,# t          $ r t
                               dd¬¦  «         Y nw xY w	 ddlm} | 	                    ¦   «         rdS |j
        rdS n,# t          $ r t
                               dd¬¦  «         Y nw xY wd	S )
an  Live background work that must block a suspend (D3/F7).

        Backgrounded delegate_task / kanban / terminal(background=true) are NOT
        counted by _running_agent_count(), but suspending mid-flight loses them.
        Checks the runner's own tracked tasks + the process registry's running
        processes + any pending process-completion watchers.
        c              3   ó6   K  — | ]} |j         ¦   «          V — Œd S r^   )r  )rb   r   s     r>   rd   zHGatewayRunner._scale_to_zero_has_live_background_work.<locals>.<genexpr>É  s,   è è € Ð<Ð< �6�1”6‘8”8ˆ|Ð<Ð<Ð<Ð<Ð<Ð<rM   Tr   )Úactive_countz+scale-to-zero async-delegation check failedrß   r*  z"scale-to-zero bg-work check failedF)r
  r¼  Útools.async_delegationrË  r2   r3   r4   r-  r+  Úhas_any_activeÚpending_watchers)r  rË  r+  s      r>   Ú'_scale_to_zero_has_live_background_workz5GatewayRunner._scale_to_zero_has_live_background_workÁ  s"  € õ Ð<Ð< TÔ%;Ð<Ñ<Ô<Ñ<Ô<ð 	Ø�4ð	WØ;Ð;Ð;Ð;Ð;Ð;àˆ|‰~Œ~ Ò!Ð!Ø�tð "øåð 	Wð 	Wð 	WÝ�LŠLÐFÐQUˆLÑVÔVÐVÐVÐVð	Wøøøð	NØ?Ð?Ð?Ð?Ð?Ð?à×.Ò.Ñ0Ô0ð Ø�tØÔ0ð Ø�tðøåð 	Nð 	Nð 	NÝ�LŠLÐ=ÈˆLÑMÔMÐMÐMÐMð	Nøøøàˆus'   ¢9 ¹&A"Á!A"Á&B ÂB Â&B5Â4B5c                 óp  — ddl m} d }	 t          ¦   «         }t          |t          ¦  «        r|                     d¦  «        nd }t          |t          ¦  «        r|                     d¦  «        nd }t          |t          ¦  «        r|                     d¦  «        }n# t          $ r d }Y nw xY w ||¦  «        S )Nr   )Úparse_idle_timeout_secondsr9   Úscale_to_zeroÚidle_timeout_minutes)Úgateway.scale_to_zerorÑ  rs   rt   ru   rv   r2   )r  rÑ  rx  Úuser_cfgrÔ  Ústzs         r>   Ú#_scale_to_zero_idle_timeout_secondsz1GatewayRunner._scale_to_zero_idle_timeout_secondsÝ  sÍ   € ØDÐDÐDÐDÐDÐDàˆð	Ý+Ñ-Ô-ˆHÝ,6°xÅÑ,FÔ,FÐP�—’˜iÑ(Ô(Ð(ÈDˆBÝ-7¸½DÑ-AÔ-AÐK�"—&’&˜Ñ)Ô)Ð)ÀtˆCÝ˜#�tÑ$Ô$ð 6Ø—g’gÐ4Ñ5Ô5�øøÝð 	ð 	ð 	ØˆCˆCˆCð	øøøà)Ð)¨#Ñ.Ô.Ð.s   ŠBB ÂB*Â)B*c                 ó¬  — ddl m} |j        }|j        }|j        }	 t          ¦   «         }t          |t          ¦  «        r|                     d¦  «        nd}t          |t          ¦  «        r|                     d¦  «        nd}t          |t          ¦  «        r¨t          |                     d¦  «        t          ¦  «        r|d         }t          |                     d¦  «        t          ¦  «        r|d         dk    r|d         }t          |                     d¦  «        t          ¦  «        r|d         dk    r|d         }n# t          $ r Y nw xY w|||fS )	a
  Return ``(max_restarts, window_seconds, max_gap_seconds)`` for the
        auto-resume restart-loop breaker (#30719, defense-3), read from
        ``gateway.restart_loop_guard`` in config.yaml with the module defaults
        as fallback. ``max_restarts <= 0`` disables the breaker.

        ``max_gap_seconds`` is the longest spacing between two consecutive
        restart-interrupted boots that still counts them as the same loop, so
        a crash cycle slower than ``window_seconds`` stays visible (#81642).
        r   ©Úrestart_loop_guardr9   NrÚ  Úmax_restartsÚwindow_secondsÚmax_gap_seconds)r9   rÚ  ÚDEFAULT_MAX_RESTARTSÚDEFAULT_WINDOW_SECONDSÚDEFAULT_MAX_GAP_SECONDSrs   rt   ru   rv   rh  r2   )r  Ú_rlgrÛ  rÜ  rÝ  rÕ  rÔ  Úrlgs           r>   Ú_restart_loop_guard_configz(GatewayRunner._restart_loop_guard_configë  sg  € ð 	7Ð6Ð6Ð6Ð6Ð6àÔ0ˆØÔ4ˆØÔ6ˆð	Ý+Ñ-Ô-ˆHÝ,6°xÅÑ,FÔ,FÐP�—’˜iÑ(Ô(Ð(ÈDˆBÝ2<¸RÅÑ2FÔ2FÐP�"—&’&Ð-Ñ.Ô.Ð.ÈDˆCÝ˜#�tÑ$Ô$ð 	=Ý˜cŸgšg nÑ5Ô5µsÑ;Ô;ð 7Ø#& ~Ô#6�LÝ˜cŸgšgÐ&6Ñ7Ô7½Ñ=Ô=ð ;À#ÐFVÔBWÐZ[ÒB[ÐB[Ø%(Ð)9Ô%:�Nå˜sŸwšwÐ'8Ñ9Ô9½3Ñ?Ô?ð=àÐ-Ô.°Ò2Ð2à&)Ð*;Ô&<�OøøÝð 	ð 	ð 	ØˆDð	øøøà˜^¨_Ð<Ð<s   �D#E Å
EÅEc                 ó&  — ddl m} ddlm}m}m} 	 | j        r(d„ | j        j                             ¦   «         D ¦   «         ng }n# t          $ r g }Y nw xY w	  |¦   «         }n# t          $ r d}Y nw xY w | |¦   «          ||¦  «        |¬¦  «        S )u4   Whether to start the idle watcher (D1/D11/Â§3.4(1)).r   ©Úrelay_wake_url)Ú!messaging_is_relay_only_or_absentÚscale_to_zero_enabledÚ
should_armc                 ó:   — g | ]\  }}t          |d d¦  «        ¯|‘ŒS )rÓ  F©rV   ©rb   r;  Úpcs      r>   r  z;GatewayRunner._scale_to_zero_should_arm.<locals>.<listcomp>   s.   € Ð_Ð_Ð_‘u�q˜"ÅÈÈYÐX]ÑA^ÔA^Ð_�Ð_Ð_Ð_rM   N)rÓ  Úrelay_only_or_absentÚwake_url)
Úgateway.relayræ  rÔ  rç  rè  ré  rz   rE  rñ  r2   )r  ræ  rç  rè  ré  rE  rï  s          r>   Ú_scale_to_zero_should_armz'GatewayRunner._scale_to_zero_should_arm  s  € à0Ð0Ð0Ð0Ð0Ð0ð	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð	ð ”;ðÐ_Ð_ ¤Ô 5× ;Ò ;Ñ =Ô =Ð_Ñ_Ô_Ð_àð ˆIøõ
 ð 	ð 	ð 	ØˆIˆIˆIð	øøøð	Ø%�~Ñ'Ô'ˆHˆHøÝð 	ð 	ð 	ØˆHˆHˆHð	øøøàˆzØ)Ð)Ñ+Ô+Ø!BÐ!BÀ9Ñ!MÔ!MØð
ñ 
ô 
ð 	
s#   ’1A ÁAÁAÁ
A" Á"A1Á0A1c                 ó¼  — ddl m} ddlm}m} 	  |¦   «         }|sdS 	 | j        r(d„ | j        j                             ¦   «         D ¦   «         ng }n# t          $ r g }Y nw xY w ||¦  «        }	  |¦   «         }n# t          $ r d}Y nw xY wt           
                    d||pd|rdnd	¦  «         dS # t          $ r  t                               d
d¬¦  «         Y dS w xY w)u‰  Log why the idle watcher did NOT arm â€” but only for an OPTED-IN instance.

        A non-opted instance (no HERMES_SCALE_TO_ZERO stamp) not arming is the normal
        case and must stay silent. When the Labs stamp IS set but the watcher still
        didn't arm, that's the surprising case worth one INFO line so "why won't it
        suspend/wake?" is a log grep, not a box-dive.
        r   rå  )rç  rè  Nc                 óX   — g | ]'\  }}t          |d d¦  «        ¯t          |d|¦  «        ‘Œ(S )rÓ  Fr­   rë  rì  s      r>   r  zEGatewayRunner._log_scale_to_zero_not_armed_reason.<locals>.<listcomp>D  sJ   € ð ð ð á!˜A˜rÝ" 2 y°%Ñ8Ô8ðÝ  7¨AÑ.Ô.ðð ð rM   u›   scale-to-zero: NOT armed despite opt-in â€” relay_only_or_absent=%s (enabled platforms=%s), wake_url=%s. Need relay-only messaging + a registered wake URL.Únoner•   ÚMISSINGz.scale-to-zero: not-armed reason logging failedTrß   )rð  ræ  rÔ  rç  rè  rz   rE  rñ  r2   r3   rz  r4   )r  ræ  rç  rè  rÓ  ÚactiveÚ
relay_onlyrï  s           r>   Ú#_log_scale_to_zero_not_armed_reasonz1GatewayRunner._log_scale_to_zero_not_armed_reason0  s�  € ð 	1Ð0Ð0Ð0Ð0Ð0ð	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð
	ZØ+Ð+Ñ-Ô-ˆGØð Ø�ðð ”{ðð ð à%)¤[Ô%:×%@Ò%@Ñ%BÔ%Bðñ ô ð ð ð �øõ ð ð ð Ø���ðøøøà:Ð:¸6ÑBÔBˆJð Ø)˜>Ñ+Ô+��øÝð  ð  ð  Ø���ð øøøå�KŠKðEð ØÐ ˜&Ø!Ð0�� yñô ð ð ð øõ ð 	Zð 	Zð 	ZÝ�LŠLÐIÐTXˆLÑYÔYÐYÐYÐYÐYð	ZøøøsX   �B1 Ÿ1A ÁB1 ÁA ÁB1 ÁA Á B1 Á/
A: Á9B1 Á:B	ÂB1 ÂB	Â	&B1 Â1&CÃCc                 óÊ   — ddl m}  ||                      ¦   «         t          j        ¦   «         | j        z
  |                      ¦   «         |                      ¦   «         ¬¦  «        S )Nr   )Úis_idle)Úrunning_agent_countÚseconds_since_last_inboundÚidle_timeout_secondsÚhas_live_background_work)rÔ  rú  r¼  rU   r½  r×  rÏ  )r  rú  s     r>   Ú_scale_to_zero_is_idlez$GatewayRunner._scale_to_zero_is_idle^  sk   € Ø1Ð1Ð1Ð1Ð1Ð1àˆwØ $× 9Ò 9Ñ ;Ô ;Ý'+¤y¡{¤{°TÔ5JÑ'JØ!%×!IÒ!IÑ!KÔ!KØ%)×%QÒ%QÑ%SÔ%Sð	
ñ 
ô 
ð 	
rM   c                 óø   — t          j         ¦   «         | _        t          | dd¦  «        dk    rL	 |                      d¦  «         n,# t          $ r t
                               dd¬¦  «         Y nw xY wd| _        dS dS )	aÓ  Stamp real inbound and restore lifecycle after a dormant wake.

        The watcher marks runtime status `draining` as it quiesces the relay, but
        dormancy is not the stop/restart drain path: the process remains alive and
        should present as running once real traffic wakes it and re-enters the
        gateway. Internal completion/replay events intentionally do not call this
        helper, so they do not keep an otherwise idle gateway awake.
        r¾  r@  r   Úrunningz$scale-to-zero: status restore failedTrß   N)rU   r½  rV   Ú_update_runtime_statusr2   r3   r4   r¾  rN  s    r>   Ú _scale_to_zero_note_real_inboundz.GatewayRunner._scale_to_zero_note_real_inboundh  sš   € õ !%¤	¡¤ˆÔÝ�4Ð8¸#Ñ>Ô>ÀÒBÐBðTØ×+Ò+¨IÑ6Ô6Ð6Ð6øÝð Tð Tð TÝ—’ÐCÈd�ÑSÔSÐSÐSÐSðTøøøà14ˆDÔ.Ð.Ð.ð CÐBs   ¯A Á&A.Á-A.c                 ór   — 	 ddl m} n# t          $ r Y dS w xY w| j                             |j        ¦  «        S )zHReturn the connected RELAY adapter, if any (the one go_dormant targets).r   ©rÄ  N)Úgateway.platforms.baserÄ  r2   r°  rv   ÚRELAY)r  rÄ  s     r>   Ú_relay_adapter_for_dormancyz)GatewayRunner._relay_adapter_for_dormancyy  sV   € ð	Ø7Ð7Ð7Ð7Ð7Ð7Ð7øÝð 	ð 	ð 	Ø�4�4ð	øøøàŒ}× Ò  ¤Ñ0Ô0Ð0s   ‚	 ‰
–Úintervalc              ƒ   óì  K  — t          j        t          |d¦  «        ¦  «        ƒ d{V —† | j        �rÁ	 t          j        |¦  «        ƒ d{V —† | j        sdS t	          j        ¦   «         | j        k     rŒI|                      ¦   «         sŒ^|                      ¦   «         }|€Œut          |dd¦  «        }t          |¦  «        sŒ–t                               d|                      ¦   «         ¦  «         	 |                      d¦  «         n,# t          $ r t                               dd¬¦  «         Y nw xY w	  |¦   «         }t          j        |¦  «        r|ƒ d{V —† n,# t          $ r t                               d	d¬¦  «         Y nw xY wt	          j        ¦   «         t#          |d
¦  «        z   | _        n;# t           j        $ r ‚ t          $ r t                               dd¬¦  «         Y nw xY w| j        �°¿dS dS )u>  Watch for idle and drive the relay dormant so the platform can suspend.

        Started ONLY when _scale_to_zero_should_arm() (opted in via the Labs
        HERMES_SCALE_TO_ZERO stamp + relay-only/absent messaging + a wakeUrl).
        On a sustained idle window it runs the DORMANT sequence (D12/F12/F14):
          - mark runtime status `draining` (composes with the existing state
            machine, Â§3.4(6); does NOT set _running=False),
          - relay adapter.go_dormant() â€” going_idle->ack + supervisor-preserving
            socket close (NOT disconnect(), NOT the run.py stop path),
          - deliberately NO mark_resume_pending (D13 â€” suspend preserves RAM).
        The process stays alive; the platform (Fly autostop:"suspend") suspends
        the now-traffic-idle machine and autostart wakes it on the wakeUrl poke,
        at which point the preserved reconnect supervisor re-dials and the
        connector drains the buffered backlog. After driving dormant we set a
        re-arm cooldown so a wake's drained backlog isn't immediately re-quiesced.
        r%   NÚ
go_dormantuu   scale-to-zero: gateway idle for >= %.0fs â€” going dormant (relay buffered, socket closed, awaiting platform suspend)Údrainingz!scale-to-zero: status mark failedTrß   z scale-to-zero: go_dormant failedg      N@z%scale-to-zero watcher iteration error)r  r–  r6   r’  rU   r¾  rÿ  r	  rV   r/  r3   rz  r×  r	  r2   r4   ÚiscoroutinerC  r›  )r  r		  r1  r	  r·  s        r>   Ú_scale_to_zero_watcherz$GatewayRunner._scale_to_zero_watcher�  st  è è € õ" Œm�C ¨$Ñ/Ô/Ñ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0Ð0ØŒmñ %	Uð$UÝ”m HÑ-Ô-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ø”}ð Ø�FÝ”9‘;”; Ô!CÒCÐCØØ×2Ò2Ñ4Ô4ð ØØ×:Ò:Ñ<Ô<�Ø�?ØÝ$ W¨l¸DÑAÔA�
Ý 
Ñ+Ô+ð ØÝ—’ðQà×<Ò<Ñ>Ô>ñô ð ð
UØ×/Ò/°
Ñ;Ô;Ð;Ð;øÝ ð Uð Uð UÝ—L’LÐ!DÈt�LÑTÔTÐTÐTÐTðUøøøðTØ'˜Z™\œ\�FÝÔ*¨6Ñ2Ô2ð %Ø$˜˜˜˜˜˜˜øøÝ ð Tð Tð TÝ—L’LÐ!CÈd�LÑSÔSÐSÐSÐSðTøøøõ
 6:´Y±[´[Å3ÀxÐQUÑCVÔCVÑ5V�Ô2Ð2øÝÔ)ð ð ð ØÝð Uð Uð UÝ—’ÐDÈt�ÑTÔTÐTÐTÐTðUøøøðI Œmñ %	Uð %	Uð %	Uð %	Uð %	Usw   ´!F/ ÁF/ Á4F/ Â	F/ Â  F/ Ã-F/ Ã/D ÄF/ Ä&D.Ä+F/ Ä-D.Ä.F/ Ä2&E ÅF/ Å&FÅ?F/ ÆFÆ,F/ Æ/5G'Ç&G'c                 ó   — | j         rdndS )NÚrestartÚshutdown©r,  rN  s    r>   Ú_status_action_labelz"GatewayRunner._status_action_labelº  s   € Ø Ô3ÐCˆyˆy¸ÐCrM   c                 ó   — | j         rdndS )NÚ
restartingúshutting downr	  rN  s    r>   Ú_status_action_gerundz#GatewayRunner._status_action_gerund½  s   € Ø#Ô6ÐKˆ|ˆ|¸OÐKrM   c                 ó"   — | j         o| j        dv S )N>   r™  Ústeer)r,  r%  rN  s    r>   Ú_queue_during_drain_enabledz)GatewayRunner._queue_during_drain_enabledÀ  s   € ð Ô&ÐV¨4Ô+@ÐDVÐ+VÐVrM   Úqueued_eventrr  c                 ó²   — |€dS t          |dd¦  «        }|€dS ||v r4|                      |¦  «        j        j                             |¦  «         dS |||<   dS )z6Append a /queue event to the FIFO chain for a session.Nr<  )rV   r/   rm  Úqueued_eventsr”   )r  r+   r	  r1  Úpending_slots        r>   Ú_enqueue_fifozGatewayRunner._enqueue_fifoÑ  s   € àˆ?ØˆFÝ˜wÐ(;¸TÑBÔBˆØÐØˆFØ˜,Ð&Ð&Ø×Ò Ñ,Ô,Ô9ÔG×NÒNØñô ð ð ð ð )5ˆL˜Ñ%Ð%Ð%rM   Úpending_eventc                 óð   — |                       |¦  «        }|r|j        j        nd}|s|S |                     d¦  «        }|€|S |�t	          |d¦  «        r||j        |<   n|                     d|¦  «         |S )aY  Promote the next overflow item after the slot was drained.

        Called at the drain site after _dequeue_pending_event consumed
        (or failed to consume) the slot.  If there's an overflow item:
          - When pending_event is None (slot was empty), return the
            overflow head as the new pending_event.
          - When pending_event already exists (slot was populated by an
            interrupt follow-up or similar), stage the overflow head in
            the slot so the NEXT recursion picks it up.
        Returns the (possibly updated) pending_event for drain to use.
        Nr   r<  )rA   rm  r	  rU  rá   r<  rš   )r  r+   r1  r 	  Ú_q_stateÚoverflowÚnext_queueds          r>   Ú_promote_queued_eventz#GatewayRunner._promote_queued_eventß  s—   € ð" ×+Ò+¨KÑ8Ô8ˆØ:BÐL�8Ô(Ô6Ð6ÈˆØð 	!Ø Ð Ø—l’l 1‘o”oˆØÐ ØÐØÐ¥7¨7Ð4GÑ#HÔ#HÐØ5@ˆGÔ% kÑ2Ð2ð �OŠO˜A˜{Ñ+Ô+Ð+ØÐrM   r   c                óž   — |                       |¦  «        }|rt          |j        j        ¦  «        nd}|�|t	          |di ¦  «        v r|dz  }|S )u=   Total pending /queue items for a session â€” slot + overflow.r   Nr<  r(   )rA   r7   rm  r	  rV   )r  r+   r1  r"	  rÓ   s        r>   Ú_queue_depthzGatewayRunner._queue_depthþ  s^   € à×+Ò+¨KÑ8Ô8ˆØ<DÐK•�HÔ)Ô7Ñ8Ô8Ð8È!ˆØÐ ;µ'¸'ÐCVÐXZÑ2[Ô2[Ð#[Ð#[Ø�Q‰JˆEØˆrM   Úevent_or_textc                 ól   — t          | d| ¦  «        pd}t          |¦  «                             d¦  «        S )zõReturn True for synthetic /goal continuation turns.

        Goal continuations are normal queued user-role events, so pause/clear
        must distinguish them from real user /queue messages before removing or
        suppressing them.
        rè   r®   z,[Continuing toward your standing goal]
Goal:)rV   rw   r!  )r(	  rè   s     r>   Ú_is_goal_continuation_eventz)GatewayRunner._is_goal_continuation_event  s5   € õ �} f¨mÑ<Ô<ÐBÀˆÝ�4‰yŒy×#Ò#Ð$SÑTÔTÐTrM   c                 ó¼  — d}|�t          |dd¦  «        nd}t          |t          ¦  «        rE|                     |¦  «        }|                      |¦  «        r|                     |d¦  «         |dz  }|                      |¦  «        }|r|j        j        ng }|rCg }|D ]2}	|                      |	¦  «        r|dz  }Œ| 	                    |	¦  «         Œ3||j        _        |S )a  Remove queued synthetic /goal continuations for one session.

        User-issued /goal pause/clear can race with a continuation already
        queued by the judge.  Remove only synthetic goal continuations while
        preserving normal /queue and user follow-up events.
        r   Nr<  r(   )
rV   rt   ru   rv   r*	  rU  rA   rm  r	  r”   )
r  r+   r1  Úremovedr	  r 	  r"	  r#	  Úkeptr	  s
             r>   Ú!_clear_goal_pending_continuationsz/GatewayRunner._clear_goal_pending_continuations  s
  € ð ˆØFMÐFY•w˜wÐ(;¸TÑBÔBÐBÐ_cˆÝ�l¥DÑ)Ô)ð 	Ø(×,Ò,¨[Ñ9Ô9ˆMØ×/Ò/°Ñ>Ô>ð Ø× Ò  ¨dÑ3Ô3Ð3Ø˜1‘�à×+Ò+¨KÑ8Ô8ˆØ:BÐJ�8Ô(Ô6Ð6ÈˆØð 	7ØˆDØ (ð .ð .�Ø×3Ò3°LÑAÔAð .Ø˜q‘L�G�Gà—K’K Ñ-Ô-Ð-Ð-Ø26ˆHÔ!Ô/ØˆrM   c                 óº   — |sdS 	 ddl m}  ||¬¦  «                             ¦   «         S # t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w)z@Best-effort fresh DB check before running a queued continuation.Fr   ©ÚGoalManagerr~  z2goal continuation: active-state recheck failed: %sN)Úhermes_cli.goalsr1	  Ú	is_activer2   r3   r4   )r  rN   r1	  r<   s       r>   Ú_goal_still_active_for_sessionz,GatewayRunner._goal_still_active_for_session,  s†   € àð 	Ø�5ð	Ø4Ð4Ð4Ð4Ð4Ð4Ø�;¨*Ð5Ñ5Ô5×?Ò?ÑAÔAÐAøÝð 	ð 	ð 	Ý�LŠLÐMÈsÑSÔSÐSØ�5�5�5�5�5øøøøð	øøøs   †#* ª
A´AÁAÚgateway_stater6  c                 ó‚   — 	 ddl m}  |||| j        |                      ¦   «         ¬¦  «         d S # t          $ r Y d S w xY w)Nr   ©Úwrite_runtime_status)r5	  r6  Úrestart_requestedÚactive_agents)Úgateway.statusr8	  r,  rÀ  r2   )r  r5	  r6  r8	  s       r>   r	  z$GatewayRunner._update_runtime_status7  s|   € ð		Ø;Ð;Ð;Ð;Ð;Ð;Ø Ð Ø+Ø'Ø"&Ô"9Ø"×5Ò5Ñ7Ô7ð	ñ ô ð ð ð øõ ð 	ð 	ð 	ØˆDˆDð	øøøs   ‚,0 °
>½>c                 ór   — 	 ddl m}  ||                      ¦   «         ¬¦  «         dS # t          $ r Y dS w xY w)u]  Persist the live in-flight agent count to ``gateway_state.json``.

        Called at every turn boundary (a running-agent slot is claimed or
        released) so the dashboard ``/api/status`` readout reflects in-flight
        gateway turns in near-real-time.  Without this the file is only
        rewritten on lifecycle transitions, so any ``active_agents`` read
        between transitions is stale (a turn could start and finish without the
        file ever moving).

        Deliberately passes ONLY ``active_agents`` â€” ``gateway_state`` and the
        other fields stay ``_UNSET`` so ``write_runtime_status``'s
        read-merge-write preserves the current lifecycle state (``running`` /
        ``draining`` / â€¦).  Passing ``gateway_state=None`` here would clobber it.
        Best-effort: a failed status write must never disrupt a turn.
        r   r7	  )r:	  N)r;	  r8	  rÀ  r2   )r  r8	  s     r>   Ú_persist_active_agentsz$GatewayRunner._persist_active_agentsC  sa   € ð 	Ø;Ð;Ð;Ð;Ð;Ð;Ø Ð ¨t×/FÒ/FÑ/HÔ/HÐIÑIÔIÐIÐIÐIøÝð 	ð 	ð 	ØˆDˆDð	øøøs   ‚$( ¨
6µ6c                 óª   — | j         rdS d| _         t                               d|                      ¦   «         ¦  «         |                      d¦  «         dS )u)  Begin external drain: stop accepting new turns, flip state.

        Idempotent â€” re-entering while already draining is a no-op beyond a
        best-effort status re-write. In-flight turns are NOT interrupted (the
        whole point is to let them finish); only NEW turns are refused.
        NTu€   External drain ENGAGED (.drain_request.json present) â€” refusing new turns; %d in-flight turn(s) will finish. Process stays up.r	  )r+  r3   rz  rÀ  r	  rN  s    r>   Ú_enter_external_drainz#GatewayRunner._enter_external_drainc  sc   € ð Ô&ð 	ØˆFØ&*ˆÔ#Ý�ŠðMà×#Ò#Ñ%Ô%ñ	
ô 	
ð 	
ð 	×#Ò# JÑ/Ô/Ð/Ð/Ð/rM   c                 óØ   — | j         sdS d| _         | j        s| j        st                               d¦  «         dS t                               d¦  «         |                      d¦  «         dS )u  Cancel external drain: revert state, re-accept new turns.

        Idempotent. Only reverts to ``running`` when we are actually mid-drain
        AND not also shutting down (a real shutdown ``_draining`` must win â€”
        never resurrect a stopping gateway to ``running``).
        NFug   External drain marker cleared during shutdown â€” not reverting to running (shutdown takes precedence).uk   External drain RELEASED (.drain_request.json removed) â€” re-accepting new turns; gateway_state -> running.r	  )r+  r*  r’  r3   rz  r	  rN  s    r>   Ú_exit_external_drainz"GatewayRunner._exit_external_drainw  s‹   € ð Ô*ð 	ØˆFØ&+ˆÔ#ØŒ>ð 	 ¤ð 	õ �KŠKð:ñô ð ð ˆFÝ�Šð@ñ	
ô 	
ð 	
ð 	×#Ò# IÑ.Ô.Ð.Ð.Ð.rM   ç      ð?c              ƒ   ó‚  K  — ddl m} | j        r¯	  |¦   «         r)|                      ¦   «          |                      ¦   «          n|                      ¦   «          nC# t          j        $ r ‚ t          $ r'}t           
                    d|d¬¦  «         Y d}~nd}~ww xY wt          j        |¦  «        ƒ d{V —† | j        °­dS dS )uN  Background task: reconcile gateway accept-state with the drain marker.

        Polls ``.drain_request.json`` (presence-based contract,
        gateway/drain_control.py). Marker present -> ``_enter_external_drain``;
        marker absent -> ``_exit_external_drain``. The 1s cadence bounds the
        observe-the-marker latency the live-validation gate checks (point a).
        Reconciles once at startup. A marker stamped with a PRIOR
        instantiation epoch (one that survived a machine restart on the durable
        HERMES_HOME volume â€” NS-570) is treated as absent by ``drain_requested``
        and is NOT honoured; only a marker from the current instantiation flips
        the gateway into drain. Best-effort: any tick error is logged and the
        loop continues (a transient stat() failure must not wedge the gateway).
        r   )Údrain_requestedz$Drain-control watcher tick error: %sTrß   N)Úgateway.drain_controlrD	  r’  r?	  r=	  rA	  r  r›  r2   r3   r4   r–  )r  r		  rD	  r<   s       r>   Ú_drain_control_watcherz$GatewayRunner._drain_control_watcher�  s  è è € ð 	:Ð9Ð9Ð9Ð9Ð9àŒmð 	*ðYØ"�?Ñ$Ô$ð 0Ø×.Ò.Ñ0Ô0Ð0ð ×/Ò/Ñ1Ô1Ð1Ð1à×-Ò-Ñ/Ô/Ð/øøÝÔ)ð ð ð ØÝð Yð Yð YÝ—’ÐCÀSÐSW�ÑXÔXÐXÐXÐXÐXÐXÐXøøøøðYøøøå”- Ñ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)ð Œmð 	*ð 	*ð 	*ð 	*ð 	*s   ‘AA ÁBÁ2BÂBr°  r±  r²  r³  c                óT   — 	 ddl m}  |||||¬¦  «         d S # t          $ r Y d S w xY w)Nr   r7	  )r�   r±  r²  r³  )r;	  r8	  r2   )r  r�   r±  r²  r³  r8	  s         r>   r¶  z-GatewayRunner._update_platform_runtime_status¯  sm   € ð		Ø;Ð;Ð;Ð;Ð;Ð;Ø Ð Ø!Ø-Ø%Ø+ð	ñ ô ð ð ð øõ ð 	ð 	ð 	ØˆDˆDð	øøøs   ‚ ™
'¦'r  c                ó°  — t          | di ¦  «                             |¦  «        }|€dS |                     d¦  «        rdS d|d<   |pd|d<   t          d¦  «        |d<   	 |                      |j        dd|d         ¬	¦  «         n# t
          $ r Y nw xY wt                               d
|j        |                     dd¦  «        |d         |j        ¦  «         dS )u"  Mark a queued platform as paused â€” keep it in ``_failed_platforms``
        but stop the reconnect watcher from hammering it.

        Used by ``/platform pause <name>`` for manual operator intervention.
        Paused platforms are surfaced in ``/platform list`` and resumed with
        ``/platform resume <name>``.  Note: the reconnect watcher does NOT
        auto-pause â€” retryable (network/DNS) failures keep retrying at the
        backoff cap indefinitely so a transient outage self-heals without
        manual intervention.
        r«  NÚpausedTz#auto-paused after repeated failuresÚpause_reasonÚinfrœ  r°  u¦   %s paused after %d consecutive failures (%s) â€” fix the underlying issue then run `/platform resume %s` to retry, or `hermes gateway restart` to restart the gateway.r›  r   )rV   rv   ri  r¶  r­   r2   r3   rã   )r  r�   r•  rz  s       r>   Ú_pause_failed_platformz$GatewayRunner._pause_failed_platformÇ  s  € õ �tÐ0°"Ñ5Ô5×9Ò9¸(ÑCÔCˆØˆ<ØˆFØ�8Š8�HÑÔð 	ØˆFØˆˆX‰Ø%ÐNÐ)Nˆˆ^Ñõ # 5™\œ\ˆˆ\Ñð	Ø×0Ò0Ø”Ø'ØØ" >Ô2ð	 1ñ ô ð ð øõ ð 	ð 	ð 	ØˆDð	øøøå�ŠðLð ŒN˜DŸHšH Z°Ñ3Ô3Ø�Ô  (¤.ñ	
ô 	
ð 	
ð 	
ð 	
s   Á$B Â
BÂBc                 ó�  — t          | di ¦  «                             |¦  «        }|€dS |                     d¦  «        sdS d|d<   |                     dd¦  «         d|d<   t          j        ¦   «         |d<   	 |                      |j        d	dd¬
¦  «         n# t          $ r Y nw xY wt           	                    d|j        ¦  «         dS )uÚ   Unpause a platform â€” reset its attempt counter and schedule an
        immediate retry.  Returns True if the platform was paused and is
        now queued; False if it wasn't paused (or wasn't in the queue).
        r«  NFrI	  rJ	  r   r›  rœ  r®  r°  u,   %s resumed â€” retrying on next watcher tickT)
rV   rv   rU  rU   r—  r¶  r­   r2   r3   rz  )r  r�   rz  s      r>   Ú_resume_paused_platformz%GatewayRunner._resume_paused_platformí  só   € õ
 �tÐ0°"Ñ5Ô5×9Ò9¸(ÑCÔCˆØˆ<Ø�5Ø�xŠx˜Ñ!Ô!ð 	Ø�5ØˆˆX‰Ø�Š� Ñ&Ô&Ð&ØˆˆZÑÝ!œ^Ñ-Ô-ˆˆ\Ñð	Ø×0Ò0Ø”Ø)ØØ"ð	 1ñ ô ð ð øõ ð 	ð 	ð 	ØˆDð	øøøå�ŠÐBÀHÄNÑSÔSÐSØˆts   Á7B Â
B#Â"B#c                  ó  — t          j        dd¦  «        } | sWt          ¦   «         }t          |                     dd¦  «        pd¦  «        } | s"t          t          |ddd¬¦  «        pd¦  «        } | sg S t          | ¦  «                             ¦   «         }|                     ¦   «         s
t          |z  }| 
                    ¦   «         st                               d|¦  «         g S 	 t          |dd¬	¦  «        5 }t          j        |¦  «        }d
d
d
¦  «         n# 1 swxY w Y   t!          |t"          ¦  «        st                               d|¦  «         g S |S # t$          $ r(}t                               d||¦  «         g cY d
}~S d
}~ww xY w)a\  Load ephemeral prefill messages from config or env var.
        
        Checks HERMES_PREFILL_MESSAGES_FILE env var first, then falls back to
        the top-level prefill_messages_file key in ~/.hermes/config.yaml.
        agent.prefill_messages_file is accepted as a legacy fallback.
        Relative paths are resolved from ~/.hermes/.
        ÚHERMES_PREFILL_MESSAGES_FILEr®   Úprefill_messages_filerµ   rx  z#Prefill messages file not found: %sr�  rQ  r‚  Nz3Prefill messages file must contain a JSON array: %sz+Failed to load prefill messages from %s: %s)r’   rÆ  rÏ  rw   rv   r!   r   Ú
expanduserÚis_absoluterl  r˜   r3   rã   r™  r3  Úloadrt   r½  r2   )Ú	file_pathrœ  r™   rˆ  rî  r¨  s         r>   r�  z$GatewayRunner._load_prefill_messages   s×  € õ ”IÐ<¸bÑAÔAˆ	Øð 	bÝ.Ñ0Ô0ˆCÝ˜CŸGšGÐ$;¸RÑ@Ô@ÐFÀBÑGÔGˆIØð bÝ¥¨¨WÐ6MÐWYÐ ZÑ ZÔ ZÐ `Ð^`ÑaÔa�	Øð 	ØˆIÝ�I‰Œ×)Ò)Ñ+Ô+ˆØ×ÒÑ!Ô!ð 	'Ý $Ñ&ˆDØ�{Š{‰}Œ}ð 	Ý�NŠNÐ@À$ÑGÔGÐGØˆIð		Ý�d˜C¨'Ð2Ñ2Ô2ð $°aÝ”y ‘|”|�ð$ð $ð $ñ $ô $ð $ð $ð $ð $ð $ð $øøøð $ð $ð $ð $å˜d¥DÑ)Ô)ð Ý—’ÐTÐVZÑ[Ô[Ð[Ø�	ØˆKøÝð 	ð 	ð 	Ý�NŠNÐHÈ$ÐPQÑRÔRÐRØˆIˆIˆIˆIˆIˆIøøøøð	øøøsH   Ã$E Ã6DÄE ÄDÄE ÄDÄ4E ÅE Å
FÅ FÅ=FÆFc                  ór   — ddl m}  t          j        dd¦  «        }|r|S t	          ¦   «         } | |¦  «        S )zÊLoad ephemeral system prompt from config or env var.

        Checks HERMES_EPHEMERAL_SYSTEM_PROMPT env var first, then
        ``display.personality`` / ``agent.system_prompt`` in config.yaml.
        r   )Ú+resolve_ephemeral_system_prompt_from_configÚHERMES_EPHEMERAL_SYSTEM_PROMPTr®   )r˜  rW	  r’   rÆ  rÏ  )rW	  Úpromptrœ  s      r>   r‚  z+GatewayRunner._load_ephemeral_system_prompt)   sR   € ð 	RÐQÐQÐQÐQÐQå”Ð;¸RÑ@Ô@ˆØð 	ØˆMÝ*Ñ,Ô,ˆØ:Ð:¸3Ñ?Ô?Ð?rM   )rA  r›  rœ  r›  rœ  c                ó”   — ddl m} d}t          | dd¦  «        }|rt          |||||¬¦  «        } |d|t	          |¦  «        ¦  «        S )u  Resolve model for this channel: channel_overrides else global default.

        Delegates the precedence rule to
        :func:`hermes_cli.model_switch.resolve_effective_model` (session
        override > channel override > global default) â€” the single owner
        shared with the API server, so the two surfaces cannot diverge
        again (see 7dd00bb47d).  This call site has no session tier: session
        /model overrides are applied later by
        ``_apply_session_model_override`` on the resolved runtime.
        r   )Úresolve_effective_modelNrz   rš  )Úhermes_cli.model_switchr[	  rV   r¥  r™  )	r  r�   r2  rA  r›  rœ  r[	  r|  rz   s	            r>   Ú_resolve_model_for_channelz(GatewayRunner._resolve_model_for_channel8   s€   € ð& 	DÐCÐCÐCÐCÐCàˆÝ˜˜x¨Ñ.Ô.ˆØð 	Ý,ØØØØ#Ø#ðñ ô ˆHð 'Ð&ØØÝ" ;Ñ/Ô/ñ
ô 
ð 	
rM   rš  c                ó¾   — t          | dd¦  «        }|r8t          |||||¬¦  «        }|r"|j        r|j        pd                     ¦   «         S t          | dd¦  «        pdS )aE  Ephemeral system prompt for this channel/thread.

        Uses ``channel_overrides`` when set, else the global gateway prompt.
        Legacy ``channel_prompts`` are applied separately via ``event.channel_prompt``
        in ``run_sync`` (adapter ``resolve_channel_prompt``), so they are not
        duplicated here.
        rz   Nrš  r®   rƒ  )rV   r¥  r¸   rx   )r  r�   r2  r›  rœ  rz   r|  s          r>   rŒ  z,GatewayRunner._get_system_prompt_for_channel]   s†   € õ ˜˜x¨Ñ.Ô.ˆØð 		>Ý,ØØØØ#Ø#ðñ ô ˆHð ð >˜HÔ2ð >Ø Ô.Ð4°"×;Ò;Ñ=Ô=Ð=Ý�tÐ7¸Ñ>Ô>ÐDÀ"ÐDrM   c                 óB   — ddl m} t          ¦   «         } ||| ¦  «        S )aÉ  Load reasoning effort from config.yaml, respecting per-model overrides.

        Thin wrapper over the shared chokepoint
        :func:`hermes_constants.resolve_reasoning_config` (per-model override >
        global ``agent.reasoning_effort``; YAML boolean False = disabled).
        Closes #21256.

        Args:
            model: The effective model for the calling session. When empty,
                   the config's ``model.default`` is used.
        r   )Úresolve_reasoning_config)r¶  r`	  rÏ  )r  r`	  rœ  s      r>   r„  z$GatewayRunner._load_reasoning_configy   s4   € ð 	>Ð=Ð=Ð=Ð=Ð=Ý*Ñ,Ô,ˆØ'Ð'¨¨UÑ3Ô3Ð3rM   Úraw_argsc                 ó°  — ddl }t          | pd¦  «                             ¦   «                              dd¦  «        }|sdS 	  |j        |¦  «        }n$# t
          $ r |                     ¦   «         }Y nw xY wd}g }|D ] }|dk    rd	}Œ|                     |¦  «         Œ!d
                     |¦  «                             ¦   «                              ¦   «         |fS )zÕParse `/reasoning` args into `(value, persist_global)`.

        `/reasoning <level>` is session-scoped by default. `--global` may be
        supplied in any position to persist the change to config.yaml.
        r   Nr®   u   â€”z--)r®   FFz--globalTr™  )	Úshlexrw   rx   rl  re   rj  r”   rf   ry   )ra	  rc	  rè   ÚtokensÚpersist_globalÚvalue_tokensrÄ  s          r>   Ú_parse_reasoning_command_argsz+GatewayRunner._parse_reasoning_command_argsŠ   sþ   € ð 	ˆˆˆå�8�>˜rÑ"Ô"×(Ò(Ñ*Ô*×2Ò2°5¸$Ñ?Ô?ˆØð 	Ø�9ð	"Ø �U”[ Ñ&Ô&ˆFˆFøÝð 	"ð 	"ð 	"Ø—Z’Z‘\”\ˆFˆFˆFð	"øøøð ˆØˆØð 	+ð 	+ˆEØ˜
Ò"Ð"Ø!%��à×#Ò# EÑ*Ô*Ð*Ð*Ø�xŠx˜Ñ%Ô%×+Ò+Ñ-Ô-×3Ò3Ñ5Ô5°~ÐEÐEs   ÁA ÁA3Á2A3rì  c                óì   — |}|s+|�)	 |                       |¦  «        }n# t          $ r d}Y nw xY w|r/|                      |¦  «        }|�|j        j        �|j        j        S |                      |¦  «        S )uá  Resolve reasoning effort for a session, honoring session overrides.

        Priority: session-scoped ``/reasoning --session`` override >
        per-model override (``agent.reasoning_overrides``) > global
        ``agent.reasoning_effort``. ``model`` should be the session's
        *effective* model (session ``/model`` override included) so
        per-model overrides track what the session actually runs â€” when
        empty, the config's ``model.default`` is used.
        N)rA  r2   rA   rm  Úreasoning_overrider„  )r  r(  r+   r  rv  Ú_r_states         r>   r�  z/GatewayRunner._resolve_session_reasoning_config¤   sª   € ð   +ÐØ#ð 	,¨Ð(:ð,Ø'+×'CÒ'CÀFÑ'KÔ'KÐ$Ð$øÝð ,ð ,ð ,Ø'+Ð$Ð$Ð$ð,øøøð  ð 	@Ø×/Ò/Ð0DÑEÔEˆHØÐ#¨Ô(=Ô(PÐ(\ØÔ,Ô?Ð?Ø×*Ò*¨5Ñ1Ô1Ð1ó   ˆ ž-¬-r  c                 ón   — |sdS |€dnt          |¦  «        |                      |¦  «        j        _        dS )z3Set or clear the session-scoped reasoning override.N)ru   r/   rm  ri	  )r  r+   r  s      r>   Ú_set_session_reasoning_overridez-GatewayRunner._set_session_reasoning_overrideÁ   sG   € ð ð 	ØˆFð
 %Ð,ˆDˆDµ$Ð7GÑ2HÔ2Hð 	×Ò˜KÑ(Ô(Ô5ÔHÐHÐHrM   c                 óø   — |}|s+|�)	 |                       |¦  «        }n# t          $ r d}Y nw xY w|r6|                      |¦  «        }|�|j        j        t
          ur|j        j        S |                      ¦   «         S )u  Resolve the effective service tier for a session.

        A session-scoped /fast override wins over the config default. The
        override dict stores "priority" or None (explicit normal), so key
        presence â€” not value truthiness â€” decides whether it applies.
        N)rA  r2   rA   rm  Úservice_tier_overrideÚ_SERVICE_TIER_UNSETr…  )r  r(  r+   rv  Ú_t_states        r>   r‘  z+GatewayRunner._resolve_session_service_tierÐ   sµ   € ð  +ÐØ#ð 	,¨Ð(:ð,Ø'+×'CÒ'CÀFÑ'KÔ'KÐ$Ð$øÝð ,ð ,ð ,Ø'+Ð$Ð$Ð$ð,øøøð  ð 	CØ×/Ò/Ð0DÑEÔEˆHàÐ$ØÔ)Ô?Ý*ð+ð +ð  Ô,ÔBÐBØ×&Ò&Ñ(Ô(Ð(rk	  r4  c                 ó^   — |sdS |rt           n||                      |¦  «        j        _        dS )zÎSet or clear the session-scoped /fast override.

        ``service_tier`` is "priority" or None (explicit normal). Pass
        ``clear=True`` to remove the override entirely (fall back to config).
        N)rp	  r/   rm  ro	  )r  r+   r  r4  s       r>   Ú"_set_session_service_tier_overridez0GatewayRunner._set_session_service_tier_overrideì   s@   € ð ð 	ØˆFð $)Ð:ÕÐ¨lð 	×Ò˜KÑ(Ô(Ô5ÔKÐKÐKrM   c                  ó  — t          ¦   «         } t          t          | ddd¬¦  «        pd¦  «                             ¦   «         }|                     ¦   «         }|r|dv rdS |dv rdS t
                               d	|¦  «         dS )
a  Load Priority Processing setting from config.yaml.

        Reads agent.service_tier from config.yaml. Accepted values mirror the CLI:
        "fast"/"priority"/"on" => "priority", while "normal"/"off" disables it.
        Returns None when unset or unsupported.
        rµ   r  r®   rx  >   r  rô  ÚnormalrJ  ÚstandardN>   rp   ÚfastÚpriorityrx	  z#Unknown service_tier '%s', ignoring)rÏ  rw   r!   rx   ry   r3   rã   )rœ  rx  r­   s      r>   r…  z GatewayRunner._load_service_tier!  sŽ   € õ +Ñ,Ô,ˆÝ•'˜#˜w¨ÀÐCÑCÔCÐIÀrÑJÔJ×PÒPÑRÔRˆà—	’	‘”ˆØð 	˜Ð!QÐQÐQØ�4ØÐ.Ð.Ð.Ø�:Ý�ŠÐ<¸cÑBÔBÐBØˆtrM   c                  ó^   — t          ¦   «         } t          t          | dd¦  «        d¬¦  «        S )z<Load show_reasoning toggle from config.yaml display section.rD  Úshow_reasoningFrx  )rÏ  r{  r!   ©rœ  s    r>   r†  z"GatewayRunner._load_show_reasoning!  s9   € õ +Ñ,Ô,ˆÝÝ�C˜Ð$4Ñ5Ô5Øð
ñ 
ô 
ð 	
rM   c                  óD  — t          j        dd¦  «                             ¦   «                              ¦   «         } | sTt	          ¦   «         }t          t          |ddd¬¦  «        pd¦  «                             ¦   «                              ¦   «         } | dk    rdS | dk    rdS dS )	z<Load gateway drain-time busy-input behavior from config/env.r(  r®   rD  r'  rx  r™  r	  r$  )r’   rÆ  rx   ry   rÏ  rw   r!   )rf  rœ  s     r>   rˆ  z#GatewayRunner._load_busy_input_mode!  s    € õ ŒyÐ9¸2Ñ>Ô>×DÒDÑFÔF×LÒLÑNÔNˆØð 	eÝ.Ñ0Ô0ˆCÝ•w˜s IÐ/@È"ÐMÑMÔMÐSÐQSÑTÔT×ZÒZÑ\Ô\×bÒbÑdÔdˆDØ�7Š?ˆ?Ø�7Ø�7Š?ˆ?Ø�7Øˆ{rM   c                  ó†  — t          j        dd¦  «                             ¦   «                              ¦   «         } | sTt	          ¦   «         }t          t          |ddd¬¦  «        pd¦  «                             ¦   «                              ¦   «         } | dk    rdS | dk    rdS t                               ¦   «         }|dk    rdndS )aÝ  Resolve normal busy TEXT follow-up behavior.

        ``busy_input_mode`` is the single source of truth (default
        ``interrupt``). The legacy ``busy_text_mode`` knob is honored only
        when a user explicitly set it, so existing queue setups keep
        working; new installs follow ``busy_input_mode``. Returns one of
        ``interrupt`` | ``queue`` (``steer`` is handled upstream by
        ``busy_input_mode`` and maps to non-queue text handling here).
        r*  r®   rD  r)  rx  r$  r™  )	r’   rÆ  rx   ry   rÏ  rw   r!   r
  rˆ  )Úlegacyrœ  Ú
input_modes      r>   r‰  z"GatewayRunner._load_busy_text_mode*!  sÄ   € õ ”Ð:¸BÑ?Ô?×EÒEÑGÔG×MÒMÑOÔOˆØð 	fÝ.Ñ0Ô0ˆCÝ�  iÐ1AÈ2ÐNÑNÔNÐTÐRTÑUÔU×[Ò[Ñ]Ô]×cÒcÑeÔeˆFØ�[Ò Ð Ø�;Ø�WÒÐØ�7å"×8Ò8Ñ:Ô:ˆ
Ø$¨Ò/Ð/ˆwˆw°[Ð@rM   c                  ó¦  — t          j        dd¦  «                             ¦   «         } | sBt          ¦   «         }t	          t          |ddd¬¦  «        pd¦  «                             ¦   «         } t          | ¦  «        }| rT|t          k    rI	 t          | ¦  «         n8# t          t          f$ r$ t                               d| t          ¦  «         Y nw xY w|S )z<Load graceful gateway restart/stop drain timeout in seconds.r#  r®   rµ   r"  rx  z7Invalid restart_drain_timeout '%s', using default %.0fs)r’   rÆ  rx   rÏ  rw   r!   r„  r€  ri  rw  rj  r3   rã   )rx  rœ  r­   s      r>   rŠ  z)GatewayRunner._load_restart_drain_timeoutB!  sé   € õ ŒiÐ6¸Ñ;Ô;×AÒAÑCÔCˆØð 	`Ý.Ñ0Ô0ˆCÝ•g˜c 7Ð,CÈRÐPÑPÔPÐVÐTVÑWÔW×]Ò]Ñ_Ô_ˆCÝ+¨CÑ0Ô0ˆØð 	�5ÕAÒAÐAðÝ�c‘
”
�
�
øÝ�zÐ*ð ð ð Ý—’ØMØÝ9ñô ð ð ð ðøøøð ˆs   Â	B Â2CÃCc                  óÂ  — t          j        d¦  «        } | �(t          | ¦  «                             ¦   «         dk    r| }n!t	          ¦   «         }t          |ddd¬¦  «        }t          |¦  «        }|�nt          |¦  «                             ¦   «         dk    rI	 t          |¦  «         n8# t          t          f$ r$ t                               d|t          ¦  «         Y nw xY w|S )z?Load in-band restart wait-for-idle timeout in seconds (#77184).Ú!HERMES_RESTART_AFTER_TURN_TIMEOUTNr®   rµ   Úrestart_after_turn_timeoutrx  z<Invalid restart_after_turn_timeout '%s', using default %.0fs)r’   rÆ  rw   rx   rÏ  r!   rƒ  ri  rw  rj  r3   rã   r  )Úenv_rawrx  rœ  r­   s       r>   r‹  z.GatewayRunner._load_restart_after_turn_timeoutU!  sï   € õ ”)Ð?Ñ@Ô@ˆØÐ¥3 w¡<¤<×#5Ò#5Ñ#7Ô#7¸2Ò#=Ð#=Ø!ˆCˆCå.Ñ0Ô0ˆCÝ˜#˜wÐ(DÈdÐSÑSÔSˆCÝ0°Ñ5Ô5ˆð ˆ?�s 3™xœxŸ~š~Ñ/Ô/°2Ò5Ð5ðÝ�c‘
”
�
�
øÝ�zÐ*ð ð ð Ý—’ØRØÝ>ñô ð ð ð ðøøøð ˆs   ÂB' Â'2CÃCc                  ó@  — t          j        dd¦  «        } | s9t          ¦   «         }t          |dd¦  «        }|du rd} n|dvrt	          |¦  «        } | pd                     ¦   «                              ¦   «         } h d	£}| |vrt                               d
| ¦  «         dS | S )u�  Load background process notification mode from config or env var.

        Modes:
          - ``all``    â€” push running-output updates *and* the final message (default)
          - ``result`` â€” only the final completion message (regardless of exit code)
          - ``error``  â€” only the final message when exit code is non-zero
          - ``off``    â€” no watcher messages at all
        ÚHERMES_BACKGROUND_NOTIFICATIONSr®   rD  Ú background_process_notificationsFr  >   Nr®   r�  >   r�  r  rP   r·  zBUnknown background_process_notifications '%s', defaulting to 'all')	r’   rÆ  rÏ  r!   rw   rx   ry   r3   rã   )rf  rœ  rx  Úvalids       r>   Ú#_load_background_notifications_modez1GatewayRunner._load_background_notifications_model!  sÀ   € õ ŒyÐ:¸BÑ?Ô?ˆØð 	 Ý.Ñ0Ô0ˆCÝ˜#˜yÐ*LÑMÔMˆCØ�eˆ|ˆ|Ø��Ø˜JÐ&Ð&Ý˜3‘x”x�Ø�˜×$Ò$Ñ&Ô&×,Ò,Ñ.Ô.ˆØ1Ð1Ð1ˆØ�uÐÐÝ�NŠNØTØñô ð ð �5ØˆrM   c                  ót   — 	 t          ¦   «         } |                      di ¦  «        pi S # t          $ r Y nw xY wi S )z>Load OpenRouter provider routing preferences from config.yaml.Úprovider_routing)rÏ  rv   r2   r{	  s    r>   rŒ  z$GatewayRunner._load_provider_routingˆ!  sS   € ð	õ /Ñ0Ô0ˆCØ—7’7Ð-¨rÑ2Ô2Ð8°bÐ8øÝð 	ð 	ð 	ØˆDð	øøøàˆ	s   ‚%( ¨
5´5c                  ól   — 	 t          ¦   «         } t          | ¦  «        }|r|S n# t          $ r Y nw xY wdS )zúLoad fallback provider chain from config.yaml.

        Returns the merged effective chain from ``fallback_providers`` plus any
        legacy ``fallback_model`` entries. ``fallback_providers`` stays first
        when both keys are present.
        N)rÏ  r"   r2   )rœ  Úfbs     r>   r�  z"GatewayRunner._load_fallback_model”!  sX   € ð	õ /Ñ0Ô0ˆCÝ# CÑ(Ô(ˆBØð Ø�	ðøåð 	ð 	ð 	ØˆDð	øøøàˆts   ‚ $ ¤
1°1c                 óä  — 	 ddl m} t          dz  }|                     ¦   «         sd| _        | j        S  ||¦  «        }	 ddlm}  |j        |¦  «        }n# t          $ r Y nw xY w	 ddl m	}  ||¦  «        }t          |t          ¦  «        r|}n# t          $ r Y nw xY wn3# t          $ r& t                               dd¬	¦  «         | j        cY S w xY wt          |¦  «        pd| _        | j        S )
aÐ  Re-read fallback_providers from disk for the next agent create/reuse.

        Cron already does this per job via ``get_fallback_chain``; the gateway
        previously froze ``self._fallback_model`` at process start, so a chain
        configured (or changed) after ``hermes gateway`` was running never
        reached messaging sessions even though the same process's cron jobs
        fell back correctly. Fixes #60955.

        A TRANSIENT read/parse failure (user mid-edit of config.yaml with a
        non-atomic write) keeps the last known-good chain instead of wiping a
        cached agent's working fallback for that turn.  Only a successful read
        that genuinely lacks the key clears the chain.
        r   )rŽ  r‹  Nr�  r–  zRfallback_providers refresh: config.yaml read failed; keeping last known-good chainTrß   )r˜  rŽ  rl  r˜   rŽ  r™  r�  rš  r2   r�  rt   ru   r3   r4   r"   )r  rŽ  Úcfg_pathrœ  r�  r�  r—  s          r>   r£  z%GatewayRunner._refresh_fallback_model§!  sr  € ð	(Ø>Ð>Ð>Ð>Ð>Ð>Ý# mÑ3ˆHØ—?’?Ñ$Ô$ð ,Ø'+�Ô$ØÔ+Ð+ð
 'Ð& xÑ0Ô0ˆCðØ4Ð4Ð4Ð4Ð4Ð4Ø9�mÔ9¸#Ñ>Ô>��øÝð ð ð Ø�ðøøøðØ>Ð>Ð>Ð>Ð>Ð>Ø+Ð+¨CÑ0Ô0�Ý˜h­Ñ-Ô-ð #Ø"�CøøÝð ð ð Ø�ðøøøøøåð 	(ð 	(ð 	(å�LŠLð0Ø:>ð ñ ô ð ð Ô'Ð'Ð'Ð'ð	(øøøõ  2°#Ñ6Ô6Ð>¸$ˆÔØÔ#Ð#s^   ‚1B" ´B" Á A ÁB" Á
A$Á!B" Á#A$Á$B" Á((B ÂB" Â
BÂB" ÂBÂB" Â"-CÃCÚchainc                 ó¬  — | €dS t          |pg ¦  «        }t          | dd¦  «        pd}t          | dd¦  «        r|t          j        ¦   «         k    rdS t          t          | dg ¦  «        pg ¦  «        }|| _        |r|d         nd| _        t          | dd¦  «        sd| _        ||k    r)t          | dd¦  «        }|r|                     ¦   «          dS dS dS )u¸  Keep a cached agent's fallback chain aligned with current config.

        Skips rewrite while a cooldown is holding the agent on an already-
        activated fallback provider â€” ``restore_primary_runtime`` owns that
        turn-scoped lifecycle. When primary is active (or cooldown expired),
        replace the chain so mid-uptime ``fallback_providers`` edits take
        effect without requiring a gateway restart (#60955).
        NÚ_rate_limited_untilr   r…  FÚ_fallback_chainÚ_unavailable_fallback_keys)r½  rV   rU   r—  r“	  rŽ  Ú_fallback_indexr4  )rµ   r�	  Ú	new_chainÚrate_limited_untilÚ	old_chainÚunavailables         r>   r¢  z,GatewayRunner._apply_fallback_chain_to_agentÖ!  s  € ð ˆ=ØˆFÝ˜˜ "Ñ%Ô%ˆ	Ý$ UÐ,AÀ1ÑEÔEÐJÈÐå�EÐ0°%Ñ8Ô8ð	à"¥T¤^Ñ%5Ô%5Ò5Ð5àˆFÝ� Ð(9¸2Ñ>Ô>ÐDÀ"ÑEÔEˆ	Ø )ˆÔØ09Ð C 	¨!¤ ¸tˆÔÝ�uÐ3°UÑ;Ô;ð 	&Ø$%ˆEÔ!ð ˜	Ò!Ð!Ý! %Ð)EÀtÑLÔLˆKØð $Ø×!Ò!Ñ#Ô#Ð#Ð#Ð#ð "Ð!ð$ð $rM   c                 ó>   — d„ |                       ¦   «         D ¦   «         S )Nc                 ó,   — i | ]\  }}|t           u¯||“ŒS rN  )rž  )rb   r+   rµ   s      r>   rê  z:GatewayRunner._snapshot_running_agents.<locals>.<dictcomp>û!  s4   € ð 
ð 
ð 
á"�˜UØÕ3Ð3Ð3ð ˜à3Ð3Ð3rM   )rO  rN  s    r>   Ú_snapshot_running_agentsz&GatewayRunner._snapshot_running_agentsú!  s/   € ð
ð 
à&*×&?Ò&?Ñ&AÔ&Að
ñ 
ô 
ð 	
rM   c                 óf   — 	 ddl m}  |t          | dd¦  «        ¦  «        S # t          $ r Y dS w xY w)z:Return the configured active chat session cap, if enabled.r   )Úresolve_max_concurrent_sessionsrz   N)Úhermes_cli.active_sessionsrž	  rV   r2   )r  rž	  s     r>   Ú_get_max_concurrent_sessionsz*GatewayRunner._get_max_concurrent_sessions"  sX   € ð	ØRÐRÐRÐRÐRÐRà2Ð2µ7¸4ÀÈ4Ñ3PÔ3PÑQÔQÐQøÝð 	ð 	ð 	Ø�4�4ð	øøøs   ‚" ¢
0¯0c                 ó¼   — |                       ¦   «         }|€dS |                      |¦  «        rdS |                      ¦   «         }||k     rdS ddlm}  |||¦  «        S )zKReturn a user-facing rejection when starting a new session exceeds the cap.Nr   )Úactive_session_limit_message)r 	  rK  r¼  rŸ	  r¢	  )r  r+   Úmax_sessionsrË  r¢	  s        r>   Ú_active_session_limit_messagez+GatewayRunner._active_session_limit_message
"  s   € à×8Ò8Ñ:Ô:ˆØÐØ�4Ø×#Ò# KÑ0Ô0ð 	Ø�4Ø×0Ò0Ñ2Ô2ˆØ˜,Ò&Ð&Ø�4ØKÐKÐKÐKÐKÐKà+Ð+¨L¸,ÑGÔGÐGrM   c                 ó–  — |                       |¦  «        rdS |                      |¦  «        }|�d|fS 	 ddlm} |r|j        r|j        j        nd} ||d|› �t          | dd¦  «        |t          |dd	¦  «        pd	t          |d
d	¦  «        pd	dœ¬¦  «        S # t          $ r&}t           	                    d|¦  «         Y d}~dS d}~ww xY w)zAClaim a cross-process active-session slot for a new gateway turn.rT  Nr   )Útry_acquire_active_sessionr9   úgateway:rz   r2  r®   r¹  )r�   r2  r¹  )rN   Úsurfacerz   r¯   z'Failed to claim active session slot: %s)
rK  r¤	  rŸ	  r¦	  r�   r­   rV   r2   r3   rã   )r  r+   r(  Úlocal_limit_messager¦	  r�   r<   s          r>   Ú_claim_active_session_slotz(GatewayRunner._claim_active_session_slot"  s'  € ð ×#Ò# KÑ0Ô0ð 	Ø�:Ø"×@Ò@ÀÑMÔMÐØÐ*ØÐ,Ð,Ð,ð	ØMÐMÐMÐMÐMÐMà06ÐY¸6¼?ÐY�v”Ô,Ð,ÐPYˆHØ-Ð-Ø&Ø- 8Ð-Ð-Ý˜t X¨tÑ4Ô4à (Ý& v¨y¸"Ñ=Ô=ÐCÀÝ& v¨y¸"Ñ=Ô=ÐCÀðð ð		ñ 	ô 	ð 	øõ ð 	ð 	ð 	Ý�NŠNÐDÀcÑJÔJÐJØ�:�:�:�:�:øøøøð	øøøs   ´A#B Â
CÂ"CÃCÚrunning_agentc                 óH  — | �	| t           u rdS t          | dd¦  «        }t          |t          t          t
          f¦  «        sdS |sdS t          | dd¦  «        }	 |�)|5  t          |¦  «        cddd¦  «         S # 1 swxY w Y   t          |¦  «        S # t          $ r Y dS w xY w)aL  Return True when *running_agent* is currently driving subagents
        via the ``delegate_task`` tool.

        Background (#30170): ``AIAgent.interrupt()`` cascades through the
        parent's ``_active_children`` list and calls ``interrupt()`` on
        every child synchronously, which aborts in-flight subagent work
        and produces a fallback cascade with no actionable signal.
        Demoting ``busy_input_mode='interrupt'`` to ``queue`` semantics
        whenever this helper returns True protects subagent work from
        conversational follow-ups while leaving the explicit ``/stop``
        path (which goes through ``_interrupt_and_clear_session``)
        untouched. Safe-by-default: returns False on any attribute or
        lock error so a missing/broken parent never blocks the existing
        interrupt path.
        NFÚ_active_childrenÚ_active_children_lock)rž  rV   rt   r½  r€  r•   rº   r2   )r«	  ÚchildrenÚlocks      r>   Ú_agent_has_active_subagentsz)GatewayRunner._agent_has_active_subagents5"  s  € ð" Ð  MÕ5LÐ$LÐ$LØ�5Ý˜=Ð*<¸dÑCÔCˆõ ˜(¥T­5µ#Ð$6Ñ7Ô7ð 	Ø�5Øð 	Ø�5Ý�}Ð&=¸tÑDÔDˆð	ØÐØð *ð *Ý ™>œ>ð*ð *ð *ð *ñ *ô *ð *ð *ð *ð *ð *ð *øøøð *ð *ð *ð *å˜‘>”>Ð!øÝð 	ð 	ð 	Ø�5�5ð	øøøs6   ÁB ÁA9Á,B Á9A=Á=B Â A=ÂB Â
B!Â B!c              ƒ   óL  K  — t          | dd¦  «        }|r|€dS 	 t          j        | j        ||¦  «        ƒ d{V —†}nA# t          t
          f$ r Y dS t          $ r! t                               d|d¬¦  «         Y dS w xY w|sdS t          | dd¦  «        }|€dS t          |d|¦  «        }	 t          j        |j	        t          |¦  «        ¦  «        ƒ d{V —†}t          |¦  «        S # t          t
          f$ r Y dS t          $ r! t                               d	|d¬¦  «         Y dS w xY w)
u�  Return True when a compression lock is held for this session's id.

        Context compression is interrupt-protected (#23975) but gateway
        ``interrupt`` busy-input mode can still start a follow-up turn against
        the pre-rotation parent while compression is mid-flight, producing
        orphaned compression siblings (#56391). Callers demote interrupt to
        queue when this returns True.

        Both blocking sources â€” the ``session_store`` lock + JSON load, and the
        SQLite ``get_compression_lock_holder`` SELECT â€” are offloaded to a
        worker thread so a large state.db never freezes the event loop (#5).
        r›  NFz”Compression in-flight check failed while reading session %s; treating compression as active to avoid interrupting a possible parent-session rotationTrß   rR   rS   z¤Compression in-flight check failed while reading lock holder for session %s; treating compression as active to avoid interrupting a possible parent-session rotation)rV   r  r  Ú#_lookup_session_id_under_store_lockÚAttributeErrorrw  r2   r3   rã   Úget_compression_lock_holderrw   rº   )r  r+   r›  rN   rX   Úraw_dbÚholders          r>   Ú"_session_has_compression_in_flightz0GatewayRunner._session_has_compression_in_flight["  sÐ  è è € õ    o°tÑ<Ô<ˆØð 	˜mÐ3Ø�5ð	Ý&Ô0ØÔ8¸-Èñ ô  ð ð ð ð ð ð ˆJˆJøõ ¥	Ð*ð 	ð 	ð 	Ø�5�5Ýð 	ð 	ð 	Ý�NŠNð*ð Øð ñ ô ð ð �4�4ð	øøøð ð 	Ø�5Ý˜T =°$Ñ7Ô7ˆ
ØÐØ�5Ý˜ U¨JÑ7Ô7ˆð	Ý"Ô,ØÔ2µC¸
±O´Oñô ð ð ð ð ð ð ˆFõ ˜‘<”<ÐøÝ¥	Ð*ð 	ð 	ð 	Ø�5�5Ýð 	ð 	ð 	Ý�NŠNðBð Øð ñ ô ð ð �4�4ð	øøøs-   ›!= ½A;Á&A;Á:A;Â);C% Ã%D#Ã9&D#Ä"D#c                 óÆ   — | j         5  |                      ¦   «          | j                             |¦  «        }ddd¦  «         n# 1 swxY w Y   |�t	          |dd¦  «        ndS )zISync helper run in the thread pool: read session_id under the store lock.NrN   )Ú_lockÚ_ensure_loaded_lockedrÄ  rv   rV   )r›  r+   r®  s      r>   r³	  z1GatewayRunner._lookup_session_id_under_store_lock‘"  s¨   € ð Ô ð 	<ð 	<Ø×/Ò/Ñ1Ô1Ð1Ø!Ô*×.Ò.¨{Ñ;Ô;ˆEð	<ð 	<ð 	<ñ 	<ô 	<ð 	<ð 	<ð 	<ð 	<ð 	<ð 	<øøøð 	<ð 	<ð 	<ð 	<ð 6;Ð5F�w�u˜l¨DÑ1Ô1Ð1ÈDÐPs   ˆ/AÁAÁ
Aé    rÖ  c                 ó®  — |                       |j        ¦  «        }|sd S t          |dd ¦  «        }t          |t          ¦  «        r|                     |¦  «        nd }|��t          |dd ¦  «        t          j        k    sQ|j        t          j        k    s<t          t          |dd ¦  «        ¦  «        st          t          |dd ¦  «        ¦  «        r-t          |j        |||j        t          j        k    ¬¦  «         d S |                      ||¬¦  «        | j        k    r#t                               d|| j        ¦  «         d S |                      |||¦  «         d S )Nr<  rÚ  rì  ©Ú
merge_textr   uJ   Dropping busy-mode follow-up for session %s â€” pending queue at cap (%d).)r@  r(  rV   rt   ru   rv   rs  rÛ  rÚ  rº   rw  r<  ÚTEXTr'	  Ú_BUSY_QUEUE_MAX_PENDINGr3   rã   r	  )r  r+   rÖ  r1  r	  r·  s         r>   Ú_queue_or_replace_pending_eventz-GatewayRunner._queue_or_replace_pending_event¢"  sk  € Ø×*Ò*¨5¬<Ñ8Ô8ˆØð 	ØˆFõ ˜wÐ(;¸TÑBÔBˆÝ4>¸|ÍTÑ4RÔ4RÐ\�<×#Ò# KÑ0Ô0Ð0ÐX\ˆØÐÝ�H˜n¨dÑ3Ô3µ{Ô7HÒHÐHØÔ!¥[Ô%6Ò6Ð6Ý•G˜H l°DÑ9Ô9Ñ:Ô:ð 7å•G˜E <°Ñ6Ô6Ñ7Ô7ð 7õ
 (ØÔ)ØØØ Ô-µÔ1AÒAð	ñ ô ð ð ˆFà×Ò˜[°'ÐÑ:Ô:¸dÔ>ZÒZÐZÝ�NŠNØ\ØØÔ,ñô ð ð
 ˆFà×Ò˜;¨¨wÑ7Ô7Ð7Ð7Ð7rM   c              ƒ   ó"  K  — |j         pd                     ¦   «         }|                      |¦  «        s|S |                      |j        ¦  «        }|                      |||j        |d¬¦  «        ƒ d{V —†\  }}|s|S |p|                     ¦   «         S )uµ  Return steerable text for a busy follow-up, transcribing voice first.

        Fresh and queued voice messages reach the normal inbound STT pipeline,
        but successful steer messages intentionally bypass that queue. Without
        preprocessing here, a media-only voice follow-up has an empty text
        payload and steer mode silently degrades to queue mode.

        Audio file attachments remain files; only voice-message media follows
        the automatic STT contract used by ``_prepare_inbound_message_text``.
        If transcription fails, preserve any caption and let the existing
        steer fallback handle an otherwise empty event without losing it.

        Routes through ``_transcribe_and_echo_pending_voice`` â€” the single
        out-of-band transcription choke point shared with the interrupt
        monitor and the pending-drain path â€” so the STT call is made at most
        once per platform message (cached on the event) and the transcript
        echo respects the count-based ledger.  If steering later falls back
        to queue mode, the drain path reuses the cached transcript instead of
        paying for a second STT call or re-echoing the same line.
        r®   z
Busy-steer©Úlog_contextN)rè   rx   Ú_pending_event_audio_pathsr@  r(  Ú"_transcribe_and_echo_pending_voice)r  rÖ  rè   r1  Úenriched_textÚsuccessful_transcriptss         r>   Ú_prepare_busy_steer_textz&GatewayRunner._prepare_busy_steer_textÉ"  sÆ   è è € ð* ”
Ð ˜b×'Ò'Ñ)Ô)ˆØ×.Ò.¨uÑ5Ô5ð 	ØˆKà×*Ò*¨5¬<Ñ8Ô8ˆØ6:×6]Ò6]ØØØŒLØØ$ð 7^ñ 7
ô 7
ð 1
ð 1
ð 1
ð 1
ð 1
ð 1
Ñ-ˆÐ-ð &ð 	ØˆKØÐ% ×,Ò,Ñ.Ô.Ð.rM   c           	   ƒ   óÔ  K  — |                       |j        ¦  «        sQt                               d|j        j        |j        j        |j        j        r|j        j        j        nd|¦  «         dS | j        �r9|  	                    |j        ¦  «        }|sdS |  
                    |¦  «        }|                      |j        |¦  «        }|                      ¦   «         r/|                      ||¦  «         d|                      ¦   «         › d�}nd|                      ¦   «         › d�}|                     |j        j        ||j        j        t"          j        k    r|j        j        dk    r|j        j        r|n.|j        j        t"          j        k    r|j        j        rd n|j        |¬	¦  «        ƒ d {V —† dS 	 d
dlm}  ||¦  «        �rO|j        pd                     ¦   «                              ¦   «         }h d£}	h d£}
d }d}||	v r| j        }n'||
v r| j        }n|dv r
| j        }d}n|dv r	| j        }d}|�á|| j        u rdnd}d|› �}|r|› d|› �}||_         ||¦  «        ƒ d {V —†}t                               d|||¦  «         |  	                    |j        ¦  «        }|rs|rq|                     |¦  «        \  }}|rW|  
                    |¦  «        }|                     |j        j        |||                      |j        |¦  «        ¬	¦  «        ƒ d {V —† dS n-# t>          $ r  t                               d|d¬¦  «         Y nw xY w|  	                    |j        ¦  «        }|sdS tA          |dd¦  «        rdS |  !                    |¦  «        }|r|j"        j#        nd }| j$        }tA          | dd¦  «        }|j%        tL          j'        k    r|dk    r|dk    rdS |dk    o|  (                    |¦  «        }|rt                               d |¦  «         d}|dk    o|  )                    |¦  «        ƒ d {V —†}|rt                               d!|¦  «         d}d}d}|dk    �r|  *                    |¦  «        ƒ d {V —†}tA          |d"d ¦  «        pg }tW          |¦  «        o2tY          |  -                    |¦  «        ¦  «        tY          |¦  «        k    }|oC|j%        tL          j'        k    o|j.         o|j/         p|o|d uo|t`          uotc          |d¦  «        }|rY	 tW          | 2                    |¦  «        ¦  «        }n5# t>          $ r(} t                               d#|| ¦  «         d}Y d } ~ nd } ~ ww xY w|sd}nÉ|dk    rÃ|j%        tL          j'        k    r®|j.        s§|j/        s |�ž|t`          ur•tA          |d$d¦  «        du r‚tc          |d%¦  «        rr	 tW          | 3                    |j        pd                     ¦   «         ¦  «        ¦  «        }n5# t>          $ r(} t                               d&|| ¦  «         d}Y d } ~ nd } ~ ww xY w|s|s|                      ||¦  «         |dk    }!|dk    }"|dk    o|}#|dk    r¦|s¤|r¢|t`          ur™	 |j        }$tA          |d"d ¦  «        pg }%|  -                    |¦  «        r0|  4                    |||j        |j        pdd'¬(¦  «        ƒ d {V —†\  }$}&n|$s|%rtk          |¦  «        }$| 6                    |$¦  «         n# t>          $ r Y nw xY wtn          j8         9                    d)d*¦  «                             ¦   «         d*k    }'|'st           :                    d+|¦  «         dS d,}(tw          j;        ¦   «         })|r|j"        j<        nd
}*|)|*z
  |(k     rdS d
d-l=m>}+ t          |j        j        ¦  «        },|"r�tn          j8         9                    d.¦  «        }-|-�)|-                     ¦   «                              ¦   «         d/v }.n'tW           |+t�          ¦   «         |,d0d¦  «        ¦  «        }.|.st           :                    d1|¦  «         dS |)|  A                    |¦  «        j"        _<        g }/tW           |+t�          ¦   «         t          |j        j        ¦  «        d2d¦  «        ¦  «        }0|0rî|rì|t`          urã	 | B                    ¦   «         }1|1 9                    d3d
¦  «        }2|1 9                    d4d
¦  «        }3|1 9                    d5¦  «        }4|r|j"        jC        nd
}5|5r3t‰          |)|5z
  d6z  ¦  «        }6|6d
k    r|/ E                    |6› d7�¦  «         |3r|/ E                    d8|2› d|3› �¦  «         |4r|/ E                    d9|4› �¦  «         n# t>          $ r Y nw xY w|/rd:d; F                    |/¦  «        › d<�nd}7|"rd=|7› d>�}n.|#rd?|7› d@�}n%|!r	|rdA|7› dB�}n|!r	|rdC|7› dB�}n|!rdD|7› dE�}ndF|7› dG�}	 d
dHlGmH}8mI}9mJ}:mK}; t�          ¦   «         }< |:|<|8¦  «        s5|"rd}=n|!rd}=n|#rd%}=nd}=|› dI |9|=¦  «        › �} |;t˜          dJz  |8¦  «         n2# t>          $ r%}>t           :                    dK|>¦  «         Y d }>~>nd }>~>ww xY w|  
                    |¦  «        }|                      |j        |¦  «        }	 |                     |j        j        ||j        j        t"          j        k    r|j        j        dk    r|j        j        r|n.|j        j        t"          j        k    r|j        j        rd n|j        |¬	¦  «        ƒ d {V —† n2# t>          $ r%}?t           :                    dL|?¦  «         Y d }?~?nd }?~?ww xY wdS )MNz`Dropping message from unauthorized user in active session: user=%s (%s), platform=%s, session=%sr¼  Tõ   â�³ Gateway õ2    â€” queued for the next turn after it comes back.õ   â�³ Gateway is ú- and is not accepting another turn right now.rµ  r  r   ©Úhas_blocking_approvalr®   >   õ   ðŸ‘�ÚyÚokrq   ÚokayÚapproveÚconfirm>   õ   ðŸ‘ŽÚnÚnoÚdenyr  Úreject>   úapprove alwaysÚalwaysúalways approverÞ	  >   úapprove sessionúsession approveÚsessionrâ	  rÖ	  rÛ	  r]  r™  z<Approval response via plain text: session=%s verb=%s args=%rzSPlain-text approval routing failed for session %s; falling through to busy handlingrß   FÚinternalr&  r$  r™  r	  zvDemoting busy_input_mode 'interrupt' to 'queue' for session %s because the running agent has active subagents (#30170)zpDemoting busy_input_mode 'interrupt' to 'queue' for session %s because context compression is in flight (#56391)rì  z'Gateway steer failed for session %s: %sÚ_supports_active_turn_redirectÚredirectz*Gateway redirect failed for session %s: %szVoice-busy-interruptrÄ	  r,  rr   z"Busy ack suppressed for session %sr  rR  r.  >   ro   rp   rq   rr   r-  z(Busy steer ack suppressed for session %sÚbusy_ack_detailÚapi_call_countr  Úcurrent_toolrø  z min elapsedú
iteration z	running: ú (r  rŠ  u   â�© Steered into current runz0. Your message arrives after the next tool call.u   â†ª Redirected current runz$. I'll adjust using your correction.u   â�³ Subagent workinguR    â€” your message is queued for when it finishes (use /stop to cancel everything).u   â�³ Compressing contextu   â�³ Queued for the next turnz.. I'll respond once the current task finishes.u   âš¡ Interrupting current taskz'. I'll respond to your message shortly.)ÚBUSY_INPUT_FLAGÚbusy_input_hint_gatewayr  r  r  r‹  z.Failed to apply busy-input onboarding hint: %szFailed to send busy-ack: %s)MÚ_is_user_authorizedr(  r3   rã   r¹  r)  r�   r­   r*  r@  ru  Ú_thread_metadata_for_sourcer	  rÂ	  r	  Ú_send_with_retryr2  rÄ  rÍ  r´  r›  rj  rÃ  rÑ	  rè   rx   ry   Ú_handle_approve_commandÚ_handle_deny_commandrz  Ú_unwrap_ephemeralr2   rV   rA   rJ  rµ   r%  rÚ  rs  rÀ	  r±	  r¸	  rÊ	  rº   r7   rÆ	  rì  rÕ  rž  rá   r	  rå	  rÇ	  rð  r$  r’   r“   rv   r4   rU   Úbusy_ack_tsrT  rS  ru  rs   r/   r>  Ú
started_tsrh  r”   rf   r<  rë	  rì	  r  r  rl  )@r  rÖ  r+   r1  Úreply_anchorÚthread_metar$  rÑ	  Ú	_raw_textÚ_approve_wordsÚ_deny_wordsÚ_approval_handlerÚ_normalized_argsr[  Ú_synthÚ_replyr³  Ú_textÚ_eph_ttlÚ_anchorÚ_busy_stater«	  Úeffective_moder)  Údemoted_for_subagentsÚdemoted_for_compressionÚsteeredÚ
redirectedÚ
steer_textÚ_steer_media_urlsÚ_steer_all_voiceÚ	can_steerr<   Úis_queue_modeÚis_steer_modeÚis_redirect_modeÚ_interrupt_textÚ_media_urlsrK  r+  Ú_BUSY_ACK_COOLDOWNrŒ  Úlast_ackrS  r?  Ústeer_ack_envÚsteer_ack_enabledÚstatus_partsÚbusy_ack_detail_enabledÚsummaryr¶  Úmax_iterrè	  Ústart_tsÚelapsed_minÚstatus_detailrë	  rì	  r  r  Ú	_user_cfgÚ
_hint_modeÚ_onb_errr¨  s@                                                                   r>   Ú#_handle_active_session_busy_messagez1GatewayRunner._handle_active_session_busy_messageî"  sï  è è € ð ×'Ò'¨¬Ñ5Ô5ð 		Ý�NŠNð8à”Ô$Ø”Ô&Ø/4¬|Ô/DÐS�”Ô%Ô+Ð+È)Øñô ð ð �4ð Œ>ñ 	Ø×.Ò.¨u¬|Ñ<Ô<ˆGØð Ø�tà×7Ò7¸Ñ>Ô>ˆLØ×:Ò:¸5¼<ÈÑVÔVˆKØ×/Ò/Ñ1Ô1ð xØ×4Ò4°[À%ÑHÔHÐHØy¨×)CÒ)CÑ)EÔ)EÐyÐyÐy��àw¨D×,FÒ,FÑ,HÔ,HÐwÐwÐw�à×*Ò*ØœÔ,Øð ”|Ô,µÔ0AÒAÐAØœÔ.°$Ò6Ð6ØœÔ.ð 7ð !�Lð #(¤,Ô"7½8Ô;LÒ"LÐ"LÐQVÔQ]ÔQgÐ"L˜$˜$ÐmrÔm}à$ð +ñ ô ð ð ð ð ð ð ð ð �4ð.4	Ø<Ð<Ð<Ð<Ð<Ð<Ø$Ð$ [Ñ1Ô1ñ , Ø"œZÐ-¨2×4Ò4Ñ6Ô6×<Ò<Ñ>Ô>�	Ø!YÐ!YÐ!Y�ØMÐMÐM�Ø$(Ð!Ø#%Ð Ø Ð.Ð.Ø(,Ô(DÐ%Ð%Ø +Ð-Ð-Ø(,Ô(AÐ%Ð%ØÐ"PÐPÐPØ(,Ô(DÐ%Ø'/Ð$Ð$ØÐ"SÐSÐSØ(,Ô(DÐ%Ø'0Ð$Ø$Ð0ð *;¸dÔ>ZÐ)ZÐ)Z˜I˜IÐ`f�EØ( ˜[˜[�FØ'ð @Ø$*Ð!?Ð!?Ð-=Ð!?Ð!?˜Ø!'�E”JØ#4Ð#4°UÑ#;Ô#;Ð;Ð;Ð;Ð;Ð;Ð;�FÝ—K’KØVØ# UÐ,<ñô ð ð  $×7Ò7¸¼ÑEÔE�HØð 	 Fð 	Ø*2×*DÒ*DÀVÑ*LÔ*L™˜˜xØ ð Ø&*×&BÒ&BÀ5Ñ&IÔ&I˜GØ"*×";Ò";Ø(-¬Ô(<Ø(-Ø)0Ø)-×)IÒ)IÈ%Ì,ÐX_Ñ)`Ô)`ð	 #<ñ #ô #ð ð ð ð ð ð ð ð  ˜4øøÝð 	ð 	ð 	Ý�NŠNð3à dð ñ ô ð ð ð ð	øøøð ×*Ò*¨5¬<Ñ8Ô8ˆØð 	Ø�5õ �5˜* eÑ,Ô,ð 	Ø�5à×.Ò.¨{Ñ;Ô;ˆØ2=ÐG˜Ô(Ô.Ð.À4ˆàÔ.ˆÝ  Ð'8¸+ÑFÔFˆàÔ¥+Ô"2Ò2Ð2Ø 'Ò)Ð)Ø 'Ò)Ð)à�5ð ˜kÒ)ð @Ø×0Ò0°Ñ?Ô?ð 	ð !ð 	%Ý�KŠKðJàñô ð ð
 %ˆNà˜kÒ)ð KØ×=Ò=¸kÑJÔJÐJÐJÐJÐJÐJÐJð 	 ð #ð 	%Ý�KŠKðDàñô ð ð
 %ˆNØˆØˆ
Ø˜WÒ$Ñ$Ø#×<Ò<¸UÑCÔCÐCÐCÐCÐCÐCÐCˆJõ
 !(¨¨|¸TÑ BÔ BÐ HÀbÐÝ#Ð$5Ñ6Ô6ð  Ý�D×3Ò3°EÑ:Ô:Ñ;Ô;½sÐCTÑ?UÔ?UÒUð ð ð 4ð Ô*­kÔ.>Ò>ð 2Ø %Ô 0Ð0ð2à %Ô 1Ð1ð(ð
 (ð4ð "¨Ð-ð4ð "Õ)@Ð@ð4õ ˜M¨7Ñ3Ô3ð ð ð $ð$Ý" =×#6Ò#6°zÑ#BÔ#BÑCÔC�G�GøÝ ð $ð $ð $Ý—N’NÐ#LÈkÐ[^Ñ_Ô_Ð_Ø#�G�G�G�G�G�Gøøøøð$øøøð ð )à!(�øà˜kÒ)Ð)ØÔ"¥kÔ&6Ò6Ð6ØÔ$ð 7àÔ%ð 7ð Ð)ØÕ%<Ð<Ð<Ý˜Ð'GÈÑOÔOÐSWÐWÐWÝ˜ zÑ2Ô2ð Xð#Ý! -×"8Ò"8¸%¼*Ð:JÈ×9QÒ9QÑ9SÔ9SÑ"TÔ"TÑUÔU�
�
øÝð #ð #ð #Ý—’ÐKÈ[ÐZ]Ñ^Ô^Ð^Ø"�
�
�
�
�
�
øøøøð#øøøð& ð 	E˜zð 	EØ×0Ò0°¸eÑDÔDÐDà&¨'Ò1ˆØ&¨'Ò1ˆØ)¨[Ò8ÐG¸ZÐð ˜kÒ)Ð)Øð *àð *ð Õ%<Ð<Ð<ðØ"'¤*�Ý% e¨\¸4Ñ@Ô@ÐFÀB�Ø×2Ò2°5Ñ9Ô9ð 	FØ/3×/VÒ/VØØØœØœ
Ð( bØ$:ð 0Wñ 0ô 0ð *ð *ð *ð *ð *ð *Ñ&�O Q Qð )ð F¨[ð FÝ&>¸uÑ&EÔ&E�OØ×'Ò'¨Ñ8Ô8Ð8Ð8øÝð ð ð Ø�ðøøøõ œ:Ÿ>š>Ð*KÈVÑTÔT×ZÒZÑ\Ô\Ð`fÒfÐØð 	Ý�LŠLÐ=¸{ÑKÔKÐKØ�4ð
  ÐÝŒi‰kŒkˆØ3>ÐE�;Ô#Ô/Ð/ÀAˆØ�‰>Ð.Ò.Ð.Ø�4àBÐBÐBÐBÐBÐBÝ+¨E¬LÔ,AÑBÔBˆð ð 	ÝœJŸNšNÐ+RÑSÔSˆMØÐ(Ø$1×$7Ò$7Ñ$9Ô$9×$?Ò$?Ñ$AÔ$AÐE_Ð$_Ð!Ð!å$(Ø+Ð+Ý,Ñ.Ô.Ø$Ø0Øñ	ô ñ%ô %Ð!ð %ð Ý—’ÐGÈÑUÔUÐUØ�tà<?ˆ×Ò˜KÑ(Ô(Ô-Ô9ð
 ˆÝ"&Ø#Ð#Ý$Ñ&Ô&Ý$ U¤\Ô%:Ñ;Ô;Ø!Øñ	ô ñ#
ô #
Ðð #ð 	 }ð 	¸ÕNeÐ9eÐ9eðØ'×<Ò<Ñ>Ô>�Ø#ŸKšKÐ(8¸!Ñ<Ô<�	Ø"Ÿ;š;Ð'7¸Ñ;Ô;�Ø&Ÿ{š{¨>Ñ:Ô:�Ø:EÐL˜;Ô+Ô6Ð6È1�Øð JÝ"% s¨X¡~¸Ñ&;Ñ"<Ô"<�KØ" Q’�Ø$×+Ò+¨{Ð,HÐ,HÐ,HÑIÔIÐIØð MØ ×'Ò'Ð(K°YÐ(KÐ(KÀÐ(KÐ(KÑLÔLÐLØð DØ ×'Ò'Ð(B°LÐ(BÐ(BÑCÔCÐCøøÝð ð ð Ø�ðøøøð <HÐOÐ7˜TŸYšY |Ñ4Ô4Ð7Ð7Ð7Ð7ÈRˆØð  	ðB¨}ð Bð Bð Bð ˆGð ð 	ð6¨]ð 6ð 6ð 6ð ˆGð ð 	Ð4ð 	ð
F }ð Fð Fð Fð ˆGð ð 	Ð6ð 	ðF¨-ð Fð Fð Fð ˆGð ð 		ð@¨}ð @ð @ð @ð ˆGð9°ð 9ð 9ð 9ð ð	Uðð ð ð ð ð ð ð ð ð ð ð õ -Ñ.Ô.ˆIØ�7˜9 oÑ6Ô6ð IØ ð -Ø!(�J�JØ"ð -Ø!(�J�JØ%ð -Ø!+�J�Jà!,�Jàð =ð =Ø.Ð.¨zÑ:Ô:ð=ð =ð ð �	�,¨Ñ6¸ÑHÔHÐHøøÝð 	Uð 	Uð 	UÝ�LŠLÐIÈ8ÑTÔTÐTÐTÐTÐTÐTÐTøøøøð	Uøøøð ×3Ò3°EÑ:Ô:ˆØ×6Ò6°u´|À\ÑRÔRˆð	;Ø×*Ò*ØœÔ,Øð ”|Ô,µÔ0AÒAÐAØœÔ.°$Ò6Ð6ØœÔ.ð 7ð !�Lð #(¤,Ô"7½8Ô;LÒ"LÐ"LÐQVÔQ]ÔQgÐ"L˜$˜$ÐmrÔm}à$ð +ñ ô ð ð ð ð ð ð ð ð øõ ð 	;ð 	;ð 	;Ý�LŠLÐ6¸Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:øøøøð	;øøøð ˆts›   Æ0EL Ì'L<Ì;L<Ô"T1 Ô1
U#Ô;UÕU#×;W? ×?
X1Ø	X,Ø,X1Ù6B[> Û>
\Ü
\â1Cf æ
fæfç(Ai é
i3éi.é.i3ê'Bl6 ì6
m%í m í m%c              ƒ   ó`  ‡ ‡‡‡‡	K  — ‰                       ¦   «         }‰                      ¦   «         Š‰                      ¦   «         Š‰                      ¦   «         ŠdŠ	d
dt          dd fˆˆˆˆ	ˆ fd„}‰ j        s‰dk    r‰dk    r |d¬¦  «         |dfS  |d¬¦  «         |dk    r|dfS t          j        ¦   «                              ¦   «         |z   }t          ‰ j        ¦  «        s(‰                      ¦   «         s‰                      ¦   «         r²t          j        ¦   «                              ¦   «         |k     r‰ |¦   «          t          j
        d	¦  «        ƒ d {V —† t          ‰ j        ¦  «        s(‰                      ¦   «         s‰                      ¦   «         r)t          j        ¦   «                              ¦   «         |k     °‰t	          t          ‰ j        ¦  «        ¦  «        pAt	          ‰                      ¦   «         ¦  «        p t	          ‰                      ¦   «         ¦  «        } |d¬¦  «         ||fS )Nr@  Frí   r-   c                 óB  •— t          j        ¦   «                              ¦   «         }‰	                     ¦   «         }‰	                     ¦   «         }‰	                     ¦   «         }| s|‰k    s|‰k    s|‰k    s	|‰z
  dk    r‰	                     d¦  «         |Š|Š|Š|Šd S d S )NrB	  r	  )r  Úget_running_looprU   r¼  r¾  r¿  r	  )
rí   rŒ  rË  Ú
cron_countÚ	api_countÚlast_active_countÚlast_api_countÚlast_cron_countÚlast_status_atr  s
        €€€€€r>   Ú_maybe_update_statusz@GatewayRunner._drain_active_agents.<locals>._maybe_update_status¯$  s¿   ø€ åÔ*Ñ,Ô,×1Ò1Ñ3Ô3ˆCØ×4Ò4Ñ6Ô6ˆLØ×4Ò4Ñ6Ô6ˆJØ×2Ò2Ñ4Ô4ˆIàð%àÐ#4Ò4Ð4Ø Ò0Ð0Ø Ò.Ð.Ø˜.Ñ(¨SÒ0Ð0à×+Ò+¨JÑ7Ô7Ð7Ø$0Ð!Ø",�Ø!*�Ø!$���ð 1Ð0rM   r   Trì   çš™™™™™¹?rŠ  )rœ	  r¼  r¾  r¿  rº   r7  r  r!
  rU   r7   r–  )
r  rÓ  Úsnapshotr(
  ÚdeadlineÚ	timed_outr$
  r%
  r&
  r'
  s
   `     @@@@r>   Ú_drain_active_agentsz"GatewayRunner._drain_active_agents¨$  s�  øøøøøè è € Ø×0Ò0Ñ2Ô2ˆØ ×5Ò5Ñ7Ô7ÐØ×5Ò5Ñ7Ô7ˆØ×3Ò3Ñ5Ô5ˆØˆð	%ð 	%­ð 	%¸ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð2 Ô#ð 	#¨¸1Ò(<Ð(<ÀÐSTÒATÐATØ Ð  tÐ,Ñ,Ô,Ð,Ø˜U�?Ð"àÐ 4Ð(Ñ(Ô(Ð(Ø�aŠ<ˆ<Ø˜T�>Ð!åÔ+Ñ-Ô-×2Ò2Ñ4Ô4°wÑ>ˆõ �DÔ(Ñ)Ô)ð		%ð ×.Ò.Ñ0Ô0ð		%ð ×-Ò-Ñ/Ô/ð			%õ Ô(Ñ*Ô*×/Ò/Ñ1Ô1°HÒ<Ð<à Ð Ñ"Ô"Ð"Ý”- Ñ$Ô$Ð$Ð$Ð$Ð$Ð$Ð$Ð$õ �DÔ(Ñ)Ô)ð		%ð ×.Ò.Ñ0Ô0ð		%ð ×-Ò-Ñ/Ô/ð			%õ Ô(Ñ*Ô*×/Ò/Ñ1Ô1°HÒ<Ð<õ
 •�TÔ)Ñ*Ô*Ñ+Ô+ð 2Ý�D×/Ò/Ñ1Ô1Ñ2Ô2ð2å�D×.Ò.Ñ0Ô0Ñ1Ô1ð 	ð
 	Ð 4Ð(Ñ(Ô(Ð(Ø˜Ð"Ð"rM   c                 ó–  — t          | j                             ¦   «         ¦  «        D ]m\  }}|t          u rŒ	 t	          ||¦  «         t
                               d|¦  «         Œ<# t          $ r%}t
                               d|¦  «         Y d }~Œfd }~ww xY w|                      |¦  «        }|rt
                               d|¦  «         d S d S )Nz8Interrupted running agent for session %s during shutdownz-Failed interrupting agent during shutdown: %sz0Interrupted %d api_server run(s) during shutdown)	r½  r7  rñ  rž  r   r3   r4   r2   rÈ  )r  r•  r+   rµ   r¨  Úinterrupted_apis         r>   Ú_interrupt_running_agentsz'GatewayRunner._interrupt_running_agentsã$  sù   € Ý"& tÔ';×'AÒ'AÑ'CÔ'CÑ"DÔ"Dð 	Qð 	QÑˆK˜ØÕ/Ð/Ð/ØðQÝ& u¨fÑ5Ô5Ð5Ý—’ÐWÐYdÑeÔeÐeÐeøÝð Qð Qð QÝ—’ÐLÈaÑPÔPÐPÐPÐPÐPÐPÐPøøøøðQøøøð
 ×9Ò9¸&ÑAÔAˆØð 	^Ý�LŠLÐKÈ_Ñ]Ô]Ð]Ð]Ð]ð	^ð 	^s   ·+A#Á#
BÁ-BÂBc              ƒ   ó:  K  — |                       ¦   «         }| j        r| j        nd}| j        rdnd}| j        rdnd}d|› d|› �}t          ¦   «         }|D �]}d}	 t	          | dd¦  «        �S| j                             ¦   «         ƒ d{V —† | j        j         	                    |¦  «        }	|	rt	          |	d	d¦  «        nd}n3# t          $ r&}
t                               d
||
¦  «         Y d}
~
nd}
~
ww xY w|€|                      |¦  «        }|�(|j        j        }t!          |j        ¦  «        }|j        }n7t'          |¦  «        }|sŒñ|d         }|d         }| 	                    d¦  «        }|||rt!          |¦  «        ndf}||v r�Œ2	 t)          |¦  «        }| j         	                    |¦  «        }|s�Œ`| j        j         	                    |¦  «        }|�$|j        st                               d|¦  «         �Œ¥|�t	          |dd¦  «        nd}|€k|�i	 |j        j        }t!          |j        ¦  «        }|j        rt!          |j        ¦  «        nd}|||f|k    rt	          |dd¦  «        }n# t          $ r Y nw xY w|                      ||||�t	          |dd¦  «        nd||¬¦  «        }|                     |||¬¦  «        ƒ d{V —†}|�At	          |dd¦  «        du r.t                               d||t	          |dd¦  «        ¦  «         �Œ¶|                     |¦  «         t                               d||¦  «         �Œé# t          $ r(}
t                               d|||
¦  «         Y d}
~
�Œd}
~
ww xY w| j        r|�t                               d¦  «         dS 	 ddlm}  |¦   «         rt                               d¦  «         dS n2# t          $ r%}
t                               d|
¦  «         Y d}
~
nd}
~
ww xY wt?          | j                              ¦   «         ¦  «        D �]û\  }}| j         !                    |¦  «        }|r|j        sŒ*| j        j         	                    |¦  «        }|�(|j        s!t                               d|j        ¦  «         Œs|j        t!          |j        ¦  «        |j        rt!          |j        ¦  «        ndf}||v rŒ¯	 |                      ||j        |j        |¬ ¦  «        }|r1|                     t!          |j        ¦  «        ||¬¦  «        ƒ d{V —†}n.|                     t!          |j        ¦  «        |¦  «        ƒ d{V —†}|�Kt	          |dd¦  «        du r8t                               d!|j        |j        t	          |dd¦  «        ¦  «         �Œ�|                     |¦  «         t                               d"|j        |j        ¦  «         �Œ¾# t          $ r2}
t                               d!|j        |j        |
¦  «         Y d}
~
�Œõd}
~
ww xY wdS )#u4  Send shutdown/restart notifications to active chats and home channels.

        Called at the very start of stop() â€” adapters are still connected so
        messages can be delivered. Best-effort: individual send failures are
        logged and swallowed so they never block the shutdown sequence.
        Nr	  r	  zpYour current task will be interrupted. Send any message after restart and I'll try to resume where you left off.z&Your current task will be interrupted.u   âš ï¸� Gateway õ    â€” r›  Úoriginz>Failed to load session origin for shutdown notification %s: %sr�   r2  r›  z^Shutdown notification suppressed for active session: %s has gateway_restart_notification=falserj  r´  ©r´  Úreply_to_message_idr1  r.  r/  TFz1Failed to send shutdown notification to %s:%s: %srP   úsend returned success=Falsez/Sent shutdown notification to active chat %s:%sz@Skipping home-channel shutdown notifications for in-chat restartr   )Údrain_notification_suppressedzWHome-channel shutdown broadcast suppressed by drain marker (suppress_notification=true)z.drain_notification_suppressed check failed: %sz\Shutdown notification suppressed for home channel: %s has gateway_restart_notification=falser   z>Failed to send shutdown notification to home channel %s:%s: %sz0Sent shutdown notification to home channel %s:%s)"rœ	  r,  r1  r•   rV   Úasync_session_storeÚ_ensure_loadedr›  rÄ  rv   r2   r3   r4   Ú_get_cached_session_sourcer�   r­   rw   r2  r›  r¸  rÄ  r°  rz   rE  Úgateway_restart_notificationrz  Ú_thread_metadata_for_targetr0  r—   rE	  r7
  r½  rñ  Úget_home_channel)r  rö  Úrestart_sourceÚactionÚhintr§  Únotifiedr+   r(  r®  r¨  Úplatform_strr2  r›  Ú_parsedÚ	dedup_keyr�   r1  rG  r5
  Úrestart_platformÚrestart_chat_idÚrestart_thread_idr¯   r·  r7
  r‰  s                              r>   Ú#_notify_active_sessions_of_shutdownz1GatewayRunner._notify_active_sessions_of_shutdownó$  sÃ  è è € ð ×.Ò.Ñ0Ô0ˆØ9=Ô9PÐZ˜Ô5Ð5ÐVZˆà!%Ô!8ÐM��¸oˆð Ô&ð:ð Xð Xð :ð	 	ð 4 Ð3Ð3¨TÐ3Ð3ˆå8;¹¼ˆØ!ð [	ñ [	ˆKØˆFð
Ý˜4 °$Ñ7Ô7ÐCØÔ2×AÒAÑCÔCÐCÐCÐCÐCÐCÐCÐCØ Ô.Ô7×;Ò;¸KÑHÔH�EØ?DÐN�W U¨H°dÑ;Ô;Ð;È$�FøøÝð ð ð Ý—’ØTØØñô ð ð ð ð ð ð øøøøðøøøð ˆ~Ø×8Ò8¸ÑEÔE�àÐ!Ø%œÔ4�Ý˜fœnÑ-Ô-�Ø"Ô,�	�	õ -¨[Ñ9Ô9�Øð ØØ& zÔ2�Ø! )Ô,�Ø#ŸKšK¨Ñ4Ô4�	ð
 & wÀ)Ð0Uµ°I±´°ÐQUÐVˆIØ˜HÐ$Ð$Ùð5Ý# LÑ1Ô1�Øœ-×+Ò+¨HÑ5Ô5�Øð Ùà#œ{Ô4×8Ò8¸ÑBÔB�ØÐ+°LÔ4]Ð+Ý—K’KØxØ$ñô ð ñ àMSÐM_¥g¨f°lÀDÑ&IÔ&IÐ&IÐeiÐ#Ø&Ð.°>Ð3MðØ+9Ô+BÔ+HÐ(Ý*-¨nÔ.DÑ*EÔ*E˜ØM[ÔMeÐ,o­C°Ô0HÑ,IÔ,IÐ,IÐkoÐ)Ø,¨oÐ?PÐQÐU^Ò^Ð^Ý29¸.È,ÐX\Ñ2]Ô2]Ð/øøÝ$ð ð ð Ø˜ðøøøð  ×;Ò;ØØØØDJÐDV�g f¨k¸4Ñ@Ô@Ð@Ð\`Ø(;Ø#ð <ñ ô �ð  'Ÿ|š|¨G°SÀ8˜|ÑLÔLÐLÐLÐLÐLÐLÐL�ØÐ%­'°&¸)ÀTÑ*JÔ*JÈeÐ*SÐ*SÝ—L’LØKØ$ØÝ ¨Ð1NÑOÔOñ	ô ð ñ à—’˜YÑ'Ô'Ð'Ý—’ØEØ  'ñô ð ñ øõ ð ð ð Ý—’ØGØ  '¨1ñô ð ð ð ð ð ñ øøøøðøøøð Ô"ð 	 ~Ð'AÝ�LŠLÐ[Ñ\Ô\Ð\ØˆFð	NØKÐKÐKÐKÐKÐKØ,Ð,Ñ.Ô.ð Ý—’ð3ñô ð ð �ðøõ ð 	Nð 	Nð 	Nõ �LŠLÐIÈ1ÑMÔMÐMÐMÐMÐMÐMÐMøøøøð	Nøøøõ "& d¤m×&9Ò&9Ñ&;Ô&;Ñ!<Ô!<ð 1	ñ 1	ÑˆH�gØ”;×/Ò/°Ñ9Ô9ˆDØð ˜tœ|ð Øàœ;Ô0×4Ò4°XÑ>Ô>ˆLØÐ'°Ô0YÐ'Ý—’ØrØ”Nñô ð ð à!œ­¨T¬\Ñ):Ô):ÐSWÔSaÐ<k½CÀÄÑ<OÔ<OÐ<OÐgkÐlˆIØ˜HÐ$Ð$Øð Ø×;Ò;ØØ”LØ”NØ#ð	 <ñ ô �ð ð HØ#*§<¢<µ°D´LÑ0AÔ0AÀ3ÐQY <Ñ#ZÔ#ZÐZÐZÐZÐZÐZÐZ�F�Fà#*§<¢<µ°D´LÑ0AÔ0AÀ3Ñ#GÔ#GÐGÐGÐGÐGÐGÐG�FØÐ%­'°&¸)ÀTÑ*JÔ*JÈeÐ*SÐ*SÝ—L’LØXØ œØœÝ ¨Ð1NÑOÔOñ	ô ð ñ à—’˜YÑ'Ô'Ð'Ý—’ØFØ”NØ”Lñô ð ñ øõ
 ð ð ð Ý—’ØTØ”NØ”LØñ	ô ð ð ð ð ð ñ øøøøðøøøðW1	ð 1	s¡   ÁA$C Ã 
C0Ã
C+Ã+C0Æ+L>Æ5AL>Ç:L>ÈAI,É+L>É,
I9É6L>É8I9É9BL>Ì1L>Ì>
M0ÍM+Í+M0Î*O Ï
O5ÏO0Ï0O5ÓCWÖ;W×
X×&'XØXr:	  c           	   ƒ   ó.  K  — |                      ¦   «         D �]|}	 t          |dd ¦  «        }t          |dd ¦  «        }t          |¦  «        rÂt          |t          ¦  «        r­|r«t          |dd ¦  «        }t          |¦  «        r	  ||¦  «         n# t
          $ r Y nw xY w	  ||¦  «         na# t
          $ rT}t                               d|t          |¦  «        ¦  «         ddl	m
}  |t          |dd ¦  «        |¦  «         Y d }~nd }~ww xY wn2# t
          $ r%}t                               d|¦  «         Y d }~nd }~ww xY w	 dd	lm}	  |	t          |dd ¦  «        d
d¬¦  «         n# t
          $ r Y nw xY w|                      |d¬¦  «        ƒ d {V —† �Œ~d S )NÚ_flush_messages_to_session_dbr[  Ú)_drop_trailing_empty_response_scaffoldingz^Shutdown transcript flush failed (%s); preserving %d in-memory message(s) to recovery snapshotr   )Úflush_agent_history_to_filerN   z$Shutdown transcript flush failed: %s©Úfinalize_sessionr9   r	  ©rN   r�   r•  zshutdown finalize©rÙ   )r•  rV   r/  rt   r½  r2   r3   rã   r7   Úgateway.shutdown_flushrL
  r4   Úhermes_cli.lifecyclerN
  Ú!_cleanup_agent_resources_off_loop)
r  r:	  rµ   rX  r[  Ú_stripÚ
_flush_errrL
  rÄ  rN
  s
             r>   Ú_finalize_shutdown_agentsz'GatewayRunner._finalize_shutdown_agentsº%  s¢  è è € Ø"×)Ò)Ñ+Ô+ð E	ñ E	ˆEð 'IÝ  Ð(GÈÑNÔN�Ý$+¨EÐ3FÈÑ$MÔ$MÐ!Ý˜FÑ#Ô#ð "­
Ð3DÅdÑ(KÔ(Kð "ÐPað "õ
 %ØÐJÈDñô �Fõ   Ñ'Ô'ð !ð!Ø"˜FÐ#4Ñ5Ô5Ð5Ð5øÝ(ð !ð !ð !Ø ˜Dð!øøøðØ˜Ð0Ñ1Ô1Ð1Ð1øÝ$ð ð ð õ ŸšðKà&ÝÐ 1Ñ2Ô2ñ	ô ð ð WÐVÐVÐVÐVÐVØ3Ð3Ý# E¨<¸Ñ>Ô>Ø-ñô ð ð ð ð ð ð øøøøð!øøøøøõ( ð Ið Ið IÝ—’ÐCÀRÑHÔHÐHÐHÐHÐHÐHÐHøøøøðIøøøðØAÐAÐAÐAÐAÐAØ Ð Ý& u¨l¸DÑAÔAØ&Ø%ðñ ô ð ð øõ
 ð ð ð Ø�ðøøøð ×8Ò8ØÐ2ð 9ñ ô ð ð ð ð ð ð ð ñ ðGE	ð E	sy   ›A(DÂBÂDÂ
BÂDÂBÂDÂ!B-Â,DÂ-
DÂ7A
DÄDÄDÄDÄ
D>ÄD9Ä9D>Å#E&Å&
E3Å2E3Úexecutor_taskc                 ó”   — |€dS |�|                      ¦   «         rdS |r)|                      |¦  «        }|r|j        j        nd|urdS dS )aŠ  Only emit the heartbeat while this task still owns the live run.

        Guards against a stale ``running: delegate_task`` heartbeat outliving the
        run that started it: stop once the executor finishes, the agent is gone,
        or the session key has been rebound to a different live agent (e.g. the
        user sent ``/new`` and a fresh agent took the slot mid-run, #12029).
        NFT)r  rA   rJ  rµ   )r  r+   rµ   rW
  Ú	_hb_states        r>   Ú&_should_emit_long_running_notificationz4GatewayRunner._should_emit_long_running_notification&  si   € ð ˆ=Ø�5ØÐ$¨×);Ò);Ñ)=Ô)=Ð$Ø�5Øð 	Ø×0Ò0°Ñ=Ô=ˆIØ(1Ð;�	”Ô$Ð$°tÀEÐIÐIØ�uØˆtrM   rÜ   rÙ   c                ó  ‡ ‡‡‡— dˆˆˆˆ fd„}t          j         |¦   «         ¦  «        }t          ‰ dd¦  «        }|€t          ¦   «         }|‰ _        |                     |¦  «         |                     |j        ¦  «         dS )a}  Clean up ``agent`` only after its executor future has finished.

        A timed-out executor call keeps running in its worker thread. Closing
        the agent before that thread exits can tear down clients or providers
        it is still using. Keep a strong task reference and wait for the real
        future before invoking the normal bounded, off-loop cleanup path.
        r-   Nc               “   ó  •K  — 	 t          j        ‰¦  «        ƒ d {V —† nL# t           j        $ r Y d S t          $ r.} t                               d‰rd‰› d�nd| ¦  «         Y d } ~ nd } ~ ww xY w‰                     ‰‰¬¦  «        ƒ d {V —† d S )Nz2Deferred agent worker%s finished with an error: %srê	  rŠ  r®   rP
  )r  r–  r›  r2   r3   r4   rS
  )r<   rµ   rÙ   rÜ   r  s    €€€€r>   Ú_cleanup_when_donezPGatewayRunner._defer_agent_cleanup_until_future_done.<locals>._cleanup_when_done3&  sê   øè è € ðÝ”n VÑ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,Ð,øÝÔ)ð ð ð ð ��Ýð ð ð Ý—’ØHØ'.Ð6�O˜�O�O�O�O°BØñô ð ð ð ð ð ð øøøøðøøøð ×8Ò8¸ÈÐ8ÑPÔPÐPÐPÐPÐPÐPÐPÐPÐPÐPs   …   A)²	A)»$A$Á$A)Ú_deferred_agent_cleanup_tasksrŽ  )r  r”  rV   r•   r^
  r—   rä  rü  )r  rÜ   rµ   rÙ   r]
  rÝ   r—  s   ````   r>   Ú&_defer_agent_cleanup_until_future_donez4GatewayRunner._defer_agent_cleanup_until_future_done$&  s«   øøøø€ ð	Qð 	Qð 	Qð 	Qð 	Qð 	Qð 	Qð 	Qð 	Qõ Ô"Ð#5Ð#5Ñ#7Ô#7Ñ8Ô8ˆÝ˜Ð=¸tÑDÔDˆØˆ=Ý‘E”EˆEØ16ˆDÔ.Ø�	Š	�$‰ŒˆØ×Ò˜uœ}Ñ-Ô-Ð-Ð-Ð-rM   rP
  c             ƒ   óÜ  K  — |€dS |                      d¦  «        s|dk    r	 d|_        n# t          $ r Y nw xY w	 t          j        |                      | j        |¦  «        | j        ¬¦  «        ƒ d{V —† dS # t          j        $ r- t           
                    d|rd|› d�nd	| j        ¦  «         Y dS t          $ r/}t           
                    d
|rd|› d�nd	|¦  «         Y d}~dS d}~ww xY w)uÉ  Run _cleanup_agent_resources in a worker thread with a bounded wait.

        Safe to await from coroutines on the gateway event loop: a slow or
        wedged teardown (memory provider IO, subprocess close) can no longer
        block message processing. On timeout the await is cancelled and the
        worker thread is left to finish (or leak) on its own â€” the caller
        proceeds regardless, exactly as the /new reset path does (#35994).
        Nr	  úsession expiryFr  zŒAgent resource cleanup%s exceeded %ss; proceeding without blocking the event loop (the worker thread is left to finish on its own). (#53175)rê	  rŠ  r®   z,Agent resource cleanup%s failed: %s (#53175))r!  Ú_end_session_on_closer2   r  r  Ú_run_in_executor_with_contextÚ_cleanup_agent_resourcesÚ_CLEANUP_TIMEOUT_Sr,  r3   rã   )r  rµ   rÙ   Úcleanup_excs       r>   rS
  z/GatewayRunner._cleanup_agent_resources_off_loopJ&  s™  è è € ð ˆ=ØˆFØ×Ò˜jÑ)Ô)ð 	¨WÐ8HÒ-HÐ-HðØ.3�Ô+Ð+øÝð ð ð Ø�ðøøøð	ÝÔ"Ø×2Ò2ØÔ1°5ñô ð Ô/ð	ñ ô ð ð ð ð ð ð ð ð ð øõ Ô#ð 	ð 	ð 	Ý�NŠNð(ð $+Ð2��W����°ØÔ'ñô ð ð ð ð õ ð 	ð 	ð 	Ý�NŠNØ>Ø#*Ð2��W����°Øñô ð ð ð ð ð ð ð øøøøð	øøøs)   £+ «
8·8¼:A8 Á88C+Â3	C+Â<$C&Ã&C+c                 ó8  — |€dS 	 t          |d¦  «        r›t          |dd¦  «        }|�8t          |d¦  «        r(	 |                     d¬¦  «         n# t          $ r Y nw xY wt          |dd¦  «        }t	          |t
          ¦  «        r|                     |¦  «         n|                     ¦   «          n# t          $ r Y nw xY w	 t          |d¦  «        r|                     ¦   «          n# t          $ r Y nw xY w	 d	d
lm	}  |¦   «          dS # t          $ r Y dS w xY w)z<Best-effort cleanup for temporary or cached agent instances.NÚshutdown_memory_providerÚ_memory_managerÚflush_pendingrG  r  r[  Úcloser   )Úcleanup_stale_async_clients)
rá   rV   rj
  r2   rt   r½  rh
  rk
  Úagent.auxiliary_clientrl
  )r  rµ   Ú_mmÚsession_messagesrl
  s        r>   rd
  z&GatewayRunner._cleanup_agent_resourcesr&  s�  € àˆ=ØˆFð$	Ý�uÐ8Ñ9Ô9ð !5õ ˜eÐ%6¸Ñ=Ô=�Ø�?¥w¨s°OÑ'DÔ'D�?ðØ×)Ò)°"Ð)Ñ5Ô5Ð5Ð5øÝ$ð ð ð Ø˜ðøøøõ $+¨5Ð2EÀtÑ#LÔ#LÐ ÝÐ.µÑ5Ô5ð 5Ø×2Ò2Ð3CÑDÔDÐDÐDà×2Ò2Ñ4Ô4Ð4øøÝð 	ð 	ð 	ØˆDð	øøøð
	Ý�u˜gÑ&Ô&ð Ø—’‘”�øøÝð 	ð 	ð 	ØˆDð	øøøð	ØJÐJÐJÐJÐJÐJØ'Ð'Ñ)Ô)Ð)Ð)Ð)øÝð 	ð 	ð 	ØˆDˆDð	øøøsY   †3B2 ºA ÁB2 Á
AÁB2 ÁAÁAB2 Â2
B?Â>B?Ã$C( Ã(
C5Ã4C5Ã9D Ä
DÄDr)   z.restart_failure_countsÚactive_session_keysc                 óV  — ddl }t          | j        z  }	 |                     ¦   «         r$ |j        |                     d¬¦  «        ¦  «        ni }n# t          $ r i }Y nw xY wi }|D ]}|                     |d¦  «        dz   ||<   Œ	 t          ||d¬¦  «         dS # t          $ r Y dS w xY w)a  Increment restart-failure counters for sessions active at shutdown.

        Persists to a JSON file so counters survive across restarts.
        Sessions NOT in active_session_keys are removed (they completed
        successfully, so the loop is broken).
        r   NrQ  r‚  r(   ró  )	r3  rl  Ú_STUCK_LOOP_FILEr˜   r4  rX  r2   rv   rz  )r  rp
  r3  r™   ÚcountsÚ
new_countsr  s          r>   Ú!_increment_restart_failure_countsz/GatewayRunner._increment_restart_failure_counts°&  sí   € ð 	ˆˆˆå˜dÔ3Ñ3ˆð	ØEIÇ[Â[Á]Ä]ÐZ�Z�T”Z §¢¸ Ñ @Ô @ÑAÔAÐAÐXZˆFˆFøÝð 	ð 	ð 	ØˆFˆFˆFð	øøøð ˆ
Ø&ð 	5ð 	5ˆCØ$Ÿjšj¨¨aÑ0Ô0°1Ñ4ˆJ�s‰OˆOð	Ý˜d J°tÐ<Ñ<Ô<Ð<Ð<Ð<øÝð 	ð 	ð 	ØˆDˆDð	øøøs#   •:A ÁAÁAÂB Â
B(Â'B(c                 óŽ  ‡ — ddl }t          ‰ j        z  }|                     ¦   «         sdS 	  |j        |                     d¬¦  «        ¦  «        }n# t          $ r Y dS w xY wd}ˆ fd„|                     ¦   «         D ¦   «         }|D ]i}	 ‰ j        j	         
                    |¦  «        }|r5|j        s.d|_        |dz  }t                               d|||         ¦  «         ŒZ# t          $ r Y Œfw xY w|r+	 ‰ j                             ¦   «          n# t          $ r Y nw xY w	 |                     d¬	¦  «         n# t          $ r Y nw xY w|S )
u,  Suspend sessions that have been active across too many restarts.

        Returns the number of sessions suspended.  Called on gateway startup
        AFTER suspend_recently_active() to catch the stuck-loop pattern:
        session loads â†’ agent gets stuck â†’ gateway restarts â†’ repeat.
        r   NrQ  r‚  c                 ó0   •— g | ]\  }}|‰j         k    ¯|‘ŒS rN  )Ú_STUCK_LOOP_THRESHOLD)rb   rè  ré  r  s      €r>   r  z>GatewayRunner._suspend_stuck_loop_sessions.<locals>.<listcomp>Þ&  s*   ø€ ÐVÐVÐV™D˜A˜q°a¸4Ô;UÒ6UÐ6U�aÐ6UÐ6UÐ6UrM   Tr(   u_   Auto-suspended stuck session %s (active across %d consecutive restarts â€” likely a stuck loop)rs  )r3  rl  rr
  r˜   r4  rX  r2   rñ  r›  rÄ  rv   Ú	suspendedr3   rã   rË  ru  )r  r3  r™   rs
  ry
  Ú
stuck_keysr+   r®  s   `       r>   Ú_suspend_stuck_loop_sessionsz*GatewayRunner._suspend_stuck_loop_sessionsË&  sÂ  ø€ ð 	ˆˆˆå˜dÔ3Ñ3ˆØ�{Š{‰}Œ}ð 	Ø�1ð	Ø�T”Z §¢¸ Ñ @Ô @ÑAÔAˆFˆFøÝð 	ð 	ð 	Ø�1�1ð	øøøð ˆ	ØVÐVÐVÐV F§L¢L¡N¤NÐVÑVÔVˆ
à%ð 	ð 	ˆKðØÔ*Ô3×7Ò7¸ÑDÔD�Øð  ¤ð Ø&*�E”OØ ‘N�IÝ—N’NðHà# V¨KÔ%8ñô ð øøõ
 ð ð ð Ø�ðøøøð ð 	ðØÔ"×(Ò(Ñ*Ô*Ð*Ð*øÝð ð ð Ø�ðøøøð	Ø�KŠK 4ˆKÑ(Ô(Ð(Ð(øÝð 	ð 	ð 	ØˆDð	øøøð ÐsH   ¬$A Á
AÁAÂ	AC Ã 
C-Ã,C-Ã3D Ä
DÄDÄD5 Ä5
EÅEc                 ó.  — ddl }t          | j        z  }|                     ¦   «         sdS 	  |j        |                     d¬¦  «        ¦  «        }||v r1||= |rt          ||d¬¦  «         dS |                     d¬¦  «         dS dS # t          $ r Y dS w xY w)z—Clear the restart-failure counter for a session that completed OK.

        Called after a successful agent turn to signal the loop is broken.
        r   NrQ  r‚  ró  Trs  )	r3  rl  rr
  r˜   r4  rX  rz  ru  r2   )r  r+   r3  r™   rs
  s        r>   Ú_clear_restart_failure_countz*GatewayRunner._clear_restart_failure_countü&  sÏ   € ð
 	ˆˆˆå˜dÔ3Ñ3ˆØ�{Š{‰}Œ}ð 	ØˆFð		Ø�T”Z §¢¸ Ñ @Ô @ÑAÔAˆFØ˜fÐ$Ð$Ø˜;Ð'Øð 1Ý% d¨F¸4Ð@Ñ@Ô@Ð@Ð@Ð@à—K’K¨4�KÑ0Ô0Ð0Ð0Ð0ð %Ð$øõ ð 	ð 	ð 	ØˆDˆDð	øøøs   «?B Á,B Â
BÂBc           	   ƒ   óÀ  K  — dd l }dd l}t          ¦   «         }|st                               d¦  «         d S | j        rd S d| _        t          j        ¦   «         }t          t          t          | dd¦  «        pd¦  «        dz   d¦  «        }t          j        dk    �rydd l}ddlm}m} g |¢d	‘d
‘}	|                     d¦  «                             ¦   «         }
ddlm}  |dd¬¦  «        }|                     dd ¦  «         t-          t.          ¦  «                             ¦   «         j        j        }t          j        }t-          |                     d¦  «        p|dz  ¦  «        }|dz  dz  }|                     ¦   «         ršt;          |¦  «        |d<   t;          |¦  «        t;          |¦  «        g}|                     d¦  «        r|                     |d         ¦  «         t          j                              tB           "                    |¦  «        ¦  «        |d<   |d|
t;          |¦  «        t;          |¦  «        g|	¢}	  |j#        |f|j$        |j$        |dœ |¦   «         ¤Ž n±# tJ          $ r¤ 	 | #                    ||j$        |j$        | |¦   «         ¬¦  «         ns# tJ          $ rf}t          |dd ¦  «        }|�|n|j&        }|�dnd}t           '                    dt          j(         )                    |¦  «        ||¦  «         Y d }~nd }~ww xY wY nw xY wd S d                      d„ |D ¦   «         ¦  «        }dtU          |¦  «        › d|› d|› d �}ddlm}  |dd¬¦  «        }|                     dd ¦  «         | +                    d!¦  «        }|r*| #                    |d"d#|g|j$        |j$        |d¬$¦  «         d S | #                    d"d#|g|j$        |j$        |d¬$¦  «         d S )%Nr   z4Could not locate hermes binary for detached /restartTr'  r@  r&   rˆ   )Ú&windows_detach_flags_without_breakawayÚwindows_detach_popen_kwargsr9   r	  uù  
                import os, subprocess, sys, time
                from hermes_cli._subprocess_compat import windows_detach_flags_without_breakaway
                pid = int(sys.argv[1])
                restart_after_s = float(sys.argv[2])
                cmd = sys.argv[3:]
                deadline = time.monotonic() + restart_after_s

                def _alive(p):
                    # On Windows, os.kill(pid, 0) is NOT a no-op â€” it maps to
                    # GenerateConsoleCtrlEvent(0, pid) (bpo-14484). Use the
                    # Win32 handle-based existence check instead.
                    if os.name == 'nt':
                        import ctypes
                        k32 = ctypes.windll.kernel32
                        k32.OpenProcess.restype = ctypes.c_void_p
                        k32.WaitForSingleObject.restype = ctypes.c_uint
                        k32.GetLastError.restype = ctypes.c_uint
                        h = k32.OpenProcess(0x1000 | 0x100000, False, int(p))
                        if not h:
                            return k32.GetLastError() != 87
                        try:
                            return k32.WaitForSingleObject(h, 0) == 0x102
                        finally:
                            k32.CloseHandle(h)
                    try:
                        os.kill(int(p), 0)
                        return True
                    except ProcessLookupError:
                        return False
                    except PermissionError:
                        return True
                    except OSError:
                        return False

                while time.monotonic() < deadline:
                    if not _alive(pid):
                        break
                    time.sleep(0.2)
                subprocess.Popen(
                    cmd,
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL,
                    creationflags=windows_detach_flags_without_breakaway(),
                )
                ©Úbuild_subprocess_envF)Úscrub_secretsÚinherit_profile_homerw  r‰   rŠ   r‹   rŒ   r�   ú-c©r  r  Úenv)r  r  r‡
  ÚcreationflagsÚwinerrorÚerrnoz�Detached restart watcher was not started after the no-breakaway retry (%s; %s=%r). The gateway will not be respawned by this restart attempt.r™  c              3   ó>   K  — | ]}t          j        |¦  «        V — Œd S r^   )rc	  Úquotera   s     r>   rd   zAGatewayRunner._launch_detached_restart_command.<locals>.<genexpr>¬'  s,   è è € Ð@Ð@¨T•u”{ 4Ñ(Ô(Ð@Ð@Ð@Ð@Ð@Ð@rM   zdeadline=$(( $(date +%s) + z )); while kill -0 zC 2>/dev/null && [ $(date +%s) -lt $deadline ]; do sleep 0.2; done; z gateway restartÚsetsidÚbashú-lc)r  r  r‡
  Ústart_new_session),r¨  r  r°  r3   rP   r0  r’   ÚgetpidrC  ri  rV   rŽ   r�   ÚtextwrapÚhermes_cli._subprocess_compatr
  r€
  Údedentrx   Útools.environments.localr‚
  rU  r   r�   r�   r‘   r­  rv   r˜   rw   r”   rž   rf   ru   rŸ   ÚPopenÚDEVNULLr–   rŠ
  rã   r™   Úbasenamerh  r©  )r  r¨  r  Ú
hermes_cmdÚcurrent_pidÚrestart_after_sr’
  r
  r€
  Úcmd_argvÚwatcherr‚
  Úwatcher_envr    Úwatcher_pythonr£   r¦   rª   Úwatcher_argvr<   r‰
  r²  Úerror_fieldrù   Ú	shell_cmdÚ
setsid_bins                             r>   Ú _launch_detached_restart_commandz.GatewayRunner._launch_detached_restart_command'  s  è è € ØˆˆˆØÐÐÐå(Ñ*Ô*ˆ
Øð 	Ý�LŠLÐOÑPÔPÐPØˆFØÔ0ð 	ØˆFØ04ˆÔ-å”i‘k”kˆÝ�e¥G¨DÐ2JÈCÑ$PÔ$PÐ$WÐTWÑXÔXÐ[^Ñ^Ð`cÑdÔdˆõ Œ<˜7Ò"Ñ"ØˆOˆOˆOðð ð ð ð ð ð ð ð
 ;˜Ð: YÐ:°	Ð:ˆHØ—o’oð-ñ/ô /÷^ Še‰gŒgð_ ð` FÐEÐEÐEÐEÐEØ.Ð.¸UÐY]Ð^Ñ^Ô^ˆKð �OŠOÐ-¨tÑ4Ô4Ð4Ý¥™>œ>×1Ò1Ñ3Ô3Ô:ÔAˆLõ !œ^ˆNÝ˜KŸOšO¨MÑ:Ô:ÐS¸lÈVÑ>SÑTÔTˆHØ$ uÑ,¨Ñ>ˆMØ×#Ò#Ñ%Ô%ð WÝ-0°©]¬]�˜MÑ*Ý! ,Ñ/Ô/µ°]Ñ1CÔ1CÐD�
Ø—?’? <Ñ0Ô0ð AØ×%Ò% k°,Ô&?Ñ@Ô@Ð@Ý,.¬J¯OªO½D¿MºMÈ*Ñ<UÔ<UÑ,VÔ,V�˜LÑ)àØØÝ�KÑ Ô Ý�OÑ$Ô$ðð ðˆLð$$Ø �
Ô Ø ðà%Ô-Ø%Ô-Ø#ð	ð ð
 2Ð1Ñ3Ô3ðð ð ð øõ ð ð ð ðØ×$Ò$Ø$Ø)Ô1Ø)Ô1Ø'Ø&LÐ&LÑ&NÔ&Nð %ñ ô ð ð øõ ð ð ð õ  ' s¨J¸Ñ=Ô=�HØ-5Ð-A  ÀsÄy�JØ08Ð0D * *È'�KÝ—N’Nð@õ œ×(Ò(¨Ñ8Ô8Ø#Ø"ñô ð ð ð ð ð ð øøøøðøøøøøðøøøð: ˆFà�hŠhÐ@Ð@°ZÐ@Ñ@Ô@Ñ@Ô@ˆð%­#¨oÑ*>Ô*>ð %ð %Ø(ð%ð %àð%ð %ð %ð 	ð 	BÐAÐAÐAÐAÐAØ*Ð*¸ÐUYÐZÑZÔZˆØ�ŠÐ)¨4Ñ0Ô0Ð0Ø—\’\ (Ñ+Ô+ˆ
Øð 	Ø×ÒØ˜V U¨IÐ6Ø!Ô)Ø!Ô)ØØ"&ð ñ ô ð ð ð ð ×ÒØ˜ 	Ð*Ø!Ô)Ø!Ô)ØØ"&ð ñ ô ð ð ð s=   È=$I" É"
LÉ-,JÊLÊ
L
Ê$ALÌ LÌL
Ì
LÌLc           
      ó|  ‡‡‡— t           j        dk    st          j                             d¦  «        sdS 	 ddl}ddlŠ|                     d¦  «        }|                     d¦  «        Š|r‰sdS 	 ddlm	}  |¦   «         Šn# t          $ r dŠY nw xY wt          j        ¦   «         }ˆˆˆfd	„} |g ¦  «        } |d
g¦  «        }t          |¦  «        |k    rg }d}	nt          |¦  «        |k    rd
g}d}	ndS t          j        ‰¦  «        }
d|› d|	› d|
› d|	› d|
› �
}‰› d|› �                     dd¦  «        }‰                     |g|¢d‘d‘|‘d‘d‘|‘‰j        ‰j        d¬¦  «         t$                               d‰||rdnd¦  «         dS # t          $ r&}t$                               d|¦  «         Y d}~dS d}~ww xY w)añ  Best-effort helper to bypass systemd's automatic restart delay.

        For planned in-chat restarts, the gateway exits cleanly so systemd does
        not record a failure.  However, units with RestartSteps still count
        automatic restarts and can delay repeated /restart tests.  A transient
        user service survives our cgroup teardown and explicitly starts the
        gateway as soon as this PID exits, while the unit keeps its normal
        backoff for real crash loops.
        ÚlinuxÚINVOCATION_IDNr   zsystemd-runÚ	systemctl)Úget_service_nameúhermes-gatewayc                 óª   •— 	 ‰                      ‰g| ¢d‘‰‘d‘d‘ddddd¬¦  «        }|j        pd	                     ¦   «         S # t          $ r Y d	S w xY w)
NÚshowz--property=MainPIDz--valueTrQ  rl  r|  )Úcapture_outputrè   rR  rS  rÓ  r®   )Úrunr  rx   r2   )Úscope_flagsÚoutÚservice_namer  r¨
  s     €€€r>   Ú
_query_pidzBGatewayRunner._launch_systemd_restart_shortcut.<locals>._query_pidó'  s—   ø€ ðØ$Ÿ.š.Ø"ð : [ð :°&ð :¸,ð :Ø-ð:Ø/8ð:à'+°$ÀÐQZÐdeð )ñ ô �Cð
  œJÐ,¨"×3Ò3Ñ5Ô5Ð5øÝ ð ð ð Ø˜2˜2ðøøøs   ƒA A Á
AÁAz--userzsystemctl --userzwhile kill -0 z" 2>/dev/null; do sleep 0.2; done; z reset-failed ú; z	 restart z-planned-restart-r
  rW  z	--collectz--unitz/bin/shr�
  T)r  r  r�
  zALaunched systemd planned-restart helper for %s (pid=%s, scope=%s)r¬  rß  z3Failed to launch systemd planned-restart helper: %s)rŽ   r�   r’   r“   rv   r¨  r  r©  Úhermes_cli.gatewayr©
  r2   r‘
  rw   rc	  rŒ
  rl  r–
  r—
  r3   rz  r4   )r  r¨  Úsystemd_runr©
  rš
  r²
  Ú
system_pidÚuser_pidr¯
  Úsystemctl_scopeÚservice_argr¢
  Ú	unit_namer¨  r±
  r  r¨
  s                 @@@r>   Ú _launch_systemd_restart_shortcutz.GatewayRunner._launch_systemd_restart_shortcutÌ'  sÞ  øøø€ õ Œ<˜7Ò"Ð"­"¬*¯.ª.¸Ñ*IÔ*IÐ"ØˆFðP	SØˆMˆMˆMØÐÐÐà Ÿ,š, }Ñ5Ô5ˆKØŸš [Ñ1Ô1ˆIØð  ið Ø�ð0Ø?Ð?Ð?Ð?Ð?Ð?à/Ð/Ñ1Ô1��øÝð 0ð 0ð 0Ø/���ð0øøøõ œ)™+œ+ˆKð	ð 	ð 	ð 	ð 	ð 	ð 	ð $˜ B™œˆJØ!�z 8 *Ñ-Ô-ˆHÝ�;ÑÔ :Ò-Ð-Ø �Ø"-��Ý�[Ñ!Ô! XÒ-Ð-Ø'˜j�Ø"4��ð
 �åœ+ lÑ3Ô3ˆKð; ð ;ð ;Ø"ð;ð ;Ø2=ð;ð ;à"ð;ð ;à-8ð;ð ;ð ð
 (ÐGÐG¸+ÐGÐG×OÒOÐPSÐUXÑYÔYˆIØ×Òàð	à ð	ð  ð	ð ð		ð
 ð	ð ð	ð ð	ð ð	ð "Ô)Ø!Ô)Ø"&ð ñ ô ð õ �KŠKØSØØØ%Ð3��¨8ñ	ô ð ð ð øõ ð 	Sð 	Sð 	SÝ�LŠLÐNÐPQÑRÔRÐRÐRÐRÐRÐRÐRÐRøøøøð	SøøøsC   ¶6F Á/B  Á?F Â BÂF ÂBÂA%F Ã6BF Æ
F;ÆF6Æ6F;c              ƒ   óÈ  K  — |                       ¦   «         }|dk    rdS t          t          | dd¦  «        pd¦  «        }|dk    rt                               d|¦  «         dS t                               d||¦  «         	 |                      d¦  «         n# t          $ r Y nw xY wt          j        ¦   «         }| 	                    ¦   «         |z   }d}|                       ¦   «         dk    rß| 	                    ¦   «         }||k    r0t           
                    d	||                       ¦   «         ¦  «         dS ||z
  d
k    rZt                               d|                       ¦   «         ||z
  ¦  «         	 |                      d¦  «         n# t          $ r Y nw xY w|}t          j        d¦  «        ƒ d{V —† |                       ¦   «         dk    °ßt                               d¦  «         dS )až  Wait for in-flight work to finish before entering ``stop()``.

        In-band restart used to call ``stop()`` immediately, which folded the
        requesting turn into the drain wait set and force-interrupted it at
        ``restart_drain_timeout`` (#77184). Instead we refuse new turns and
        wait here for active agents/cron/api work to reach zero, then let
        ``stop()`` run against an idle gateway (drain is instant).

        Returns True when work drained to zero, False when the safety cap
        elapsed with work still active (caller proceeds to ``stop()``, which
        may then interrupt remaining runs under ``restart_drain_timeout``).
        r   Tr(  r@  uq   Restart requested with %d active work unit(s); restart_after_turn_timeout=0 â€” entering stop()/drain immediatelyFz‹Restart requested with %d active work unit(s); deferring stop() until they finish (cap=%.0fs) so in-flight turns are not amputated (#77184)r	  zŠRestart after-turn wait timed out after %.0fs with %d still active; proceeding to stop()/drain which may interrupt remaining work (#77184)r%   zXRestart deferred: waiting on %d active work unit(s) (%.0fs remaining before force drain)r)
  NuL   Restart deferred wait complete â€” active work drained; proceeding to stop())rÀ  ri  rV   r3   rz  r	  r2   r  r!
  rU   rã   r–  )r  rö  rÓ  rØ   r+
  r'
  rŒ  s          r>   Ú!_await_active_work_before_restartz/GatewayRunner._await_active_work_before_restart+(  s?  è è € ð ×(Ò(Ñ*Ô*ˆØ�QŠ;ˆ;Ø�4å� Ð&CÀSÑIÔIÐPÈSÑQÔQˆØ�aŠ<ˆ<Ý�KŠKðUàñô ð ð
 �5å�Šð/ð Øñ	
ô 	
ð 	
ð	Ø×'Ò'¨
Ñ3Ô3Ð3Ð3øÝð 	ð 	ð 	ØˆDð	øøøõ Ô'Ñ)Ô)ˆØ—9’9‘;”; Ñ(ˆØˆØ×%Ò%Ñ'Ô'¨!Ò+Ð+Ø—)’)‘+”+ˆCØ�hŠˆÝ—’ð8ð Ø×+Ò+Ñ-Ô-ñô ð ð �uØ�nÑ$¨Ò-Ð-Ý—’ð;à×+Ò+Ñ-Ô-Ø˜s‘Nñ	ô ð ðØ×/Ò/°
Ñ;Ô;Ð;Ð;øÝ ð ð ð Ø�Dðøøøà!$�Ý”- Ñ$Ô$Ð$Ð$Ð$Ð$Ð$Ð$Ð$ð/ ×%Ò%Ñ'Ô'¨!Ò+Ð+õ2 	�Šð#ñ	
ô 	
ð 	
ð ˆts$   Á?B Â
B"Â!B"Å.F Æ
FÆF©ÚdetachedÚvia_servicer¿
  rÀ
  c                ó¶   ‡ ‡‡— ‰ j         rdS d‰ _        ‰‰ _        ‰‰ _        d‰ _         d‰ _        dˆˆ ˆfd„}t          j         |¦   «         ¦  «        ‰ _        dS )NFTr-   c               “   óP  •K  — ‰                      ¦   «         ƒ d {V —† ‰rN	 ‰                     ¦   «         ƒ d {V —† n2# t          $ r%} t                               d| ¦  «         Y d } ~ nd } ~ ww xY wt          j        d¦  «        ƒ d {V —† ‰                     d‰‰¬¦  «        ƒ d {V —† d S )Nz4Failed to launch detached gateway restart helper: %sr¦  T©r	  Údetached_restartÚservice_restart)r½
  r¤
  r2   r3   rP   r  r–  r¨  )r¨  r¿
  r  rÀ
  s    €€€r>   Ú_run_restartz3GatewayRunner.request_restart.<locals>._run_restart(  sþ   øè è € Ø×8Ò8Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:ð
 ð \ð\Ø×?Ò?ÑAÔAÐAÐAÐAÐAÐAÐAÐAÐAøÝ ð \ð \ð \Ý—L’LÐ!WÐYZÑ[Ô[Ð[Ð[Ð[Ð[Ð[Ð[øøøøð\øøøå”- Ñ%Ô%Ð%Ð%Ð%Ð%Ð%Ð%Ð%Ø—)’) D¸8ÐU`�)ÑaÔaÐaÐaÐaÐaÐaÐaÐaÐaÐas   ¡< ¼
A+ÁA&Á&A+rŽ  )r-  r,  r.  r/  r*  r  r”  r3  )r  r¿
  rÀ
  rÆ
  s   ``` r>   Úrequest_restartzGatewayRunner.request_restarts(  sŽ   øøø€ ØÔ%ð 	Ø�5Ø"&ˆÔØ!)ˆÔØ$/ˆÔ!Ø%)ˆÔ"ð ˆŒð	bð 	bð 	bð 	bð 	bð 	bð 	bð 	bõ4 %Ô0°°±´Ñ@Ô@ˆÔØˆtrM   >   r—  r˜  Úrestart_interruptedc              ƒ   ó  K  — 	 |                      |¦  «        ƒ d{V —† t          |di ¦  «        }t          |t          ¦  «        r|                     |¦  «        nd}|�t          j        |¦  «        ƒ d{V —† |                      |¦  «        }|r|j        j	        ndt          u r|                      |¦  «         dS dS # |                      |¦  «        }|r|j        j	        ndt          u r|                      |¦  «         w w xY w)aã  Dispatch one synthetic startup resume and wait for its agent turn.

        ``BasePlatformAdapter.handle_message()`` returns after it installs the
        adapter-level guard and spawns the background processing task.  Startup
        restore needs a stronger boundary: inbound messages must stay queued
        until the resumed agent turn itself has finished, otherwise a user
        message can race the restore turn immediately after ``handle_message``
        returns.
        NÚ_session_tasks)Úhandle_messagerV   rt   ru   rv   r  r–  rA   rJ  rµ   rž  Ú_release_running_agent_state)r  r1  rÖ  r+   Úsession_tasksrÝ   Ú
_pre_states          r>   Ú_run_startup_resume_eventz'GatewayRunner._run_startup_resume_event¥(  s7  è è € ð	?Ø×(Ò(¨Ñ/Ô/Ð/Ð/Ð/Ð/Ð/Ð/Ð/Ý# GÐ-=¸rÑBÔBˆMÝ5?ÀÍtÑ5TÔ5TÐ^�=×$Ò$ [Ñ1Ô1Ð1ÐZ^ˆDØÐÝ”n TÑ*Ô*Ð*Ð*Ð*Ð*Ð*Ð*Ð*ð ×1Ò1°+Ñ>Ô>ˆJØ)3Ð=�
”Ô%Ð%¸ÕBYÐYÐYØ×1Ò1°+Ñ>Ô>Ð>Ð>Ð>ð ZÐYøð ×1Ò1°+Ñ>Ô>ˆJØ)3Ð=�
”Ô%Ð%¸ÕBYÐYÐYØ×1Ò1°+Ñ>Ô>Ð>Ð>ð Zøøøs   „A4B= Â=ADc                 ó  — t          | dd ¦  «        }|€	g }|| _         |j        |¦  «         	 |j        }t                               d|r|j        r|j        j        nd|r|j        nd¦  «         d S # t          $ r Y d S w xY w)NrŸ  zJQueued inbound message during gateway startup restore: platform=%s chat=%sr¼  )
rV   rŸ  r”   r(  r3   rz  r�   r­   r2  r2   )r  rÖ  r™  r(  s       r>   Ú_queue_startup_restore_eventz*GatewayRunner._queue_startup_restore_eventÃ(  s²   € Ý˜Ð6¸Ñ=Ô=ˆØˆ=ØˆEØ*/ˆDÔ'ØˆŒ�UÑÔÐð	Ø”\ˆFÝ�KŠKØ\Ø)/ÐR°F´OÐR�”Ô%Ð%ÈØ"(Ð7�”�¨iñô ð ð ð øõ
 ð 	ð 	ð 	ØˆDˆDð	øøøs   ®AA1 Á1
A?Á>A?c           
   ƒ   óª  K  — d}t          | dd¦  «        }|€dS |r· |j        d¦  «        }t          |dd¦  «        }|                      |¦  «        }|€:t                               dt          t          |dd¦  «        dd¦  «        ¦  «         Œt	 t          |dd	¦  «         n# t          $ r Y nw xY w|                     |¦  «        ƒ d{V —† |d
z  }|°·|S )z=Replay inbound messages queued while startup auto-resume ran.r   rŸ  Nr(  zCDropping startup-restore queued message: adapter unavailable for %sr�   r­   Ú_hermes_startup_restore_replayTr(   )rV   rU  r@  r3   r4   Úsetattrr2   rË
  )r  Údrainedr™  rÖ  r(  r1  s         r>   Ú_drain_startup_restore_queuez*GatewayRunner._drain_startup_restore_queueÓ(  s  è è € àˆÝ˜Ð6¸Ñ=Ô=ˆØˆ=Ø�1Øð 	Ø�E”I˜a‘L”LˆEÝ˜U H¨dÑ3Ô3ˆFØ×.Ò.¨vÑ6Ô6ˆGØˆÝ—’ØYÝ�G F¨J¸Ñ=Ô=¸wÈÑMÔMñô ð ð ðÝ˜Ð?ÀÑFÔFÐFÐFøÝð ð ð Ø�ðøøøà×(Ò(¨Ñ/Ô/Ð/Ð/Ð/Ð/Ð/Ð/Ð/Ø�q‰LˆGð# ð 	ð$ ˆs   ÂB! Â!
B.Â-B.c              ƒ   óè  K  — t          t          | dg ¦  «        pg ¦  «        }|�rt          ¦   «         }|dk    rjt          j        ||¬¦  «        ƒ d{V —†\  }}|rHt
                               d|t          |¦  «        ¦  «         |D ]}|                     | j	        ¦  «         Œn&t          j
        |ddiŽƒ d{V —† t          |¦  «        }|D ]^}|                     ¦   «         rŒ|                     ¦   «         }|�1t
                               dt          |¦  «        ||j        f¬	¦  «         Œ_g | _        |                      ¦   «         ƒ d{V —†}d
| _        |rt
                               d|¦  «         dS dS )u	  Wait (BOUNDED) for startup auto-resume, then release + drain inbound.

        The wait is bounded by ``_startup_restore_drain_timeout_secs`` so that
        a single pathologically long boot-resume turn cannot hold the inbound
        gate shut for every channel.  On timeout we release the gate and let
        the still-running resume turn(s) finish in the background â€” they are
        NOT cancelled.  This is safe because duplicate-agent protection does
        not depend on the wait: ``_schedule_resume_pending_sessions`` claims
        each session's ``_running_agents`` slot SYNCHRONOUSLY before this gate
        runs, so any inbound message drained while a resume turn is still in
        flight queues behind that slot instead of spawning a second agent.
        r   r   r  NzÕStartup-restore gate released after %.0fs with %d boot auto-resume turn(s) still running; draining inbound queue now (resume slots already claimed, so no duplicate agents). Slow turn(s) continue in the background.Úreturn_exceptionsTzstartup auto-resume task failedrß   Fz;Drained %d inbound message(s) queued during startup restore)r½  rV   ry  r  rB  r3   rã   r7   rä  Ú_log_background_resume_resultÚgatherr•   r  rÛ   r4   rÎ   rä   r   rÖ
  r6  rz  )r  r—  rÓ  r  r5  rÝ   r<   rÕ
  s           r>   Ú_finish_startup_restorez%GatewayRunner._finish_startup_restoreí(  sÓ  è è € õ •W˜TÐ#;¸RÑ@Ô@ÐFÀBÑGÔGˆØñ %	Ý9Ñ;Ô;ˆGØ˜Š{ˆ{õ '.¤l°5À'Ð&JÑ&JÔ&JÐ JÐ JÐ JÐ JÐ JÐ J‘��gØð SÝ—N’Nð&ð
  Ý˜G™œñô ð ð !(ð Sð S˜Ø×.Ò.¨tÔ/QÑRÔRÐRÐRøõ ”n eÐD¸tÐDÐDÐDÐDÐDÐDÐDÐDÐDÝ˜5‘z”z�Øð ð �Ø—>’>Ñ#Ô#ð ØØ—n’nÑ&Ô&�Ø�?Ý—L’LØ9Ý"& s¡)¤)¨S°#Ô2CÐ!Dð !ñ ô ð øð ')ˆÔ#Ø×9Ò9Ñ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;ˆØ,1ˆÔ)Øð 	`Ý�KŠKÐUÐW^Ñ_Ô_Ð_Ð_Ð_ð	`ð 	`rM   rÝ   c                 óÄ   — |                       ¦   «         rdS |                      ¦   «         }|�3t                               dt	          |¦  «        ||j        f¬¦  «         dS dS )a  Done-callback for a boot-resume turn that outlived the
        startup-restore gate.  Logs a late failure that would otherwise be
        swallowed once the task is discarded from ``_background_tasks``.
        Cancellation is expected (shutdown) and is not an error.Nz=background startup auto-resume task failed after gate releaserß   )r  rÛ   r3   r4   rÎ   rä   rÈ  s     r>   rÙ
  z+GatewayRunner._log_background_resume_result')  sq   € ð �>Š>ÑÔð 	ØˆFØ�nŠnÑÔˆØˆ?Ý�LŠLØOÝ˜s™)œ) S¨#Ô*;Ð<ð ñ ô ð ð ð ð ˆ?rM   c              ƒ   óü  K  — 	 ddl m}m}m}m}m} t          j        |¦  «        ƒ d{V —†sdS d„ | j        D ¦   «         }t          j        |d|¬¦  «        ƒ d{V —†}n-# t          $ r  t                               dd¬¦  «         Y dS w xY w|sdS d}|D �]h}		 t          |	d	         ¦  «        }
nE# t          $ r8 t                               d
|	d         |	                     d	¦  «        ¦  «         Y Œ[w xY w| j                             |
¦  «        }|€Œ||	d         }|	                     d¦  «        r||z   }|	                     d¦  «        r
d|	d         ind}	 |                     |	d         ||¬¦  «        ƒ d{V —†}n;# t          $ r.}t                               d|	d         |¦  «         d}Y d}~nd}~ww xY w	 |�nt!          |dd¦  «        r]t          j        ||	d         ¦  «        ƒ d{V —† |dz  }t                               d|	d	         |	d         |	d         |	d         ¦  «         n@t          j        ||	d         t%          t!          |dd¦  «        pd¦  «        ¦  «        ƒ d{V —† n,# t          $ r t                               dd¬¦  «         Y nw xY w|	                     d¦  «        pd}|rQ	 | j                             |¦  «        ƒ d{V —† �Œ:# t          $ r! t                               d|d¬¦  «         Y �Œdw xY w�Œj|S )u  Redeliver final responses recorded in the delivery ledger by a
        previous (now dead) gateway process.

        Runs at startup BEFORE ``_schedule_resume_pending_sessions``. A
        session with a recoverable obligation already produced its answer â€”
        the turn completed and only delivery is owed â€” so this method sends
        the stored text and clears ``resume_pending`` for that session,
        preventing the resume path from re-running (and re-paying for) a
        turn whose output we hold.

        Crash-ambiguity contract (see gateway/delivery_ledger.py):
        rows that were mid-send or previously rejected carry a visible
        recovered-reply marker so a possible duplicate is labeled, never
        silent. Returns the number of redeliveries attempted.
        r   )ÚRECOVERED_MARKERÚledger_enabledÚmark_deliveredÚmark_failedÚsweep_recoverableNc           	      óJ   — h | ] }t          |d t          |¦  «        ¦  «        ’Œ!S rç  )rV   rw   r:  s     r>   rQ  z?GatewayRunner._redeliver_pending_obligations.<locals>.<setcomp>T)  s7   € ð ð ð Ø01•˜˜7¥C¨¡F¤FÑ+Ô+ðð ð rM   )Údeliverable_platformszdelivery ledger sweep failedTrß   r�   z"obligation %s: unknown platform %rÚobligation_idr4  Úneeds_markerr›  r2  ©r2  r4  r¯   z)obligation %s: redelivery send raised: %sr/  Fr(   zIRedelivered recovered final response to %s:%s (obligation %s, attempt %d)r›  rP   r®   zsend failedzdelivery ledger update failedr+   z"clear_resume_pending failed for %s)Úgateway.delivery_ledgerrÞ
  rß
  rà
  rá
  râ
  r  r  r°  r2   r3   r4   rÄ  rv   r0  rã   rV   rz  rw   r8
  Úclear_resume_pending)r  rÞ
  rß
  rà
  rá
  râ
  Ú_deliverableÚclaimedÚredeliveredr�  r�   r1  r4  r¯   r·  Úsend_errr+   s                    r>   Ú_redeliver_pending_obligationsz,GatewayRunner._redeliver_pending_obligations6)  s€  è è € ð 	ðð ð ð ð ð ð ð ð ð ð ð ð ð õ !Ô*¨>Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:ð Ø�qðð Ø59´]ðñ ô ˆLõ $Ô-Ø! 4¸|ðñ ô ð ð ð ð ð ð ˆGˆGøõ ð 	ð 	ð 	Ý�LŠLÐ7À$ˆLÑGÔGÐGØ�1�1ð	øøøð ð 	Ø�1àˆØð =	ñ =	ˆCðÝ# C¨
¤OÑ4Ô4��øÝð ð ð Ý—’Ø8Ø˜Ô(¨#¯'ª'°*Ñ*=Ô*=ñô ð ð �ðøøøð ”m×'Ò'¨Ñ1Ô1ˆGØˆð Ø˜)”nˆGØ�wŠw�~Ñ&Ô&ð 5Ø*¨WÑ4�à36·7²7¸;Ñ3GÔ3GÐQ�˜c +Ô.Ð/Ð/ÈTð ðØ&Ÿ|š|Ø 	œNØ#Ø%ð  ,ñ  ô  ð ð ð ð ð ð ��øõ
 ð ð ð Ý—’Ø?Ø˜Ô(¨(ñô ð ð ������øøøøðøøøðMØÐ%­'°&¸)ÀUÑ*KÔ*KÐ%Ý!Ô+¨N¸CÀÔ<PÑQÔQÐQÐQÐQÐQÐQÐQÐQØ 1Ñ$�KÝ—K’Kð6à˜Jœ¨¨Y¬Ø˜OÔ,¨c°*¬oñ	ô ð ð õ "Ô+Ø#Ø˜OÔ,Ý�G F¨G°RÑ8Ô8ÐI¸MÑJÔJñô ð ð ð ð ð ð ð øøõ
 ð Mð Mð MÝ—’Ð<Àt�ÑLÔLÐLÐLÐLðMøøøð
 Ÿ'š' -Ñ0Ô0Ð6°BˆKØð ðØÔ2×GÒGÈÑTÔTÐTÐTÐTÐTÐTÐTÐTÑTøÝ ð ð ð Ý—L’LØ<¸kØ!%ð !ñ ô ð ð ñ ðøøøñð Ðse   „(A ®.A Á&BÂBÂB,Â,?C.Ã-C.Å$E7Å7
F/Æ$F*Æ*F/Æ3B0I$É$&JÊJÊ* KË'K7Ë6K7c           
      ó  ‡ ‡— t          ¦   «         }	 ‰ j        j        5  ‰ j                             ¦   «          ˆˆ fd„‰ j        j                             ¦   «         D ¦   «         }ddd¦  «         n# 1 swxY w Y   n3# t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w|rl	 ddl	m
} ‰                      ¦   «         \  }}}|                     |||¬¦  «        rdS n2# t          $ r%}t                               d|¦  «         Y d}~nd}~ww xY wt          j        ¦   «         }	d}
|D �];}|j        p|j        }|�|	|z
                       ¦   «         |k    rŒ/‰                      |j        ¦  «        rŒJ|j        }‰                      |¦  «        }|€;t                               d|j        t/          |j        d	|j        ¦  «        ¦  «         Œ£	 ‰                      |¦  «        s!t                               d
|j        ¦  «         ŒÚn9# t          $ r,}t                               d|j        |¦  «         Y d}~�Œd}~ww xY w‰                      |j        ¦  «        }t6          |j        _        t=          j        ¦   «         |j        _        ‰                       ¦   «          tC          dtD          j#        |d¬¦  «        }tI          j%        ‰  &                    |||j        ¦  «        ¦  «        }‰ j'         (                    |¦  «         | )                    ‰ j'        j*        ¦  «         t/          ‰ dd¦  «        r1t/          ‰ dd¦  «        }|€	g }|‰ _+        | ,                    |¦  «         |
dz  }
�Œ=|
rt           -                    d|
¦  «         |
S )uõ  Auto-continue fresh restart-interrupted sessions after startup.

        ``resume_pending`` already preserves the transcript AND the existing
        ``_is_resume_pending`` branch in ``_handle_message_with_agent``
        injects a reason-aware recovery system note on the next turn.  This
        method closes the UX gap by synthesizing that next turn once
        adapters are back online â€” the event text is empty so the existing
        injection path owns the wording and we never double up.

        Adapters that are not yet ready (adapter missing from
        ``self.adapters``) are skipped silently; their sessions stay
        ``resume_pending`` and will auto-resume on the next real user
        message, or when the platform reconnects â€” the reconnect watcher
        calls this again scoped to that ``platform``.

        ``platform`` (a ``Platform``) restricts the pass to sessions that
        originated on that platform.  The reconnect path passes it so a
        platform coming back online retries only its own sessions and never
        re-touches another platform's in-flight recoveries.  Sessions whose
        agent is already running are skipped regardless, so a session
        scheduled at startup is never resumed a second time.
        c                 ó~   •— g | ]9}|j         r0|j        s)|j        �"|j        ‰j        v r‰�|j        j        ‰k    ¯7|‘Œ:S r^   )rj  ry
  r3
  rl  Ú_AUTO_RESUME_REASONSr�   )rb   r®  r�   r  s     €€r>   r  zCGatewayRunner._schedule_resume_pending_sessions.<locals>.<listcomp>¼)  sm   ø€ ð ð ð Ø#ØÔ+ðð "œOðð œÐ0ØÔ+¨tÔ/HÐHÐHØ!Ð)¨U¬\Ô-BÀhÒ-NÐ-Nð ð
 .OÐ-NÐ-NrM   Nz/Failed to enumerate resume-pending sessions: %sr   rÙ  )rÝ  z$Restart-loop guard check skipped: %sz5Skipping auto-resume for %s: adapter not ready for %sr­   z^Skipping auto-resume for %s: session owner is no longer authorized under the current allowlistz;Skipping auto-resume for %s: authorization check failed: %sr®   T)rè   rÚ  r(  rã	  r6  Fr   r(   z;Scheduled auto-resume for %d restart-interrupted session(s)).rs  r›  rº	  r»	  rÄ  r•  r2   r3   rã   r9   rÚ  rã  Úcheck_and_recordr4   r   rŒ  rk  Ú
updated_atÚtotal_secondsrK  r+   r3
  r@  rV   r�   rí	  r/   rž  rJ  rµ   rU   rô	  r=	  rr  rs  rÀ	  r  r”  rÏ
  r¼  r—   rä  rü  r   r”   rz  )r  r�   r�  r¡   r<   rá  Ú_max_restartsÚ_windowÚ_max_gaprŒ  Ú	scheduledr®  Úmarkerr(  r1  Ú_resume_staterÖ  rÝ   r—  s   ``                 r>   Ú!_schedule_resume_pending_sessionsz/GatewayRunner._schedule_resume_pending_sessions¡)  so  øø€ õ. 1Ñ2Ô2ˆð	ØÔ#Ô)ð 	ð 	ØÔ"×8Ò8Ñ:Ô:Ð:ðð ð ð ð Ø'+Ô'9Ô'B×'IÒ'IÑ'KÔ'Kðñ ô �
ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	øøõ ð 	ð 	ð 	Ý�NŠNÐLÈcÑRÔRÐRØ�1�1�1�1�1øøøøð	øøøð ð 
	Jð	JØ>Ð>Ð>Ð>Ð>Ð>à37×3RÒ3RÑ3TÔ3TÑ0�˜w¨Ø×(Ò(Ø! 7¸Hð )ñ ô ð ð ˜1ðøõ ð Jð Jð JÝ—’ÐCÀSÑIÔIÐIÐIÐIÐIÐIÐIøøøøðJøøøõ Œl‰nŒnˆØˆ	Øð G	ñ G	ˆEØÔ0ÐD°EÔ4DˆFØÐ! s¨V¡|×&BÒ&BÑ&DÔ&DÀvÒ&MÐ&MØð ×'Ò'¨Ô(9Ñ:Ô:ð Øà”\ˆFØ×.Ò.¨vÑ6Ô6ˆGØˆÝ—’ØKØÔ%Ý˜FœO¨W°f´oÑFÔFñô ð ð
 ðØ×/Ò/°Ñ7Ô7ð Ý—N’NðHàÔ)ñô ð ð
 ðøõ ð ð ð Ý—’ØQØÔ% sñô ð ð ���‘øøøøðøøøð !×/Ò/°Ô0AÑBÔBˆMÝ'>ˆMÔÔ$Ý,0¬I©K¬KˆMÔÔ)Ø×'Ò'Ñ)Ô)Ð)õ
 !ØÝ(Ô-ØØð	ñ ô ˆEõ Ô&Ø×.Ò.¨w¸¸uÔ?PÑQÔQñô ˆDð Ô"×&Ò& tÑ,Ô,Ð,Ø×"Ò" 4Ô#9Ô#AÑBÔBÐBÝ�tÐ;¸UÑCÔCð #Ý Ð&>ÀÑEÔE�Ø�=Ø�EØ27�DÔ/Ø—’˜TÑ"Ô"Ð"Ø˜‰NˆI‰IØð 	Ý�KŠKØMØñô ð ð Ðsk   ’A; žAA/Á#A; Á/A3Á3A; Á6A3Á7A; Á;
B+ÂB&Â&B+Â16C* Ã*
DÃ4DÄDÇ5HÈ
IÈ!H?È?Ic                 óP   — | j         p| j        p| j                             ¦   «         S r^   )r,  r*  r”  r8  rN  s    r>   Ú_startup_should_abortz#GatewayRunner._startup_should_abort/*  s.   € àÔ#ð -ØŒ~ð-àÔ#×*Ò*Ñ,Ô,ð	
rM   c              ƒ   óü  K  — |                       ¦   «         sdS |�r|�p	 |                     ¦   «         ƒ d{V —† n8# t          $ r+}t                               d|j        |¦  «         Y d}~nd}~ww xY w|                      ||¦  «        ƒ d{V —† | j        }t          j	        ¦   «         }|�||ur	|ƒ d{V —† nF| j
                             ¦   «         s-|                      | j        | j        | j        ¬¦  «        ƒ d{V —† dS )zCClean up and exit startup when restart/shutdown begins mid-startup.FNu'   âœ— %s background-task cancel error: %srÃ
  T)rý
  r  r2   r3   r4   r­   r  r2  r  Úcurrent_taskr”  r8  r¨  r,  r.  r/  )r  r1  r�   r¨  Ú	stop_taskrÿ
  s         r>   Ú$_abort_startup_if_shutdown_requestedz2GatewayRunner._abort_startup_if_shutdown_requested6*  sn  è è € ð ×)Ò)Ñ+Ô+ð 	Ø�5ØÐ 8Ð#7ð[Ø×5Ò5Ñ7Ô7Ð7Ð7Ð7Ð7Ð7Ð7Ð7Ð7øÝð [ð [ð [Ý—’ÐFÈÌÐXYÑZÔZÐZÐZÐZÐZÐZÐZøøøøð[øøøà×/Ò/°¸ÑBÔBÐBÐBÐBÐBÐBÐBÐBØ”Oˆ	ÝÔ+Ñ-Ô-ˆØÐ  Y°lÐ%BÐ%BØˆOˆOˆOˆOˆOˆOˆOˆOØÔ%×,Ò,Ñ.Ô.ð 	Ø—)’)ØÔ/Ø!%Ô!7Ø $Ô 9ð ñ ô ð ð ð ð ð ð ð ð
 ˆts   ž9 ¹
A.Á!A)Á)A.rØ   c                 óÎ  — t          | dd¦  «        }|�t          |dd¦  «        sdS t          | dd¦  «        €B	 t          |¦  «        | _        n,# t          $ r t                               dd¬¦  «         Y nw xY wt          | dd¦  «        }|�|                     ¦   «         sD	 t          |¦  «        | _        dS # t          $ r  t                               d	d¬¦  «         Y dS w xY wdS )
uÑ   Arm the selector floor and out-of-loop watchdog before adapters.

        Disabled entirely with ``gateway.loop_watchdog: false`` in config.yaml
        (no env override â€” config-only knob, #69089).
        rz   NÚloop_watchdogTrR  z&Failed to arm gateway loop floor timerrß   rS  z.Failed to start gateway loop liveness watchdog)	rV   rz  rR  r2   r3   r4   Úis_aliver~  rS  )r  rØ   rz   Úwatchdogs       r>   Ú_start_loop_liveness_guardsz)GatewayRunner._start_loop_liveness_guardsP*  s)  € õ ˜˜x¨Ñ.Ô.ˆØÐ¥g¨f°oÀtÑ&LÔ&LÐØˆFÝ�4Ð3°TÑ:Ô:ÐBðVÝ0EÀdÑ0KÔ0K�Ô-Ð-øÝð Vð Vð VÝ—’ÐEÐPT�ÑUÔUÐUÐUÐUðVøøøõ ˜4Ð!:¸DÑAÔAˆØÐ 8×#4Ò#4Ñ#6Ô#6Ðð^Ý/KÈDÑ/QÔ/Q�Ô,Ð,Ð,øÝð ^ð ^ð ^Ý—’ÐMÐX\�Ñ]Ô]Ð]Ð]Ð]Ð]ð^øøøð Ðs#   ¹A Á&A7Á6A7Â"B8 Â8&C"Ã!C"c                 óz  — t          | dd¦  «        }d| _        |�B	 |                     ¦   «          n,# t          $ r t                               dd¬¦  «         Y nw xY wt          | dd¦  «        }d| _        |�D	 |                     ¦   «          dS # t          $ r  t                               dd¬¦  «         Y dS w xY wdS )zBDisarm lifetime liveness guards before shutdown can load the loop.rS  Nz-Failed to stop gateway loop liveness watchdogTrß   rR  z)Failed to cancel gateway loop floor timer)rV   rS  r¨  r2   r3   r4   rR  r  )r  r  Úfloor_timers      r>   Ú_stop_loop_liveness_guardsz(GatewayRunner._stop_loop_liveness_guardsf*  sü   € å˜4Ð!:¸DÑAÔAˆØ'+ˆÔ$ØÐð]Ø—’‘”��øÝð ]ð ]ð ]Ý—’ÐLÐW[�Ñ\Ô\Ð\Ð\Ð\ð]øøøõ ˜dÐ$>ÀÑEÔEˆØ(,ˆÔ%ØÐ"ðYØ×"Ò"Ñ$Ô$Ð$Ð$Ð$øÝð Yð Yð YÝ—’ÐHÐSW�ÑXÔXÐXÐXÐXÐXðYøøøð #Ð"s!   œ1 ±&AÁAÁ8B Â&B8Â7B8c              ƒ   óp   K  — | j                              ¦   «         ƒ d{V —†}|                     ¦   «          |S )a)  Discard orphan turn markers before consuming a clean-exit receipt.

        If either persistence or marker removal fails, startup must fail closed.
        Continuing with the old receipt would let a later unclean exit masquerade
        as clean and discard genuinely interrupted turns.
        N)r8
  Údiscard_active_turn_markersru  )r  Úmarker_pathÚ	discardeds      r>   Ú_consume_clean_shutdown_markerz,GatewayRunner._consume_clean_shutdown_markerx*  sF   è è € ð Ô2×NÒNÑPÔPÐPÐPÐPÐPÐPÐPˆ	Ø×ÒÑÔÐØÐrM   c              ƒ   óæ  K  — d}d}	 t          dt          dd¦  «        ¦  «        }t          dt          |dz  ¦  «        ¦  «        }| j                             |¬¦  «        ƒ d{V —†}n2# t
          $ r%}t                               d	|¦  «         Y d}~nd}~ww xY w	 | j                             d
¬¦  «        ƒ d{V —†}n2# t
          $ r%}t                               d|¦  «         Y d}~nd}~ww xY w||fS )zARecover exact active turns, then run the legacy recency fallback.r   rB	  r  é  rd  r|  )Úmax_age_secondsNz0Exact active-turn recovery on startup failed: %séx   z-Legacy session recovery on startup failed: %s)	rC  r„  rh  r8
  Úrecover_interrupted_turnsr2   r3   rã   Úsuspend_recently_active)r  Úexactr.  Úagent_timeoutÚmarker_max_ager<   s         r>   Ú_recover_unclean_sessionsz'GatewayRunner._recover_unclean_sessionsƒ*  sp  è è € àˆØˆð	TÝ ¥ZÐ0FÈÑ%MÔ%MÑNÔNˆMÝ  ­#¨m¸aÑ.?Ñ*@Ô*@ÑAÔAˆNØÔ2×LÒLØ .ð Mñ ô ð ð ð ð ð ð ˆEˆEøõ ð 	Tð 	Tð 	TÝ�NŠNÐMÈsÑSÔSÐSÐSÐSÐSÐSÐSøøøøð	Tøøøð	QØ!Ô5×MÒMØ #ð Nñ ô ð ð ð ð ð ð ˆHˆHøõ ð 	Qð 	Qð 	QÝ�NŠNÐJÈCÑPÔPÐPÐPÐPÐPÐPÐPøøøøð	Qøøøà�hˆÐs0   ˆAA( Á(
BÁ2BÂBÂ!B= Â=
C,ÃC'Ã'C,c           
   ƒ   óB3  ‡ ‡OK  — t                                d¦  «         	 t          j        ¦   «          nø# t          t
          t          f$ rÞ 	 t          ‰ j        dd¦  «        p8t          j
                             t          t          ¦   «         ¦  «        d¦  «        }t          j        |d¬¦  «         t          j
                             |d¦  «        }t          |dd	¬
¦  «        }t          j        |d¬¦  «         n,# t           $ r t                                dd¬¦  «         Y nw xY wY nw xY wt          t$          dd¦  «        }|�òt'          t          d¦  «        rÝ	 t          ‰ j        dd¦  «        p8t          j
                             t          t          ¦   «         ¦  «        d¦  «        }t          j
                             |d¦  «        }t          j        |d¬¦  «         t          |dd	¬
¦  «        }t          j        ||dd¬¦  «         n,# t           $ r t                                dd¬¦  «         Y nw xY w	 t+          j        ¦   «         ‰ _        n# t          $ r
 d‰ _        Y nw xY w‰ j        �‰                      ‰ j        ¦  «         t                                d‰ j        j        ¦  «         	 ddlm}  |‰ j        ¦  «        }	|	�Y|	                     d¦  «        rDt                                d|	                     dd¦  «        |	d         |	d         |	d         ¦  «         n2# t           $ r%}
t                                d|
¦  «         Y d}
~
nd}
~
ww xY w	 t?          t          j         dd¦  «        ¦  «        }t                                d|¦  «         n# t           $ r Y nw xY w	 t          j         d d!¦  «        }| !                    ¦   «         d"v }|rt                                d#¦  «         nt                                d$|¦  «         n# t           $ r Y nw xY w	 dd%l"m#}  |¦   «         }|r!|d&k    rt                                d'|¦  «         n# t           $ r Y nw xY w	 dd(l$m%}  |d)d¬*¦  «         n# t           $ r Y nw xY w	 dd+l&m'} dd,l(m)}  | |¦   «         ¦  «        ‰ _*        t          ‰ j*        d-d.¦  «        rt                                d/¦  «         n,# t           $ r t                                d0d¬¦  «         Y nw xY w	 dd1l+m,}m-}  |¦   «         } ||¦  «        }|r5t                                d2|¦  «         t                                d3¦  «         n,# t           $ r t                                d4d¬¦  «         Y nw xY w‰  .                    ¦   «         ƒ d{V —†rdS d5}d6}d7}d7}	 dd8l/m0} tc          d9„ | 2                    ¦   «         D ¦   «         ¦  «        }tc          d:„ | 2                    ¦   «         D ¦   «         ¦  «        }n# t           $ r Y nw xY wtg          d;„ ||z   D ¦   «         ¦  «        }t          j         d<d=¦  «         !                    ¦   «         d>v ptg          d?„ ||z   D ¦   «         ¦  «        }|s|st                                d@¦  «         ti          ‰ j        ¦  «        }|r¬| 5                    dAdB¦  «        d         }d} tl           7                    ¦   «         D ]\  }!}"|!j8        |k    r
|"dC         }  nŒt            9                    dD|| pdE¦  «         	 dd(l$m%}  |dF|¬*¦  «         n# t           $ r Y nw xY w‰  :                    |¦  «         dS 	 ddGl;m<}#  |#¦   «          n,# t           $ r t                                dHd¬¦  «         Y nw xY w	 ddIl=m>}$m?}%m@}&mA}'  |&¦   «           |$¦   «         r-t                                dJ |%¦   «         ¦  «          |'¦   «          n,# t           $ r t                                dKd¬¦  «         Y nw xY w	 dd+l&m'} ddLlBmC}(  |¦   «         }) |(|)d.¬M¦  «         ddLlDmC}*  |*|)¦  «         n,# t           $ r t                                dNd¬¦  «         Y nw xY w‰ jE         F                    ¦   «          	 ddOlGmH}+ |+ I                    ¦   «         },|,rt                                dP|,¦  «         n2# t           $ r%}-t                                dQ|-¦  «         Y d}-~-nd}-~-ww xY wt”          dRz  }.|. K                    ¦   «         r’t                                dS¦  «         	 ‰  L                    |.¦  «        ƒ d{V —†}/n=# t           $ r0}0t            9                    dT|0¦  «         t	          dU¦  «        |0‚d}0~0ww xY w|/rt                                dV|/¦  «         nA‰  M                    ¦   «         ƒ d{V —†\  }1}2|1|2z   },|,rt                                dW|,|1|2¦  «         	 ‰  N                    ¦   «         }3|3rt                                dX|3¦  «         n2# t           $ r%}-t                                dY|-¦  «         Y d}-~-nd}-~-ww xY wd‰ _O        g ‰ _P        g ‰ _Q        d}4d}5g }6g }7t¥          t          ‰ j        dZd.¦  «        ¦  «        }8g }9‰ j        jS         7                    ¦   «         D �]u\  }!}:‰  .                    ¦   «         ƒ d{V —†r dS |:jT        sŒ+|8rFt«          |!|:¦  «        s6t                                d[|!j8        ¦  «         |9 V                    |!¦  «         Œs|5dBz  }5‰  W                    |!|:¦  «        };|;sk|!j8        }<d\„ t°          jY         Z                    ¦   «         D ¦   «         }=|<|=vrt                                d]|<¦  «         nt                                d^|<¦  «         Œû|; [                    ‰  \                    ¦   «         ¦  «         |; ]                    ‰ j^        ¦  «         |; _                    ‰ j`        ¦  «         |; a                    ‰ jb        ¦  «         t          |;d_d¦  «        }>tÇ          |>¦  «        r |>‰ jd        ¦  «         |; e                    ‰ jf        ¦  «         |; g                    ‰  h                    |;ji        ¦  «        ¦  «         ‰ jj        |;_j        t                                d`|!j8        ¦  «         ‰  k                    |!j8        dadd¬b¦  «         	 ‰  l                    |;|!¦  «        ƒ d{V —†}?‰  .                    |;|!¦  «        ƒ d{V —†r dS |?r€|;‰ jm        |!<   ‰  n                    |;¦  «         t'          |;dc¦  «        r‰ jo        |;_p        |4dBz  }4‰  k                    |!j8        dddd¬b¦  «         t                                de|!j8        ¦  «         �n~t                                df|!j8        ¦  «         ‰  q                    |;|!¦  «        ƒ d{V —† |;jr        r´‰  k                    |!j8        |;js        rdgndh|;jt        |;ju        ¬b¦  «         |;js        r|7n|6}@|@ V                    |!j8        › di|;ju        › �¦  «         |;js        rL|:dBtí          jw        ¦   «         djz   ‰  x                    |!|;¦  «        ‰  y                    |!|;¦  «        dkœ‰ jz        |!<   n‡‰  k                    |!j8        dgddl¬b¦  «         |7 V                    |!j8        › dm�¦  «         |:dBtí          jw        ¦   «         djz   ‰  x                    |!|;¦  «        ‰  y                    |!|;¦  «        dkœ‰ jz        |!<   nê# t           $ rÝ}-t            9                    dn|!j8        |-¦  «         ‰  q                    |;|!¦  «        ƒ d{V —† ‰  k                    |!j8        dgdt          |-¦  «        ¬b¦  «         |7 V                    |!j8        › di|-› �¦  «         |:dBtí          jw        ¦   «         djz   ‰  x                    |!|;¦  «        ‰  y                    |!|;¦  «        dkœ‰ jz        |!<   Y d}-~-nd}-~-ww xY w‰  .                    ¦   «         ƒ d{V —†r dS �Œw	 ‰  {                    ¦   «         ƒ d{V —†}A|4|Az  }4nÅ# tø          $ r‰}-t          |-¦  «        }t            9                    do|¦  «         	 dd(l$m%}  |dF|¬*¦  «         n# t           $ r Y nw xY wtú          ‰ _~        ‰  :                    |¦  «         d.‰ _O        Y d}-~-d.‰ _        dS d}-~-wt           $ r'}-t            9                    dp|-d¬¦  «         Y d}-~-nd}-~-ww xY wd.‰ _        n# d.‰ _        w xY w|9D ]VŠOtg          ˆOfdq„‰ j€         Z                    ¦   «         D ¦   «         ¦  «        }B|Bs t                                dr‰Oj8        ¦  «         ŒW|4dk    �rƒ|6r�|7sds                     |6¦  «        }t            9                    dt|¦  «         	 dd(l$m%}  |dF|¬*¦  «         n# t           $ r Y nw xY wtú          ‰ _~        ‰  :                    |¦  «         d.‰ _O        dS |6r=t            9                    du�t          |6¦  «        ds                     |6¦  «        ¦  «         |5dk    r‡|7rids                     |7¦  «        }t                                dv�t          ‰ jz        ¦  «        |¦  «         	 dd(l$m%}  |dwd¬*¦  «         n# t           $ r Y nw xY wt                                dx|5¦  «         n4t                                dy¦  «         t                                dz¦  «         ‰  .                    ¦   «         ƒ d{V —†rdS ‰ jm        ‰ j‚        _m        ‰  ƒ                    ¦   «          d‰ _„        ‰  …                    d{¦  «         	 t          ‰ d|d¦  «        }C|C�|C †                    ¦   «         rŠt+          j‡        �t          �t          t          ‰ d}d~¦  «        ¬¦  «        ¦  «        ‰ _Š        t          ‰ d€d¦  «        }D|D�9|D ‹                    ‰ jŠ        ¦  «         ‰ jŠ         Œ                    |Dj�        ¦  «         n,# t           $ r t                                d�d¬¦  «         Y nw xY w�t          ‰ jE        jŽ        ¦  «        }E|Ert                                d‚|E¦  «         ‰ jE         �                    dƒd„d…„ ‰ jm         �                    ¦   «         D ¦   «         i¦  «        ƒ d{V —† |4dk    rt                                d†|4¦  «         	 dd‡l‘m’}F  |F‰ jm        ¦  «        ƒ d{V —†}G�t'          dˆ„ |G                     d„i ¦  «         Z                    ¦   «         D ¦   «         ¦  «        }Ht                                d‰|H¦  «         n2# t           $ r%}-t                                dŠ|-¦  «         Y d}-~-nd}-~-ww xY w‰  ”                    ¦   «         ƒ d{V —†}I|Is?tg          d‹„ t”          dŒz  t”          d�z  fD ¦   «         ¦  «        r‰  •                    ¦   «          |4dk    rt+          j–        dŽ¦  «        ƒ d{V —† �t/          ¦   «         }J�t1          ¦   «         }K|Jrd‰ _™        ‰  š                    ¦   «         ƒ d{V —† |KrA	 ‰  ›                    d¬�¦  «        ƒ d{V —† �t9          ¦   «          n# �t9          ¦   «          w xY w‰  �                    ¦   «         ƒ d{V —† ‰  ž                    ¦   «          ‰  Ÿ                    ¦   «         ƒ d{V —† 	 ddOlGmH}+ |+j         }Lg |+_         �tC          |L¦  «        D ]‰\  }M}N‰  ¢                    |Nfˆ fd�„	d‘|N                     d’¦  «        › �d.¬“¦  «         t                                d”|N                     d’¦  «        ¦  «         |Md•z  d–k    rt+          j–        d¦  «        ƒ d{V —† ŒŠn2# t           $ r%}-t            9                    d—|-¦  «         Y d}-~-nd}-~-ww xY w‰  ¢                    ‰ j£        d˜¦  «         ‰  ¢                    ‰ j¤        d™¦  «         ‰  ¢                    ‰ j¥        dš¦  «         ‰  ¢                    ‰ j¦        d›¦  «         ‰ jz        rQt                                dœ�t          ‰ jz        ¦  «        d�                     dž„ ‰ jz        D ¦   «         ¦  «        ¦  «         ‰  ¢                    ‰ j§        dŸˆ fd „¬¡¦  «        ‰ _¨        ‰  ¢                    ‰ j©        d¢¦  «         ‰  ¢                    ‰ jª        d£¦  «         	 ‰  «                    ¦   «         rIt                                d¤‰  ¬                    ¦   «         ¦  «         ‰  ¢                    ‰ j­        d¥¦  «         n‰  ®                    ¦   «          n,# t           $ r t                                d¦d¬¦  «         Y nw xY w‰  ¢                    ‰ j¯        d§¦  «         t                                d¨¦  «         dS )©z—
        Start the gateway and all configured platform adapters.
        
        Returns True if at least one adapter connected successfully.
        zStarting Hermes Gateway...Úlog_dirNÚlogsT)rò  zgateway_faulthandler.logÚarQ  r‚  )rD  Úall_threadsz!faulthandler.enable() unavailablerß   ÚSIGUSR2rN  )rD  r  r�	  z*Could not set up faulthandler file loggingzSession storage: %sr   )Úcheck_systemd_timing_alignmentÚmismatchzôStale systemd unit detected: %s has TimeoutStopSec=%.0fs but drain_timeout=%.0fs (expected >=%.0fs). systemd may SIGKILL the gateway mid-drain. Run `hermes gateway install --force` to regenerate the unit, or shorten agent.restart_drain_timeout.Úunitz	(unknown)Útimeout_stop_secÚdrain_timeoutÚexpected_minz)check_systemd_timing_alignment failed: %sr’  r   zvAgent budget: max_iterations=%d (agent.max_turns from config.yaml, or HERMES_MAX_ITERATIONS from .env, or default 500)r3  rr   >   ro   rp   rq   rr   z^Secret redaction: ENABLED (tool output, logs, and chat responses are scrubbed before delivery)zÆSecret redaction: DISABLED (HERMES_REDACT_SECRETS=%s). API keys and tokens may appear verbatim in chat output, session JSONs, and logs. Set security.redact_secrets: true in config.yaml to re-enable.r:  rJ  zActive profile: %sr7	  Ústarting)r5	  r6  rc  )Ústart_gateway_health_exportrÓ  Fz#Gateway health OTLP export: enabledz)gateway health OTLP export startup failed)Údetect_compromisedÚgateway_log_messageú%szCRun `hermes doctor` on the gateway host for full remediation steps.z1security advisory check failed at gateway startup)ÚTELEGRAM_ALLOWED_USERSÚDISCORD_ALLOWED_USERSÚWHATSAPP_ALLOWED_USERSÚWHATSAPP_CLOUD_ALLOWED_USERSÚSLACK_ALLOWED_USERSÚSIGNAL_ALLOWED_USERSÚSIGNAL_GROUP_ALLOWED_USERSÚTELEGRAM_GROUP_ALLOWED_USERSÚTELEGRAM_GROUP_ALLOWED_CHATSÚEMAIL_ALLOWED_USERSÚSMS_ALLOWED_USERSÚMATTERMOST_ALLOWED_USERSÚMATRIX_ALLOWED_USERSÚDINGTALK_ALLOWED_USERSÚFEISHU_ALLOWED_USERSÚWECOM_ALLOWED_USERSÚWECOM_CALLBACK_ALLOWED_USERSÚWEIXIN_ALLOWED_USERSÚBLUEBUBBLES_ALLOWED_USERSÚQQ_ALLOWED_USERSÚYUANBAO_ALLOWED_USERSÚGATEWAY_ALLOWED_USERS)ÚTELEGRAM_ALLOW_ALL_USERSÚDISCORD_ALLOW_ALL_USERSr”  ÚWHATSAPP_CLOUD_ALLOW_ALL_USERSÚSLACK_ALLOW_ALL_USERSÚSIGNAL_ALLOW_ALL_USERSÚEMAIL_ALLOW_ALL_USERSÚSMS_ALLOW_ALL_USERSÚMATTERMOST_ALLOW_ALL_USERSÚMATRIX_ALLOW_ALL_USERSÚDINGTALK_ALLOW_ALL_USERSÚFEISHU_ALLOW_ALL_USERSrŠ  ÚWECOM_CALLBACK_ALLOW_ALL_USERSr�  ÚBLUEBUBBLES_ALLOW_ALL_USERSr‘  r�  rN  ©Úplatform_registryc              3   ó2   K  — | ]}|j         ¯	|j         V — Œd S r^   )Úallowed_users_env©rb   r¨  s     r>   rd   z&GatewayRunner.start.<locals>.<genexpr>b+  sB   è è € ð )ð )Ø()ØÔ&ð)ØÔ#ð)ð )ð )ð )ð )ð )rM   c              3   ó2   K  — | ]}|j         ¯	|j         V — Œd S r^   )rŸ  rQ  s     r>   rd   z&GatewayRunner.start.<locals>.<genexpr>f+  s@   è è € ð +ð +Ø$%Ø”?ð+Ø”ð+ð +ð +ð +ð +ð +rM   c              3   ó>   K  — | ]}t          j        |¦  «        V — Œd S r^   )r’   rÆ  rÕ  s     r>   rd   z&GatewayRunner.start.<locals>.<genexpr>l+  s;   è è € ð 
ð 
Ø�BŒI�a‰LŒLð
ð 
ð 
ð 
ð 
ð 
rM   rš  r®   >   ro   rq   rr   c              3   óh   K  — | ]-}t          j        |d ¦  «                             ¦   «         dv V — Œ.dS )r®   >   ro   rq   rr   N)r’   rÆ  ry   rÕ  s     r>   rd   z&GatewayRunner.start.<locals>.<genexpr>o+  s\   è è € ð e
ð e
àõ ŒI�a˜ÑÔ×"Ò"Ñ$Ô$Ð(<Ð<ðe
ð e
ð e
ð e
ð e
ð e
rM   a4  No env user allowlists configured. Messaging platforms default to pairing/allowlist policies and will deny unknown senders unless you configure platform allowlists (e.g., TELEGRAM_ALLOWED_USERS=your_id) or explicitly opt in with GATEWAY_ALLOW_ALL_USERS=true plus dm_policy/group_policy: open on the platform.rÉ  r(   r|  zuRefusing to start: %s has dm_policy/group_policy set to 'open' but neither GATEWAY_ALLOW_ALL_USERS nor %s is enabled.za platform allow-all flagÚstartup_failed)Údiscover_pluginsz*plugin discovery failed at gateway startup)Úregister_relay_adapterÚ	relay_urlÚself_provision_relayÚsend_relay_policyz*relay adapter registered (connector at %s)z4relay adapter registration failed at gateway startup)Úregister_from_config)Úaccept_hooksz1shell-hook registration failed at gateway startupr*  z5Recovered %s background process(es) from previous runzProcess checkpoint recovery: %sú.clean_shutdownu?   Previous gateway exited cleanly â€” skipping session suspensionzrClean-start marker cleanup failed; refusing startup so the clean-exit receipt cannot mask a later unclean exit: %sz#clean-start recovery cleanup failedz>Discarded %d orphan active-turn marker(s) after clean shutdownzSMarked %d in-flight session(s) as resumable from previous run (%d exact, %d legacy)z'Auto-suspended %d stuck-loop session(s)zStuck-loop detection failed: %sr½  z–Skipping %s on default profile: no bot credential in this profile's secrets. Secondary multiplexed profiles that provide the token will still connect.c                 ó   — h | ]	}|j         ’Œ
S rN  rç  ©rb   rñ   s     r>   rQ  z&GatewayRunner.start.<locals>.<setcomp>C,  s   € Ð!QÐ!QÐ!Q¨a !¤'Ð!QÐ!QÐ!QrM   uq   No adapter for '%s' â€” is the plugin installed? (platform is enabled in config.yaml but no plugin registered it)zNo adapter available for %sÚset_reaction_handlerzConnecting to %s...Ú
connectingr°  Ú_voice_input_callbackrÚ  u   âœ“ %s connectedu   âœ— %s failed to connectr®  r¯  rC  r  rš  zfailed to connectz: failed to connectu   âœ— %s error: %sz$Gateway multiplexer config error: %sz,Secondary-profile adapter startup failed: %sc              3   ó    •K  — | ]}‰|v V — Œ	d S r^   rN  )rb   Ú_profile_mapr  s     €r>   rd   z&GatewayRunner.start.<locals>.<genexpr>õ,  s<   øè è € ð 'ð 'à ð ˜LÐ(ð'ð 'ð 'ð 'ð 'ð 'rM   uÄ   %s is enabled but no profile (default or secondary) provided a bot credential for it â€” the platform is not being served. Add its token to the profile that should own it, or disable the platform.r³
  z0Gateway hit a non-retryable startup conflict: %szf%d platform(s) fatally misconfigured and parked: %s. Staying alive so retryable platforms can recover.uS   Gateway started with no connected platforms â€” %d platform(s) queued for retry: %sÚdegradedz»No adapter could be created for any of the %d configured platform(s). Check that required dependencies are installed and credentials are set. Gateway will continue for cron job execution.zNo messaging platforms enabled.z5Gateway will continue running for cron job execution.r	  rQ  rT  r@  )Ú
interval_sÚ
start_timer¼  z&Failed to start gateway loop heartbeatz%s hook(s) loadedzgateway:startuprE  c                 ó   — g | ]	}|j         ‘Œ
S rN  rç  r:  s     r>   r  z'GatewayRunner.start.<locals>.<listcomp>p-  s   € Ð@Ð@Ð@ a˜!œ'Ð@Ð@Ð@rM   z#Gateway running with %s platform(s)©Úbuild_channel_directoryc              3   ó4   K  — | ]}t          |¦  «        V — Œd S r^   )r7   )rb   Úchss     r>   rd   z&GatewayRunner.start.<locals>.<genexpr>z-  s(   è è € ÐWÐW¨�3˜s™8œ8ÐWÐWÐWÐWÐWÐWrM   z%Channel directory built: %d target(s)z"Channel directory build failed: %sc              3   ó>   K  — | ]}|                      ¦   «         V — Œd S r^   )r˜   ©rb   r™   s     r>   rd   z&GatewayRunner.start.<locals>.<genexpr>‚-  s>   è è € ð  
ð  
àð �KŠK‰MŒMð 
ð  
ð  
ð  
ð  
ð  
rM   ú.update_pending.jsonú.update_pending.claimed.jsonrB	  ©Úskip_targetsc                 ó.   •— ‰                      | ¦  «        S r^   )Ú_run_process_watcher)Úwr  s    €r>   rò   z%GatewayRunner.start.<locals>.<lambda>Å-  s   ø€  d×&?Ò&?ÀÑ&BÔ&B€ rM   zprocess_watcher:rN   )r	  z(Resumed watcher for recovered process %séd   éc   z!Recovered watcher setup error: %sÚsession_expiry_watcherÚsession_stall_watcherÚkanban_notifier_watcherÚkanban_dispatcher_watcherz;Starting reconnection watcher for %d failed platform(s): %sr  c              3   ó$   K  — | ]}|j         V — Œd S r^   rç  r:  s     r>   rd   z&GatewayRunner.start.<locals>.<genexpr>æ-  s$   è è € ÐBÐB a˜!œ'ÐBÐBÐBÐBÐBÐBrM   Úplatform_reconnect_watcherc                 ó&   •— t          ‰d| ¦  «        S ©NrW  ©rÔ
  ©r   r  s    €r>   rò   z%GatewayRunner.start.<locals>.<lambda>û-  ó   ø€ �w tÐ-FÈÑJÔJ€ rM   ©Úon_spawnÚhandoff_watcherÚasync_delegation_watcheru?   scale-to-zero: armed (idle timeout %.0fs) â€” watching for idleÚscale_to_zero_watcherz*scale-to-zero: arm check failed at startupÚdrain_control_watcherzPress Ctrl+C to stop)°r3   rz  ÚfaulthandlerÚenabler¾  rj  r–   rV   rz   r’   r™   rf   rw   rx  Úmakedirsr™  r2   r4   Úsignalrá   rN  r  r!
  r“  r  rv  Úgateway.shutdown_forensicsr  r'  rv   rã   rh  rÆ  ry   r?  r;  r;	  r8	  r˜  rd  Ú&agent.monitoring.gateway_health_exportr&  Ú_gateway_health_export_runtimeÚhermes_cli.security_advisoriesr'  r(  r  Úgateway.platform_registryrN  r€  Úplugin_entriesr
  r¢  re   r›  rñ  r­   rP   rº  Úhermes_cli.pluginsrV  rð  rW  rX  rY  rZ  Úagent.shell_hooksr[  Úagent.outbound_webhooksr¸  Údiscover_and_loadr-  r+  Úrecover_from_checkpointrl  r˜   r  r  r{
  r6  rŸ  r   rº   rE  rÓ  rÇ  r”   Ú_create_adapterrÄ  Ú__members__r•  Úset_message_handlerÚ_primary_message_handlerÚset_fatal_error_handlerr˜  Úset_session_storer›  Úset_busy_session_handlerr
  r/  r’  Úset_topic_recovery_fnrf  Úset_authorization_checkÚ_make_adapter_auth_checkr�   r&  r¶  r0  r°  r  Ú_handle_voice_channel_inputrb  r  Úhas_fatal_errorrŸ  r´  rµ  rU   r—  r   r¡  r«  Ú!_start_secondary_profile_adaptersr§  r�  r)  rV  r}  r7   r‘  rÎ  r’  r	  r  r”  r|  ry  rQ  r—   rä  rü  r¯  r½  rž  Úgateway.channel_directoryrj  ÚsumÚ_send_update_notificationÚ#_schedule_update_notification_watchr–  rm  rq  rš  Ú_send_restart_notificationÚ(_send_home_channel_startup_notificationsrv  rî
  rû
  rÛ
  rÎ  rí  Ú_spawn_supervisedÚ_session_expiry_watcherÚ_session_stall_watcherÚ_kanban_notifier_watcherÚ_kanban_dispatcher_watcherÚ_platform_reconnect_watcherrW  Ú_handoff_watcherÚ_async_delegation_watcherrñ  r×  r	  rø  rF	  )Pr  Ú_fh_log_dirÚ_fh_enable_pathÚ_fh_enable_fileÚ_sigusr2Ú_log_dirÚ_faulthandler_pathÚ_fhr  Ú
_alignmentrÄ  Ú_effective_max_iterÚ_redact_rawÚ
_redact_onr;  r@  r8	  rd  r&  r'  r(  Ú	_adv_hitsÚ_adv_msgÚ_builtin_allowed_varsÚ_builtin_allow_all_varsÚ_plugin_allowed_varsÚ_plugin_allow_all_varsrN  Ú_any_allowlistÚ
_allow_allr•  r>  rŸ  r�   rœ  rV  rW  rX  rY  rZ  r[  Ú
_hooks_cfgÚregister_outbound_webhooksr+  re  r¨  Ú_clean_markerr  r<   r  r.  ÚstuckÚconnected_countÚenabled_platform_countÚstartup_nonretryable_errorsÚstartup_retryable_errorsÚ_multiplex_onÚ_multiplex_skipped_platformsrÀ  r1  Ú_pvalÚ_builtin_namesÚ_set_reactionr/  r  Ú_secondary_connectedÚ_served_by_secondaryÚ_existing_hbÚ_bgÚ
hook_countrj  Ú	directoryÚch_countrA
  Ú!chat_restart_notification_pendingÚ$planned_restart_notification_pendingÚwatchersrî  r�
  r  sP   `                                                                              @r>   r§  zGatewayRunner.start—*  s!  øøè è € õ 	�ŠÐ0Ñ1Ô1Ð1ð
	QÝÔÑ!Ô!Ð!Ð!øÝ�j­'Ð2ð 	Qð 	Qð 	Qð
QÝ% d¤k°9¸dÑCÔCð ÅrÄwÇ|Â|Ý�Ñ)Ô)Ñ*Ô*ØñHô H�õ ”˜K°$Ð7Ñ7Ô7Ð7Ý"$¤'§,¢,¨{Ð<VÑ"WÔ"W�Ý"& ¸ÀgÐ"NÑ"NÔ"N�ÝÔ#¨ÀdÐKÑKÔKÐKÐKøÝð Qð Qð QÝ—’Ð@È4�ÑPÔPÐPÐPÐPðQøøøøøð	Qøøøõ$ �6 9¨dÑ3Ô3ˆØÐ¥G­L¸*Ñ$EÔ$EÐðZÝ" 4¤;°	¸4Ñ@Ô@ð ÅBÄGÇLÂLÝ�Ñ)Ô)Ñ*Ô*ØñEô E�õ &(¤W§\¢\°(Ð<VÑ%WÔ%WÐ"Ý”˜H¨tÐ4Ñ4Ô4Ð4ÝÐ-¨s¸WÐEÑEÔE�ÝÔ%ØØØ $Øð	ñ ô ð ð øõ ð Zð Zð ZÝ—’ÐIÐTX�ÑYÔYÐYÐYÐYðZøøøð	&Ý!(Ô!9Ñ!;Ô!;ˆDÔÐøÝð 	&ð 	&ð 	&Ø!%ˆDÔÐÐð	&øøøàÔÐ)Ø×,Ò,¨TÔ-?Ñ@Ô@Ð@Ý�ŠÐ)¨4¬;Ô+CÑDÔDÐDð	JØQÐQÐQÐQÐQÐQØ7Ð7¸Ô8SÑTÔTˆJØÐ%¨*¯.ª.¸Ñ*DÔ*DÐ%Ý—’ðVð —N’N 6¨;Ñ7Ô7ØÐ1Ô2Ø˜Ô/Ø˜~Ô.ñ	ô 	ð 	øøõ ð 	Jð 	Jð 	JÝ�LŠLÐDÀbÑIÔIÐIÐIÐIÐIÐIÐIøøøøð	Jøøøð
	Ý"%¥b¤iÐ0GÈÑ&OÔ&OÑ"PÔ"PÐÝ�KŠKðFà#ñô ð ð øõ
 ð 	ð 	ð 	ØˆDð	øøøð	Ýœ)Ð$;¸VÑDÔDˆKØ$×*Ò*Ñ,Ô,Ð0JÐJˆJØð Ý—’ð>ñô ð ð õ
 —’ð3ð  ñô ð øøõ ð 	ð 	ð 	ØˆDð	øøøð	ØCÐCÐCÐCÐCÐCØ.Ð.Ñ0Ô0ˆHØð <˜H¨	Ò1Ð1Ý—’Ð0°(Ñ;Ô;Ð;øøÝð 	ð 	ð 	ØˆDð	øøøð	Ø;Ð;Ð;Ð;Ð;Ð;Ø Ð ¨zÀtÐLÑLÔLÐLÐLøÝð 	ð 	ð 	ØˆDð	øøøð	UØ5Ð5Ð5Ð5Ð5Ð5ØZÐZÐZÐZÐZÐZØ2MÐ2MÈkÈkÉmÌmÑ2\Ô2\ˆDÔ/Ý�tÔ:¸IÀuÑMÔMð CÝ—’ÐAÑBÔBÐBøøÝð 	Uð 	Uð 	UÝ�LŠLÐDÈtˆLÑTÔTÐTÐTÐTð	Uøøøð	ðð ð ð ð ð ð ð ð +Ð*Ñ,Ô,ˆIØ*Ð*¨9Ñ5Ô5ˆHØð Ý—’˜t XÑ.Ô.Ð.Ý—’ð)ñô ð øøõ ð 	ð 	ð 	Ý�LŠLØCØð ñ ô ð ð ð ð	øøøð
 ×:Ò:Ñ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<ð 	Ø�4ð!
Ðð&#
Ðð$ ')ÐØ(*Ðð	ØCÐCÐCÐCÐCÐCÝ#(ð )ð )Ø->×-MÒ-MÑ-OÔ-Oð)ñ )ô )ñ $ô $Ð õ &+ð +ð +Ø):×)IÒ)IÑ)KÔ)Kð+ñ +ô +ñ &ô &Ð"Ð"øõ ð 	ð 	ð 	ØˆDð	øøøåð 
ð 
Ø"7Ð:NÑ"Nð
ñ 
ô 
ñ 
ô 
ˆõ ”YÐ8¸"Ñ=Ô=×CÒCÑEÔEÐI]Ð]ð 
Õadð e
ð e
à,Ð/EÑEðe
ñ e
ô e
ñ b
ô b
ˆ
ð ð 	 jð 	Ý�NŠNð@ñô ð õ 4°D´KÑ@Ô@ˆØð 	Ø#Ÿ\š\¨#¨qÑ1Ô1°!Ô4ˆNØ ˆMÝ&:×&@Ò&@Ñ&BÔ&Bð ð Ñ"�˜(Ø”> ^Ò3Ð3Ø$,¨Q¤K�MØ�Eð 4õ �LŠLðIàØÐ<Ð!<ñ	ô ð ðØ?Ð?Ð?Ð?Ð?Ð?Ø$Ð$Ð3CÐQWÐXÑXÔXÐXÐXøÝð ð ð Ø�ðøøøà×$Ò$ VÑ,Ô,Ð,Ø�4ð	Ø;Ð;Ð;Ð;Ð;Ð;ØÐÑÔÐÐøÝð 	ð 	ð 	Ý�NŠNØ<Àtð ñ ô ð ð ð ð	øøøð	ðð ð ð ð ð ð ð ð ð ð ð ð !Ð Ñ"Ô"Ð"à%Ð%Ñ'Ô'ð $Ý—’ÐHÈ)È)É+Ì+ÑVÔVÐVð
 "Ð!Ñ#Ô#Ð#øøÝð 	ð 	ð 	Ý�NŠNØFÐQUð ñ ô ð ð ð ð	øøøð	Ø5Ð5Ð5Ð5Ð5Ð5Ø>Ð>Ð>Ð>Ð>Ð>Ø$˜™œˆJØ Ð  ¸%Ð@Ñ@Ô@Ð@ðð ð ð ð ð ð 'Ð& zÑ2Ô2Ð2Ð2øÝð 	ð 	ð 	Ý�LŠLØCØð ñ ô ð ð ð ð	øøøð 	Œ
×$Ò$Ñ&Ô&Ð&ð	AØ?Ð?Ð?Ð?Ð?Ð?Ø(×@Ò@ÑBÔBˆIØð `Ý—’ÐSÐU^Ñ_Ô_Ð_øøÝð 	Að 	Að 	AÝ�NŠNÐ<¸aÑ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@øøøøð	Aøøøõ %Ð'8Ñ8ˆØ×ÒÑ!Ô!ð 	Ý�KŠKÐYÑZÔZÐZðSØ"&×"EÒ"EÀmÑ"TÔ"TÐTÐTÐTÐTÐTÐT�	�	øÝð Sð Sð SÝ—’ðNàñô ð õ
 #Ð#HÑIÔIÈsÐRøøøøðSøøøð ð Ý—’ØTØñô ð øð
 %)×$BÒ$BÑ$DÔ$DÐDÐDÐDÐDÐDÐD‰OˆE�8Ø Ñ(ˆIØð Ý—’ð,àØØñô ð ð	?Ø×5Ò5Ñ7Ô7ˆEØð QÝ—’ÐHÈ%ÑPÔPÐPøøÝð 	?ð 	?ð 	?Ý�LŠLÐ:¸AÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>øøøøð	?øøøð -1ˆÔ)Ø&(ˆÔ#Ø&(ˆÔ#àˆØ!"ÐØ13Ð#Ø.0Ð õ �W T¤[Ð2FÈÑNÔNÑOÔOˆØ79Ð$Ø)-¬Ô)>×)DÒ)DÑ)FÔ)Fð i	ñ i	Ñ%ˆH�oØ×>Ò>Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@ð Ø�t�tØ"Ô*ð Øð ð Õ%AÀ(ÈOÑ%\Ô%\ð Ý—’ð<ð ”Nñ	ô ð ð -×3Ò3°HÑ=Ô=Ð=ØØ" aÑ'Ð"à×*Ò*¨8°_ÑEÔEˆGØð à œ�Ø!QÐ!Qµ8Ô3G×3NÒ3NÑ3PÔ3PÐ!QÑ!QÔ!Q�Ø Ð.Ð.Ý—N’Nð[àñô ð ð õ —N’NÐ#@À%ÑHÔHÐHØð ×'Ò'¨×(EÒ(EÑ(GÔ(GÑHÔHÐHØ×+Ò+¨DÔ,LÑMÔMÐMØ×%Ò% dÔ&8Ñ9Ô9Ð9Ø×,Ò,¨TÔ-UÑVÔVÐVÝ# GÐ-CÀTÑJÔJˆMÝ˜Ñ&Ô&ð ;Ø�˜dÔ9Ñ:Ô:Ð:Ø×)Ò)¨$Ô*PÑQÔQÐQØ×+Ò+¨D×,IÒ,IÈ'ÔJZÑ,[Ô,[Ñ\Ô\Ð\Ø&*Ô&:ˆGÔ#õ �KŠKÐ-¨x¬~Ñ>Ô>Ð>Ø×0Ò0Ø”Ø+ØØ"ð	 1ñ ô ð ðjØ $× JÒ JØ˜Xñ!ô !ð ð ð ð ð ð �ð ×BÒBÀ7ÈHÑUÔUÐUÐUÐUÐUÐUÐUð  Ø˜4˜4Øð KØ.5�D”M (Ñ+Ø×:Ò:¸7ÑCÔCÐCõ ˜wÐ(?Ñ@Ô@ð YØ8<Ô8X˜Ô5Ø# qÑ(�OØ×8Ò8Ø œØ'2Ø#'Ø&*ð	 9ñ ô ð õ —K’KÐ 2°H´NÑCÔCÐCÑCå—N’NÐ#=¸x¼~ÑNÔNÐNð ×7Ò7¸ÀÑJÔJÐJÐJÐJÐJÐJÐJÐJØÔ.ð 1Ø×<Ò<Ø$œNØ9@Ô9VÐ+c¨:¨:Ð\cØ'.Ô'?Ø*1Ô*Eð	 =ñ ô ð ð  'Ô<ð=Ð4Ð4à!<ð ð
 ŸšØ'œ~ÐNÐN°Ô1LÐNÐNñô ð ð #Ô8ð à*9Ø,-Ý.2¬nÑ.>Ô.>ÀÑ.CØ48×4RÒ4RØ$,¨gñ5"ô 5"ð 37×2NÒ2NØ$,¨gñ3"ô 3"ð
@ð 
@˜DÔ2°8Ñ<øð ×<Ò<Ø$œNØ+5Ø'+Ø*=ð	 =ñ ô ð ð 1×7Ò7Ø'œ~ÐBÐBÐBñô ð ð
 '6Ø()Ý*.¬.Ñ*:Ô*:¸RÑ*?Ø04×0NÒ0NØ (¨'ñ1ô 1ð /3×.JÒ.JØ (¨'ñ/ô /ð
<ð 
<˜Ô.¨xÑ8øøõ ð ð ð Ý—’Ð/°´ÀÑCÔCÐCð ×3Ò3°G¸XÑFÔFÐFÐFÐFÐFÐFÐFÐFØ×4Ò4Ø”NØ#-Ø#Ý"% a¡&¤&ð	 5ñ ô ð ð )×/Ò/°8´>Ð0HÐ0HÀQÐ0HÐ0HÑIÔIÐIð .Ø !Ý"&¤.Ñ"2Ô"2°RÑ"7Ø(,×(FÒ(FØ  'ñ)ô )ð '+×&BÒ&BØ  'ñ'ô 'ð
4ð 
4�Ô& xÑ0Ð0Ð0Ð0Ð0Ð0øøøøðøøøð2 ×>Ò>Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@ð Ø�t�tñð	:Ø)-×)OÒ)OÑ)QÔ)QÐ#QÐ#QÐ#QÐ#QÐ#QÐ#QÐ ØÐ3Ñ3ˆOˆOøÝ#ð 	ð 	ð 	õ ˜‘V”VˆFÝ�LŠLÐ?ÀÑHÔHÐHðØ?Ð?Ð?Ð?Ð?Ð?Ø$Ð$Ð3CÐQWÐXÑXÔXÐXÐXøÝð ð ð Ø�ðøøøå<ˆDŒOØ×$Ò$ VÑ,Ô,Ð,Ø05ˆDÔ-Ø�4�4�4ð 5:ˆDÔ1Ð1Ð1øøøøõ ð 	[ð 	[ð 	[Ý�LŠLÐGÈÐUYˆLÑZÔZÐZÐZÐZÐZÐZÐZøøøøð	[øøøð
 5:ˆDÔ1Ð1ø°EˆDÔ1Ð9Ð9Ð9Ð9ð 5ð 	ð 	ˆHÝ#&ð 'ð 'ð 'ð 'à$(Ô$:×$AÒ$AÑ$CÔ$Cð'ñ 'ô 'ñ $ô $Ð ð (ð Ý—’ð7ð ”Nñô ð øð ˜aÒÑØ*ð Ð3Kð ØŸšÐ#>Ñ?Ô?�Ý—’ÐOÐQWÑXÔXÐXðØCÐCÐCÐCÐCÐCØ(Ð(Ð7GÐU[Ð\Ñ\Ô\Ð\Ð\øÝ ð ð ð Ø�Dðøøøå"@�”Ø×(Ò(¨Ñ0Ô0Ð0Ø49�Ô1Ø�tØ*ð õ —’ðHæÐ3Ñ4Ô4Ø—I’IÐ9Ñ:Ô:ñ	ô ð ð &¨Ò)Ð)Ø+ð ð "ŸYšYÐ'?Ñ@Ô@�FÝ—N’Nð>æ˜DÔ2Ñ3Ô3°Vñô ð ð
ØGÐGÐGÐGÐGÐGØ,Ð,Ø*4Ø(,ðñ ô ð ð øõ %ð ð ð Ø˜ðøøøõ —’ðDð +ñ	ô ð ð õ —’Ð@ÑAÔAÐAÝ—’ÐSÑTÔTÐTð ×:Ò:Ñ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<ð 	Ø�4Ø(,¬ˆÔÔ%Ø×)Ò)Ñ+Ô+Ð+àˆŒØ×#Ò# IÑ.Ô.Ð.ð	RÝ" 4Ð)?ÀÑFÔFˆLØÐ# |×'8Ò'8Ñ':Ô':Ð#Ý,3Ô,?Þ*Þ#?Ý#*¨4Ð1FÈÑ#LÔ#Lðñ ô ñ-ô -�Ô)õ ˜dÐ$7¸Ñ>Ô>�Ø�?Ø—G’G˜DÔ5Ñ6Ô6Ð6ØÔ-×?Ò?ÀÄÑLÔLÐLøøÝð 	Rð 	Rð 	RÝ�LŠLÐAÈDˆLÑQÔQÐQÐQÐQð	Røøøö ˜œÔ0Ñ1Ô1ˆ
Øð 	9Ý�KŠKÐ+¨ZÑ8Ô8Ð8ØŒj�oŠoÐ/ØÐ@Ð@¨4¬=×+=Ò+=Ñ+?Ô+?Ð@Ñ@Ô@ð2
ñ ô ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð ˜QÒÐÝ�KŠKÐ=¸ÑOÔOÐOð	DØIÐIÐIÐIÐIÐIØ5Ð5°d´mÑDÔDÐDÐDÐDÐDÐDÐDˆIÞÐWÐW¨y¯}ª}¸[È"Ñ/MÔ/M×/TÒ/TÑ/VÔ/VÐWÑWÔWÑWÔWˆHÝ�KŠKÐ?ÀÑJÔJÐJÐJøÝð 	Dð 	Dð 	DÝ�NŠNÐ?ÀÑCÔCÐCÐCÐCÐCÐCÐCøøøøð	Døøøð
 ×7Ò7Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9ˆØð 	7�Cð  
ð  
õ Ð5Ñ5ÝÐ=Ñ=ðð 
ñ  
ô  
ñ 
ô 
ð 	7ð ×4Ò4Ñ6Ô6Ð6ð
 ˜QÒÐÝ”- Ñ$Ô$Ð$Ð$Ð$Ð$Ð$Ð$Ð$ö -JÑ,KÔ,KÐ)Þ/TÑ/VÔ/VÐ,ð -ð 	-Ø(,ˆDÔ%Ø×-Ò-Ñ/Ô/Ð/Ð/Ð/Ð/Ð/Ð/Ð/ð 0ð 	6ð6Ø×CÒCØ!%ð Dñ ô ð ð ð ð ð ð ð ö 4Ñ5Ô5Ð5Ð5øÖ3Ñ5Ô5Ð5Ð5øøøð ×1Ò1Ñ3Ô3Ð3Ð3Ð3Ð3Ð3Ð3Ð3Ø×.Ò.Ñ0Ô0Ð0Ø×*Ò*Ñ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,ð	AØ?Ð?Ð?Ð?Ð?Ð?ð
 (Ô8ˆHØ02ÐÔ-ö (¨Ñ1Ô1ð +ð +‘
��7Ø×&Ò&Ø$ÐBÐBÐBÐBÐBØB w§{¢{°<Ñ'@Ô'@ÐBÐBØ!ð 'ñ ô ð õ
 —’ÐFÈÏÊÐT`ÑHaÔHaÑbÔbÐbØ�s‘7˜b’=�=Ý!œ-¨Ñ*Ô*Ð*Ð*Ð*Ð*Ð*Ð*Ð*øð+øõ ð 	Að 	Að 	AÝ�LŠLÐ<¸aÑ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@øøøøð	Aøøøð 	×Ò˜tÔ;Ð=UÑVÔVÐVð 	×Ò˜tÔ:Ð<SÑTÔTÐTð
 	×Ò˜tÔ<Ð>WÑXÔXÐXð 	×Ò˜tÔ>Ð@[Ñ\Ô\Ð\ð Ô!ð 	Ý�KŠKØMÞ�DÔ*Ñ+Ô+Ø—	’	ÐBÐB¨4Ô+AÐBÑBÔBÑBÔBñô ð ð* (,×'=Ò'=ØÔ,Ø(ØJÐJÐJÐJð (>ñ (
ô (
ˆÔ$ð 	×Ò˜tÔ4Ð6GÑHÔHÐHð 	×Ò˜tÔ=Ð?YÑZÔZÐZð	VØ×-Ò-Ñ/Ô/ð 
;Ý—’ØUØ×<Ò<Ñ>Ô>ñô ð ð ×&Ò& tÔ'BÐD[Ñ\Ô\Ð\Ð\ð
 ×8Ò8Ñ:Ô:Ð:øøÝð 	Vð 	Vð 	VÝ�LŠLÐEÐPTˆLÑUÔUÐUÐUÐUð	Vøøøð 	×Ò˜tÔ:Ð<SÑTÔTÐTå�ŠÐ*Ñ+Ô+Ð+àˆtsã   4 ´D)ÁB-C:Ã9D)Ã:&D#Ä D)Ä"D#Ä#D)Ä(D)ÅB/H
 È
&H3È2H3È7I ÉI$É#I$Ê.A1L  Ì 
MÌ*M
Í
MÍ=N Î
NÎNÎ"A#P Ð
PÐPÐ3Q Ñ
QÑQÑQ0 Ñ0
Q=Ñ<Q=ÒAS Ó&S?Ó>S?ÔAU Õ&VÖ VÖ)AX Ø
XØXÜ\0 Ü0
\=Ü<\=Ý]) Ý)&^Þ^ÞA_$ ß$&`à`à4a á&a/á.a/â7c ã
c3ãc.ã.c3ä/e å
få+f æ fç(1h è
i	è$iéi	ó8|ôH |ü
A@ü$C<ÿ<A@Á@$AA ÁAAD ÁA
ADÁA*ACÁA9ABÁBACÁB
ABÁBACÁBABÁB+ACÁCAD ÁCADÁCADÁC<AD ÁDADÁDAD ÁD	ADÁF2AG ÁG
AGÁGAGÁJAJ  ÁJ 
AJ-ÁJ,AJ-ÁMB1AP ÁP&AP9ÁP8AP9ÁSA7AU ÁU
AV ÁUAU;ÁU;AV ÁYAY. ÁY.AY?Á[B.A]: Á]:
A^)Á^A^$Á^$A^)ÁcA1Ad> Ád>&Ae'Áe&Ae'r²  rå  Tr   ©r	  Ú_attemptr„  c                ó¦  ‡ ‡‡‡‡‡‡— t          ‰ dd¦  «        €t          ¦   «         ‰ _        t          j        ¦   «         Št          j         ‰¦   «         ¦  «        }‰ j                             |¦  «         ‰�:	  ‰|¦  «         n-# t          $ r  t           
                    d‰d¬¦  «         Y nw xY wˆˆˆˆˆˆˆ fd„}|                     |¦  «         |S )uò  Launch a long-lived background task with task-level supervision.

        Complements upstream's per-iteration inner-loop try/except (which only
        guards a single loop-body) by covering what that CANNOT: an exception
        raised in the watcher's OUTER ``while self._running:`` loop or its
        pre-try setup region, plus task-level death generally. A bare
        ``asyncio.create_task`` drops such an exception on the floor â€” no log,
        no restart, the watcher silently gone. This retains the handle in
        ``self._background_tasks``, logs any crash, and restarts with capped
        exponential backoff up to ``_MAX_SUPERVISED_RESTARTS`` failures in rapid
        succession (each within ``_SUPERVISED_HEALTHY_SECS`` of its restart).
        The counter resets after any run that stayed healthy for at least
        ``_SUPERVISED_HEALTHY_SECS`` â€” so a long-lived daemon that crashes
        occasionally over days is never permanently abandoned.

        ``on_spawn`` (optional) is invoked with the freshly-created task on
        every spawn, INCLUDING internal backoff respawns. Callers that also
        track the live handle elsewhere (e.g. ``self._reconnect_watcher_task``
        for ``_ensure_reconnect_watcher_running``) MUST pass it â€” otherwise the
        supervisor's own respawn creates a new task without updating that
        external handle, so ``_ensure_...`` later sees the stale/done handle
        and spawns a SECOND concurrent watcher (double reconnect attempts).
        r¼  Nzon_spawn callback for %s raisedTrß   c                 óŠ  •‡‡— ‰j                              | ¦  «          | j        ¦   «         rd S  | j        ¦   «         }|€d S t                               d‰
||¬¦  «         ‰rß‰j        rÚt          j        ¦   «         ‰z
  }|‰j	        k    rdŠn‰Š‰‰j
        k    r$t                               d‰
‰‰j	        ¦  «         d S t          ddt          ‰d¦  «        z  ¦  «        Šˆˆ	ˆˆ
ˆˆˆfd„}t          j         |¦   «         ¦  «        }‰j                              |¦  «         |                     ‰j         j        ¦  «         d S d S d S )	NzSupervised task %s died: %rrß   r   uh   Supervised task %s died %d times in rapid succession (each within %ds of restart) â€” giving up restartsrø  r|  é   c               “   óŒ   •K  — t          j        ‰ ¦  «        ƒ d {V —† ‰j        r‰                     ‰‰‰‰dz   ‰¬¦  «         d S d S )Nr(   rÝ  )r  r–  r’  r«  )ÚbackoffÚcoro_factoryÚeffective_attemptrÖ   r„  r	  r  s   €€€€€€€r>   Ú_respawnz@GatewayRunner._spawn_supervised.<locals>._done.<locals>._respawn‚.  sx   øè è € Ý!œ-¨Ñ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ø”}ð Ø×.Ò.Ø(Ø Ø$+Ø%6¸Ñ%:Ø%-ð /ñ ô ð ð ð ðð rM   )r¼  rü  r  rÛ   r3   rP   r’  rU   r—  Ú_SUPERVISED_HEALTHY_SECSÚ_MAX_SUPERVISED_RESTARTSr6   r  r”  r—   rä  )r   r<   Úran_forræ  Úrespawn_taskrã  rå  rÞ  Ú_startedrä  rÖ   r„  r	  r  s        @@€€€€€€€r>   Ú_donez.GatewayRunner._spawn_supervised.<locals>._doneb.  s¤  øøø€ ØÔ"×*Ò*¨1Ñ-Ô-Ð-ØˆqŒ{‰}Œ}ð Ø�Ø�!”+‘-”-ˆCØˆ{ð �Ý�LŠLÐ6¸¸cÈCˆLÑPÔPÐPØð "O˜4œ=ð "OÝœ.Ñ*Ô*¨XÑ5�Ø˜dÔ;Ò;Ð;ð
 )*Ð%Ð%à(0Ð%Ø$¨Ô(EÒEÐEÝ—L’LðNàØ)ØÔ5ñô ð ð �FÝ˜b !¥sÐ+<¸aÑ'@Ô'@Ñ"@ÑAÔA�ð	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	õ  'Ô2°8°8±:´:Ñ>Ô>�ØÔ&×*Ò*¨<Ñ8Ô8Ð8Ø×.Ò.¨tÔ/EÔ/MÑNÔNÐNÐNÐNðE"Oð "Oð "Oð "OrM   )rV   r•   r¼  rU   r—  r  r”  r—   r2   r3   r4   rä  )	r  rä  rÖ   r	  rÞ  r„  rÝ   rì  rë  s	   ``````  @r>   r«  zGatewayRunner._spawn_supervised6.  s  øøøøøøø€ õ0 �4Ð,¨dÑ3Ô3Ð;Ý%(¡U¤UˆDÔ"õ ”>Ñ#Ô#ˆõ Ô" < <¡>¤>Ñ2Ô2ˆØÔ×"Ò" 4Ñ(Ô(Ð(ØÐðUØ�˜‘”��øÝð Uð Uð UÝ—’Ð>ÀÈt�ÑTÔTÐTÐTÐTðUøøøð-	Oð -	Oð -	Oð -	Oð -	Oð -	Oð -	Oð -	Oð -	Oð -	Oð -	Oð^ 	×Ò˜uÑ%Ô%Ð%Øˆs   Á8B Â'B.Â-B.r¥  c              ƒ   ó\  K  — t          j        d¦  «        ƒ d{V —† | j        �r‡	 | j        €t          j        |¦  «        ƒ d{V —† Œ+| j                             ¦   «         ƒ d{V —†}|D ]Ú}|                     d¦  «        }|sŒ| j                             |¦  «        ƒ d{V —†sŒ;	 |                      |¦  «        ƒ d{V —† | j                             |¦  «        ƒ d{V —† Œx# t          $ rV}t                               d||d¬¦  «         | j                             |t          |¦  «        ¦  «        ƒ d{V —† Y d}~ŒÓd}~ww xY wnC# t           j        $ r ‚ t          $ r'}t                               d|d¬¦  «         Y d}~nd}~ww xY wt          j        |¦  «        ƒ d{V —† | j        �°…dS dS )u±  Background task that processes pending CLIâ†’gateway session handoffs.

        Polls ``state.db`` for sessions in ``handoff_state='pending'`` and,
        for each one:

        1. Atomically claims it (pending â†’ running).
        2. Resolves the destination platform's configured home channel.
        3. Re-binds the gateway's session_key for that home channel to the
           CLI's existing session_id via ``session_store.switch_session`` so
           the full role-aware transcript replays on the next agent turn.
        4. Forges a synthetic ``MessageEvent`` (``internal=True``) with a
           handoff-notice text and dispatches through the normal gateway
           message pipeline so the agent runs and replies on the platform.
        5. Marks the row ``completed`` (or ``failed`` with ``handoff_error``).

        The CLI process is poll-blocked on the row's terminal state and
        prints the result to the user.
        r²  NrÍ   z!Handoff for session %s failed: %sTrß   zHandoff watcher tick error: %s)r  r–  r’  rR   Úlist_pending_handoffsrv   Úclaim_handoffÚ_process_handoffÚcomplete_handoffr2   r3   rã   Úfail_handoffrw   r›  r4   )r  r		  r5  r�  rN   r<   s         r>   r±  zGatewayRunner._handoff_watcher”.  sv  è è € õ* Œm˜AÑÔÐÐÐÐÐÐÐØŒmñ 	*ðSØÔ#Ð+Ý!œ-¨Ñ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1ØØ $Ô 0× FÒ FÑ HÔ HÐHÐHÐHÐHÐHÐH�Ø"ð Rð R�CØ!$§¢¨¡¤�JØ%ð !Ø Ø!%Ô!1×!?Ò!?À
Ñ!KÔ!KÐKÐKÐKÐKÐKÐKð !à ðRØ"×3Ò3°CÑ8Ô8Ð8Ð8Ð8Ð8Ð8Ð8Ð8Ø"Ô.×?Ò?À
ÑKÔKÐKÐKÐKÐKÐKÐKÐKÐKøÝ$ð Rð Rð RÝŸšØ?Ø&¨°dð 'ñ ô ð ð #Ô.×;Ò;¸JÍÈCÉÌÑQÔQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQÐQøøøøðRøøøðRøõ  Ô)ð ð ð ØÝð Sð Sð SÝ—’Ð=¸sÈT�ÑRÔRÐRÐRÐRÐRÐRÐRøøøøðSøøøå”- Ñ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)ð5 Œmñ 	*ð 	*ð 	*ð 	*ð 	*sI   ¦!E ÁAE Â%;C!Ã E Ã!
EÃ+AD<Ä7E Ä<EÅE ÅFÅF Æ Fr�  c           	   ƒ   ó  K  — ddl m} ddlm}m} ddlm} |d         }|                     d¦  «        pd                     ¦   «          	                    ¦   «         }|st          d¦  «        ‚	  ||¦  «        }n(# t          t          f$ r t          d	|› d
�¦  «        ‚w xY wt          || j        | j        ¦  «        }	|	st          d|› d�¦  «        ‚|	j        }
| j                             |¦  «        }|r|j        st          d|› d�¦  «        ‚|                     d¦  «        p	|dd…         }d|› �}	 |
                     t)          |j        ¦  «        |¦  «        ƒ d{V —†}n7# t*          $ r*}t,                               d||d¬¦  «         d}Y d}~nd}~ww xY w|p|j        rt)          |j        ¦  «        nd}t)          |j        ¦  «        }||j        k    ot5          |¦  «        }|r|sd}d}nd}|r|nd}||j        k    r|dk    r|rt)          |¦  «        }n|} ||||j        ||d|¬¦  «        }| j        j                             |¦  «        }|r|j        ni } |||                     dd¦  «        |                     dd¦  «        ¬¦  «        }| j                              |¦  «        ƒ d{V —† | j         !                    ||¦  «        ƒ d{V —†}|€t          d|› d |› �¦  «        ‚|  "                    |¦  «         |  #                    |¦  «         d!|› d"�} |||d¬#¦  «        }t,           $                    d$|||j        ||¦  «         |  %                    |¦  «        ƒ d{V —†}|sdS i }|r||d%<   	 |	 &                    |t)          |j        ¦  «        ||pd¦  «        ƒ d{V —†}n%# t*          $ r}t          d&|› �¦  «        |‚d}~ww xY wtO          |d'd¦  «        s#tO          |d(d)¦  «        } t          d&| › �¦  «        ‚dS )*zAExecute one handoff row. Raises on failure (caller marks failed).r   r	  )r[  r`  )rr  rÍ   Úhandoff_platformr®   zhandoff_platform is emptyzunknown platform 'rV  z
platform 'z' is not active in this gatewayzno home channel configured for z(; run /sethome on the desired chat firstrÏ  Né   u   Hermes â€” z/Handoff: create_handoff_thread raised on %s: %sTrß   r¶  zsystem:handoffrµ  ÚHandoff)r�   r2  r*  r´  r¹  r)  r›  r<  r=  F©r<  r=  zcould not switch session key u    â†’ z([Session was just handed off from CLI ("z¿") to this channel. The full prior conversation history is loaded above. Briefly confirm you're working here and summarize what we were working on, so the user can continue from this device.])rè   r(  rã	  ub   Handoff: dispatching synthetic turn for CLI session %s â†’ %s (home=%s, thread=%s, session_key=%s)r›  zadapter.send failed: r/  rP   r6
  )(rÆ  rÄ  rr  r[  r`  r	  rr  rv   rx   ry   r¾  rj  rŸ  re  rz   r°  r1  r=
  r2  Úcreate_handoff_threadrw   r2   r3   r4   r›  rÍ  rd  r±  rÖ   rE  rÁ  r8
  Úget_or_create_sessionÚswitch_sessionÚ_evict_cached_agentrÌ
  rz  Ú_handle_messager0  rV   )!r  r�  rÄ  r[  r`  rr  Úcli_session_idr_  r�   r”  r1  r‰  Ú	cli_titleÚthread_nameÚnew_thread_idr<   Úeffective_thread_idÚhome_chat_idÚis_telegram_private_chatÚdest_chat_typeÚdest_user_idÚdest_chat_idÚdest_sourcerG  rÁ  r+   ÚswitchedÚsynthetic_textÚsynthetic_eventÚresponse_textÚsend_metadatar·  rï  s!                                    r>   rð  zGatewayRunner._process_handoffÆ.  sï  è è € à+Ð+Ð+Ð+Ð+Ð+ØDÐDÐDÐDÐDÐDÐDÐDØ7Ð7Ð7Ð7Ð7Ð7à˜TœˆØŸšÐ!3Ñ4Ô4Ð:¸×AÒAÑCÔC×IÒIÑKÔKˆØð 	<ÝÐ:Ñ;Ô;Ð;ð	FØ�x Ñ.Ô.ˆHˆHøÝ�HÐ%ð 	Fð 	Fð 	FÝÐD°MÐDÐDÐDÑEÔEÐEð	Føøøõ /¨x¸¼ÀdÄmÑTÔTˆ	Øð 	ÝØK˜]ÐKÐKÐKñô ð ð Ô#ˆð Œ{×+Ò+¨HÑ5Ô5ˆØð 	˜4œ<ð 	Ýð:°-ð :ð :ð :ñô ð ð
 —G’G˜GÑ$Ô$Ð:¨°r¸°rÔ(:ˆ	ð 0 IÐ/Ð/ˆð		!Ø")×"?Ò"?Ý�D”LÑ!Ô! ;ñ#ô #ð ð ð ð ð ð ˆMˆMøõ ð 	!ð 	!ð 	!Ý�LŠLØAØ˜s¨Tð ñ ô ð ð !ˆMˆMˆMˆMˆMˆMøøøøð	!øøøð ,ð 
Ø#'¤>Ð;�C�”ÑÔÐ°tð 	õ ˜4œ<Ñ(Ô(ˆà˜Ô)Ò)ð BÝ3°LÑAÔAð 	!ð
 ð 		ZÐ!9ð 		ZØ%ˆNØ+ˆLˆLð "ˆNØ+CÐY˜<˜<ÐIYˆLð �xÔ'Ò'Ð'¨N¸hÒ,FÐ,FÐK^Ð,FÝÐ2Ñ3Ô3ˆLˆLà'ˆLØ#�mØØ Ø”iØ$Ø ØØ)ð
ñ 
ô 
ˆð ”{Ô,×0Ò0°Ñ:Ô:ˆØ&2Ð:�Ô"Ð"¸ˆØ'Ð'ØØ$)§I¢IÐ.GÈÑ$NÔ$NØ%*§Y¢YÐ/IÈ5Ñ%QÔ%Qð
ñ 
ô 
ˆð Ô&×<Ò<¸[ÑIÔIÐIÐIÐIÐIÐIÐIÐIð Ô1×@Ò@ÀÈnÑ]Ô]Ð]Ð]Ð]Ð]Ð]Ð]ˆØÐÝØR°ÐRÐRÀ.ÐRÐRñô ð ð 	× Ò  Ñ-Ô-Ð-ð 	×)Ò)¨+Ñ6Ô6Ð6ðG¸	ð Gð Gð Gð 	ð '˜,ØØØð
ñ 
ô 
ˆõ 	�Šð3à˜M¨4¬<Ð9LØñ		
ô 	
ð 	
ð #×2Ò2°?ÑCÔCÐCÐCÐCÐCÐCÐCˆØð 	ð ˆFð )+ˆØð 	=Ø)<ˆM˜+Ñ&ð	GØ$Ÿ>š>ØÝ�D”LÑ!Ô!ØØÐ% ñ	ô ð ð ð ð ð ð ˆFˆFøõ ð 	Gð 	Gð 	GÝÐ<°sÐ<Ð<Ñ=Ô=À3ÐFøøøøð	Gøøøõ �v˜y¨$Ñ/Ô/ð 	>Ý˜& 'Ð+HÑIÔIˆCÝÐ<°sÐ<Ð<Ñ=Ô=Ð=ð	>ð 	>s<   Á,A8 Á8%BÄ2.E! Å!
FÅ+ FÆFÍ52N( Î(
O
Î2OÏO
c           	   ƒ   ó²  K  — t          j        d¦  «        ƒ d{V —† i }d}| j        �r.	 | j                             ¦   «         ƒ d{V —† g }t          | j        j                             ¦   «         ¦  «        D ]E\  }}|j	        rŒ| j         
                    |¦  «        ƒ d{V —†sŒ.|                     ||f¦  «         ŒF|r¿i }|D ]S\  }}	|                     d¦  «        }
t          |
¦  «        dk    r|
d         nd}|                     |d¦  «        dz   ||<   ŒTd	                     d
„ t!          |                     ¦   «         ¦  «        D ¦   «         ¦  «        }t"                               dt          |¦  «        |¦  «         |D �]o\  }}	 	 ddlm} |                     d¦  «        }
t          |
¦  «        dk    r|
d         nd} ||j        |d¬¦  «         n# t,          $ r Y nw xY wd}t/          | dd¦  «        }|�W|5  | j                             |¦  «        }t3          |t4          ¦  «        r|d         n|r|nd}ddd¦  «         n# 1 swxY w Y   |€%|                      |¦  «        }|r|j        j        nd}|r&|t<          ur|                      |d¬¦  «        ƒ d{V —† |                       |¦  «         |  !                    |d¬¦  «         | j         "                    |¦  «        ƒ d{V —† t"           #                    d|j        ¦  «         | $                    |j        d¦  «         �Œ¨# t,          $ r¼}|                     |j        d¦  «        dz   }|||j        <   ||k    r`t"           %                    d||j        |¦  «         | j         "                    |d¬¦  «        ƒ d{V —† | $                    |j        d¦  «         n#t"           #                    d|||j        |¦  «         Y d}~�Œid}~ww xY w|retM          d„ |D ¦   «         ¦  «        }t          |¦  «        |z
  }|rt"                               d||¦  «         nt"                               d|¦  «         	 |  '                    ¦   «         }|rt"                               d|¦  «         n2# t,          $ r%}	t"           #                    d|	¦  «         Y d}	~	nd}	~	ww xY w	 |  (                    ¦   «          n2# t,          $ r%}	t"           #                    d|	¦  «         Y d}	~	nd}	~	ww xY wt/          | d d!¦  «        }d"}tS          j)        ¦   «         |z
  |k    r´	 tU          t/          | j+        d#d¦  «        pd¦  «        }|dk    r=| j         ,                    |¦  «        ƒ d{V —†}|rt"                               d$|¦  «         n2# t,          $ r%}	t"           #                    d%|	¦  «         Y d}	~	nd}	~	ww xY wtS          j)        ¦   «         | _-        n2# t,          $ r%}t"           #                    d&|¦  «         Y d}~nd}~ww xY wt]          |¦  «        D ]%}| j        s nt          j        d¦  «        ƒ d{V —† Œ&| j        �°,dS dS )'aˆ  Background task that finalizes expired sessions.

        Runs every ``interval`` seconds (default 5 min).  For each session
        whose reset policy has expired, invokes ``on_session_finalize``
        hooks, cleans up the cached AIAgent's tool resources, evicts the
        cache entry so it can be garbage-collected, and marks the session
        so it won't be finalized again.
        rø  Nr)   rÉ  r|  r¼  r   r(   r  c              3   ó*   K  — | ]\  }}|› d |› �V — ŒdS )rÉ  NrN  )rb   r;  Úcs      r>   rd   z8GatewayRunner._session_expiry_watcher.<locals>.<genexpr>³/  sA   è è € ð .ð .Ù'+ q¨!˜1˜
˜
˜q˜
˜
ð.ð .ð .ð .ð .ð .rM   z,Session expiry: %d sessions to finalize (%s)rM
  r®   Úsession_expiredrO
  r  ra
  rP
  Úexpiry_finalizedr  zSession expiry finalized for %szkSession finalize gave up after %d attempts for %s: %s. Marking as finalized to prevent infinite retry loop.F)Úclear_model_overridez*Session finalize failed (%d/%d) for %s: %sc              3   ó.   K  — | ]\  }}|j         ¯d V — ŒdS )r(   N)r  )rb   rK  r¨  s      r>   rd   z8GatewayRunner._session_expiry_watcher.<locals>.<genexpr>
0  sB   è è € ð  ð  Ù"˜a ¸!Ô:Lð Øð ð  ð  ð  ð  ð  rM   z3Session expiry done: %d finalized, %d pending retryz!Session expiry done: %d finalizedz+Agent cache idle sweep: evicted %d agent(s)zIdle agent sweep failed: %sz%Agent cache pressure sweep failed: %sÚ_last_session_store_prune_tsr@  r$   Úsession_store_max_age_daysz,SessionStore prune: dropped %d stale entrieszSessionStore prune failed: %sz Session expiry watcher error: %s)/r  r–  r’  r8
  r9
  r½  r›  rÄ  rñ  r  Ú_is_session_expiredr”   re   r7   rv   rf   Úsortedr3   rz  rR
  rN
  rN   r2   rV   r  rt   r€  rA   rJ  rµ   rž  rS
  rû  Ú_clear_conversation_scopeÚset_expiry_finalizedr4   rU  rã   r¦  Ú_sweep_idle_cached_agentsÚ!_sweep_agent_cache_under_pressurerU   rh  rz   Úprune_old_entriesr  Úrange)r  r		  Ú_finalize_failuresÚ_MAX_FINALIZE_RETRIESÚ_expired_entriesr  r®  Ú
_platformsÚ_krÄ  r
  Ú_platÚ_plat_summaryrN
  Ú	_platformÚ_cached_agentrå  Ú_cachedÚ
_exp_stater¨  Úfailuresrì  Ú_failedÚ_idle_evictedÚ_last_prune_tsÚ_prune_intervalÚ_max_ageÚ_prunedrK  s                                r>   r¬  z%GatewayRunner._session_expiry_watcher“/  s¼  è è € õ Œm˜BÑÔÐÐÐÐÐÐÐØ-/ÐØ !ÐØŒmñ o	'ðiDØÔ.×=Ò=Ñ?Ô?Ð?Ð?Ð?Ð?Ð?Ð?Ð?à#%Ð Ý"& tÔ'9Ô'B×'HÒ'HÑ'JÔ'JÑ"KÔ"Kð :ð :‘J�C˜ØÔ-ð !Ø Ø!%Ô!9×!MÒ!MÈeÑ!TÔ!TÐTÐTÐTÐTÐTÐTð !Ø Ø$×+Ò+¨S°%¨LÑ9Ô9Ð9Ð9à#ð ð 24�JØ"2ð Ið I™˜˜BØ!#§¢¨#¡¤˜Ý-0°©[¬[¸1ª_¨_  q¤	 	À)˜Ø,6¯NªN¸5À!Ñ,DÔ,DÀqÑ,H˜
 5Ñ)Ð)Ø$(§I¢Ið .ð .Ý/5°j×6FÒ6FÑ6HÔ6HÑ/IÔ/Ið.ñ .ô .ñ %ô %�Mõ —K’KØFÝÐ,Ñ-Ô-¨}ñô ð ð
 #3ð Lñ L‘J�C˜ðKð
!ØMÐMÐMÐMÐMÐMØ%(§Y¢Y¨s¡^¤^˜FÝ58¸±[´[À1²_°_¨¨q¬	¨	È"˜IØ,Ð,Ø+0Ô+;Ø)2Ø'8ðñ ô ð ð øõ
  )ð !ð !ð !Ø ˜Dð!øøøð
 )-˜Ý&-¨dÐ4GÈÑ&NÔ&N˜Ø&Ð2Ø!,ð {ð {Ø*.Ô*;×*?Ò*?ÀÑ*DÔ*D Ý>HÈÕRWÑ>XÔ>XÐ0z°¸´
°
ÐipÐ^zÐ^eÐ^eÐvz ð{ð {ð {ñ {ô {ð {ð {ð {ð {ð {ð {øøøð {ð {ð {ð {ð
 )Ð0Ø)-×)AÒ)AÀ#Ñ)FÔ)F˜JØEOÐ,Y¨J¬OÔ,AÐ,AÐUY˜MØ(ð ¨]ÕBYÐ-YÐ-YØ"&×"HÒ"HØ -Ð7Gð #Iñ #ô #ð ð ð ð ð ð ð ð ×0Ò0°Ñ5Ô5Ð5ð ×6Ò6ØÐ(:ð 7ñ ô ð ð #Ô6×KÒKÈEÑRÔRÐRÐRÐRÐRÐRÐRÐRÝŸšØ=Ø!Ô,ñô ð ð +×.Ò.¨uÔ/?ÀÑFÔFÐFÑFøÝ$ð ð ð Ø#5×#9Ò#9¸%Ô:JÈAÑ#NÔ#NÐQRÑ#R˜Ø?GÐ*¨5Ô+;Ñ<Ø#Ð'<Ò<Ð<Ý"ŸNšNð!Wà (¨%Ô*:¸Añô ð ð
 #'Ô":×"OÒ"OØ %¸Eð #Pñ #ô #ð ð ð ð ð ð ð ð /×2Ò2°5Ô3CÀTÑJÔJÐJÐJå"ŸLšLØ LØ (Ð*?ÀÔAQÐSTñô ð øøøøùøøøøðøøøð& $ð Ýð  ð  Ø&6ð ñ  ô  ñ ô �Eõ "Ð"2Ñ3Ô3°eÑ;�GØð ÝŸšØQØ! 7ñô ð ð õ
 ŸšØ?Àñô ð ðDØ$(×$BÒ$BÑ$DÔ$D�MØ$ð ÝŸšØIØ)ñô ð øøõ !ð Dð Dð DÝ—L’LÐ!>ÀÑCÔCÐCÐCÐCÐCÐCÐCøøøøðDøøøðNØ×:Ò:Ñ<Ô<Ð<Ð<øÝ ð Nð Nð NÝ—L’LÐ!HÈ"ÑMÔMÐMÐMÐMÐMÐMÐMøøøøðNøøøõ ")¨Ð/MÈsÑ!SÔ!S�Ø"(�Ý”9‘;”; Ñ/°/ÒAÐAðJÝ#&Ý# D¤KÐ1MÈqÑQÔQÐVÐUVñ$ô $˜ð $ aš<˜<Ø,0Ô,D×,VÒ,VÐW_Ñ,`Ô,`Ð&`Ð&`Ð&`Ð&`Ð&`Ð&`˜GØ&ð "Ý &§¢Ø$RØ$+ñ!"ô !"ð !"øøõ %ð Jð Jð JÝŸšÐ%DÀbÑIÔIÐIÐIÐIÐIÐIÐIøøøøðJøøøå8<¼	¹¼�DÔ5øøÝð Dð Dð DÝ—’Ð?ÀÑCÔCÐCÐCÐCÐCÐCÐCøøøøðDøøøõ ˜8‘_”_ð 'ð '�Ø”}ð Ø�EÝ”m AÑ&Ô&Ð&Ð&Ð&Ð&Ð&Ð&Ð&Ð&ð_ Œmñ o	'ð o	'ð o	'ð o	'ð o	's  ªEW& ÆAGÇL'Ç
G ÇL'ÇG Ç L'Ç:>IÈ8L'ÉI	ÉL'ÉI	ÉCL'Ì%W& Ì'
O-Ì1B1O(Ï"W& Ï(O-Ï-A*W& Ñ1R
 Ò	W& Ò

R9ÒR4Ò/W& Ò4R9Ò9W& Ò=S ÓW& Ó
TÓS<Ó7W& Ó<TÔ0W& Ô2A(V ÖW& Ö
W
Ö%W× W& ×W
×
W& ×&
X×0XØXc                 ó"   — t          dd¦  «        S )zCReturn configured stall timeout (seconds); 0 disables the watchdog.r!  rå  )r„  rN  s    r>   Ú_session_stall_timeout_secondsz,GatewayRunner._session_stall_timeout_secondsP0  s   € åÐ8¸#Ñ>Ô>Ð>rM   c              #   óú  K  — t          ¦   «         }t          t          | di ¦  «                             ¦   «         ¦  «        D ]2}|€Œt	          |¦  «        }||v rŒ|                     |¦  «         |V — Œ3t          t          | di ¦  «                             ¦   «         ¦  «        D ]V}t          |                     ¦   «         ¦  «        D ]2}|€Œt	          |¦  «        }||v rŒ|                     |¦  «         |V — Œ3ŒWdS )zAYield every live platform adapter (default + multiplex profiles).r°  Nr}  )r•   r½  rV   r•  rÍ   r—   )r  r¢   r1  ÚaidÚamaps        r>   Ú_iter_gateway_adaptersz$GatewayRunner._iter_gateway_adaptersT0  s  è è € å™œˆÝ�G D¨*°bÑ9Ô9×@Ò@ÑBÔBÑCÔCð 	ð 	ˆGØˆØÝ�W‘+”+ˆCØ�dˆ{ˆ{ØØ�HŠH�S‰MŒMˆMØˆMˆMˆMˆMÝ� Ð':¸BÑ?Ô?×FÒFÑHÔHÑIÔIð 	ð 	ˆDÝ §¢¡¤Ñ.Ô.ð ð �Ø�?ØÝ˜‘k”k�Ø˜$�;�;ØØ—’˜‘”�Ø����ðð	ð 	rM   c                 ó  — t          | dd¦  «        pi                      |¦  «        }|�	|t          u rdS t          |d¦  «        sdS 	 |                     ¦   «         }n# t
          $ r Y dS w xY wt          |t          ¦  «        r|ndS )zÜReturn the shared activity snapshot for stall progress (#72039).

        Single progress source: ``AIAgent.get_activity_summary()`` /
        ``agent.session_activity``. No turn-start or pending-inbound clocks.
        r7  Nr>  )rV   rv   rž  rá   r>  r2   rt   ru   )r  r+   rµ   r
  s       r>   Ú_session_activity_for_stallz)GatewayRunner._session_activity_for_stalli0  s©   € õ ˜Ð0°$Ñ7Ô7Ð=¸2×BÒBÀ;ÑOÔOˆØˆ=˜EÕ%<Ð<Ð<Ø�4Ý�uÐ4Ñ5Ô5ð 	Ø�4ð	Ø×0Ò0Ñ2Ô2ˆGˆGøÝð 	ð 	ð 	Ø�4�4ð	øøøå$ W­dÑ3Ô3Ð=ˆwˆw¸Ð=s   ÁA Á
A*Á)A*Útimeout_secondsc              ƒ   óâ	  K  — ddl m}m}m}m} t          | dd¦  «        }|€	i }|| _        d}t          j        ¦   «         }i }	|                      ¦   «         D ]K}
t          |
dd¦  «        pi }t          | 
                    ¦   «         ¦  «        D ]\  }}|r||	vr	|�|
|f|	|<   ŒŒLt          t          | dd¦  «        pi  
                    ¦   «         ¦  «        D ]J\  }}|r||	v s|sŒ|d         }t          |dd¦  «        }|�|                      |¦  «        nd}
|
€ŒC|
|f|	|<   ŒKt          |	 
                    ¦   «         ¦  «        D �]o\  }\  }
}|du}|r|                      |¦  «        nd}|r |||¬¦  «        nd}t          |                     |¦  «        ¦  «        } ||||¬	¦  «        r|                     |d¦  «         d
} |||||¬¦  «        sŒ�|€Œ’t!          dt#          |dz  ¦  «        ¦  «        }|pi }t$                               d|||||                     d¦  «        p|                     d¦  «        pd|                     d¦  «        p|                     d¦  «        pd¦  «         t          |dd¦  «        }|�t          |dd¦  «        nd}|s"t$                               d|¦  «         d||<   �Œtt          |
dd¦  «        pi                      |¦  «        dup2t          t          | dd¦  «        pi                      |¦  «        ¦  «        } ||                      |¦  «        t          j        ¦   «         ¬¦  «        }|r|�;||k     r5t$                               d|||¦  «         |                     |d¦  «         �Œ?	 |�%t+          | d¦  «        r|                      |¦  «        nd}	 t/          j        |
                     t5          |¦  «         ||¦  «        |¬¦  «        t6          ¬¦  «        ƒ d{V —†}n7# t.          j        $ r% t$                               dt6          |¦  «         Y �Œëw xY w|�@t          |dd¦  «        d
u r-t$                               d|t          |dd¦  «        ¦  «         �Œ1|dz  }d||<   �Œ=# t:          $ r'}t$                               d||¦  «         Y d}~�Œid}~ww xY wt          |                     ¦   «         ¦  «        D ]}||	vr|                     |d¦  «         Œ|S ) z’Scan pending inbound sessions and notify once per stall episode.

        Returns the number of notifications sent this pass (for tests).
        r   )Ú!format_session_stall_notificationÚ*resolve_session_idle_seconds_from_activityÚ'should_clear_session_stall_notificationÚ&should_emit_session_stall_notificationrª  Nr<  r©  r(  rî  )r8  rD  Úhas_pending_inboundF)r8  rD  r>  Úalready_notifiedr(   rø  z Session stall detected: session=%s idle=%.0fs (timeout=%.0fs, ~%d min); pending inbound present | last_activity=%s | provenance=%s (agent.session_stall_timeout)Úlast_activity_descÚlast_activity_descriptionr¼  r†  Úlast_activity_provenancer2  z5Session stall notify skipped (no chat_id): session=%sTzSSession stall notify aborted (no longer stale): session=%s pending=%s fresh_idle=%srî	  r.  r  zLSession stall notify send timed out after %.0fs for %s; will retry next tickr/  z&Session stall notify failed for %s: %srP   r6
  )Úgateway.session_stallr:  r;  r<  r=  rV   rª  rU   r5  r½  rñ  r@  r7  rº   rv   rU  rC  rh  r3   rã   rz  rá   rî	  r  r  r0  rw   Ú"_STALL_NOTIFY_SEND_TIMEOUT_SECONDSr,  r2   rž  )r  r8  r:  r;  r<  r=  Únotified_mapÚsentrŒ  r¡   r1  r	  r+   rÖ  r#	  r(  r 	  Úhas_pendingÚactivityrD  ÚalreadyÚminsr2  Ústill_pendingÚ
fresh_idler¯   r·  r<   r  s                                r>   Ú_check_session_stallsz#GatewayRunner._check_session_stallsz0  sÒ  è è € ð
	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
õ ˜tÐ%>ÀÑEÔEˆØÐØˆLØ+7ˆDÔ(àˆÝŒi‰kŒkˆØ13ˆ
à×2Ò2Ñ4Ô4ð 	?ð 	?ˆGÝ" 7Ð,?ÀÑFÔFÐLÈ"ˆLÝ&*¨<×+=Ò+=Ñ+?Ô+?Ñ&@Ô&@ð ?ð ?Ñ"�˜UØð ? ;°jÐ#@Ð#@ÀUÐEVØ/6¸Ð.>�J˜{Ñ+øð?õ &*Ý�TÐ+¨TÑ2Ô2Ð8°b×?Ò?ÑAÔAñ&
ô &
ð 	7ð 	7Ñ!ˆK˜ð ð  +°Ð";Ð";À8Ð";ØØ˜Q”KˆEÝ˜U H¨dÑ3Ô3ˆFà4:Ð4F�×(Ò(¨Ñ0Ô0Ð0ÈDð ð ˆØØ'.°Ð&6ˆJ�{Ñ#Ð#å59¸*×:JÒ:JÑ:LÔ:LÑ5MÔ5Mð E	ñ E	Ñ1ˆKÑ1˜' =Ø'¨tÐ3ˆKàALÐV�×0Ò0°Ñ=Ô=Ð=ÐRVð ð
 ðÐ:Ð:¸8ÈÐMÑMÔMÐMàð õ
 ˜<×+Ò+¨KÑ8Ô8Ñ9Ô9ˆGØ6Ð6Ø /Ø)Ø$/ðñ ô ð  ð
 × Ò  ¨dÑ3Ô3Ð3Ø�Ø9Ð9Ø /Ø)Ø$/Ø!(ð	ñ ô ð ð àÐ#ØÝ�q�#˜l¨bÑ0Ñ1Ô1Ñ2Ô2ˆDØ�~ 2ˆHÝ�NŠNð0ð ØØØØ—’Ð1Ñ2Ô2ð Ø—<’<Ð ;Ñ<Ô<ðàØ—’˜\Ñ*Ô*ð Ø—<’<Ð :Ñ;Ô;ðàñô ð õ  ˜]¨H°dÑ;Ô;ˆFØ:@Ð:L•g˜f i°Ñ6Ô6Ð6ÐRVˆGØð Ý—’ØKØñô ð ð
 -1�˜[Ñ)Ùõ ˜Ð"5°tÑ<Ô<ÐBÀ×GÒGØñô ð ðð õ Ý˜TÐ#3°TÑ:Ô:Ð@¸b×EÒEØ#ñô ñô ð ð DÐCØ×0Ò0°Ñ=Ô=Ý”I‘K”Kðñ ô ˆJð !ð ØÐ&¨:¸Ò+GÐ+Gå—’ð:àØ!Øñô ð ð × Ò  ¨dÑ3Ô3Ð3Ùð*ð Ð)­g°dÐ<YÑ.ZÔ.ZÐ)ð ×4Ò4°VÑ<Ô<Ð<àð ðÝ#*Ô#3ØŸšÝ ™LœLØ=Ð=¸lÑKÔKØ%-ð %ñ ô õ
 !Cð$ñ $ô $ð ð ð ð ð ð �F�Føõ Ô+ð ð ð Ý—N’Nð7å:Ø#ñ	ô ð ð ‘Hðøøøð Ð%­'°&¸)ÀTÑ*JÔ*JÈeÐ*SÐ*SÝ—N’NØ@Ø#Ý ¨Ð1NÑOÔOñô ð ñ
 Ø˜‘	�Ø,0�˜[Ñ)Ñ)øÝð ð ð Ý—’Ø<ØØñô ð ð ð ð ð ñ øøøøðøøøõ ˜×)Ò)Ñ+Ô+Ñ,Ô,ð 	,ð 	,ˆCØ˜*Ð$Ð$Ø× Ò   dÑ+Ô+Ð+øàˆsD   Î )Q=Î*AO8Ï7Q=Ï80P,Ð(Q=Ð+P,Ð,AQ=Ñ1
Q=Ñ=
R.ÒR)Ò)R.c              ƒ   ó@  K  — t          j        t          dt          dt	          |¦  «        ¦  «        ¦  «        ¦  «        ƒ d{V —† | j        rÑ	 |                      ¦   «         }|dk    r|                      |¦  «        ƒ d{V —† n2# t          $ r%}t           
                    d|¦  «         Y d}~nd}~ww xY wt          dt          t	          |¦  «        ¦  «        ¦  «        }t          |¦  «        D ]%}| j        s nt          j        d¦  «        ƒ d{V —† Œ&| j        °ÏdS dS )aE  Periodic pending-inbound + stale-activity stall watchdog (#72016).

        Progress comes only from ``get_activity_summary()`` (#72039).
        Pending inbound is a notify policy gate, not a progress clock.
        Notify-only: does not kill the turn (contrast ``gateway_timeout`` /
        ``shutdown_watchdog``).
        r%   rB	  Nr   zSession stall watcher error: %sr(   )r  r–  r6   rC  ri  r’  r1  rM  r2   r3   r4   rh  r  )r  r		  rÓ  r<   ÚstepsrK  s         r>   r­  z$GatewayRunner._session_stall_watcher21  sd  è è € õ Œm�C ¥c¨#­u°X©¬Ñ&?Ô&?Ñ@Ô@ÑAÔAÐAÐAÐAÐAÐAÐAÐAØŒmð 	'ðEØ×=Ò=Ñ?Ô?�Ø˜Q’;�;Ø×4Ò4°WÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=øøÝð Eð Eð EÝ—’Ð>ÀÑDÔDÐDÐDÐDÐDÐDÐDøøøøðEøøøõ ˜�3�u X™œÑ/Ô/Ñ0Ô0ˆEÝ˜5‘\”\ð 'ð '�Ø”}ð Ø�EÝ”m AÑ&Ô&Ð&Ð&Ð&Ð&Ð&Ð&Ð&Ð&ð Œmð 	'ð 	'ð 	'ð 	'ð 	's   Á5B Â
B3ÂB.Â.B3c                 óJ   — 	 ddl m}  |¦   «         pdS # t          $ r Y dS w xY w)z0Return the profile name this gateway represents.r   r:  rJ  )r?  r;  r2   )r  r;  s     r>   r§  z"GatewayRunner._active_profile_nameJ1  sO   € ð	ØCÐCÐCÐCÐCÐCØ*Ð*Ñ,Ô,Ð9°	Ð9øÝð 	ð 	ð 	Ø�9�9ð	øøøs   ‚ ”
"¡"c                 ó,  ‡ — t          ‰ dd¦  «        sdS t          ‰ dd¦  «        }|�|                     ¦   «         sdS t                               d|�|                     ¦   «         nd¦  «         ‰                      ‰ j        dˆ fd„¬	¦  «        ‰ _        dS )
a³  Ensure the platform reconnect watcher background task is alive.

        If the tracked reconnect watcher task has died (e.g. from exhausting
        its restart budget, or a terminal exception that _spawn_supervised
        could not recover), respawns it so platforms queued for reconnection
        are not permanently stranded. Called after queueing a retryable fatal
        error in _handle_adapter_fatal_error (#70344).
        r’  FNrW  u7   Reconnect watcher task is dead (done=%s) â€” respawningzN/Ar}  c                 ó&   •— t          ‰d| ¦  «        S r  r€  r�  s    €r>   rò   zAGatewayRunner._ensure_reconnect_watcher_running.<locals>.<lambda>m1  r‚  rM   rƒ  )rV   r  r3   rã   r«  r°  rW  )r  rÝ   s   ` r>   r¢  z/GatewayRunner._ensure_reconnect_watcher_runningX1  s¯   ø€ õ �t˜Z¨Ñ/Ô/ð 	ØˆFÝ�tÐ6¸Ñ=Ô=ˆØÐ D§I¢I¡K¤KÐØˆFÝ�ŠØEØÐ+ˆD�IŠI‰KŒKˆK°ñ	
ô 	
ð 	
ð (,×'=Ò'=ØÔ,Ø(ØJÐJÐJÐJð (>ñ (
ô (
ˆÔ$Ð$Ð$rM   c           
   ƒ   óx  K  — t          j        d¦  «        ƒ d{V —† | j        �r•| j        s@t	          d¦  «        D ]/}| j        s dS | j        r nt          j        d¦  «        ƒ d{V —† Œ0ŒOt          j        ¦   «         }t          | j                             ¦   «         ¦  «        D �]Ó}| j        s dS | j         	                    |¦  «        }|€Œ*| 	                    d¦  «        rŒ@||d         k     rŒM|d         }|d         dz   }t          ||¦  «        s)t                               d	|j        ¦  «         | j        |= Œ™t                               d
|j        |¦  «         d}	 |                      ||¦  «        }|s)t                               d|j        ¦  «         | j        |= Œþ|                     |                      ¦   «         ¦  «         |                     | j        ¦  «         |                     | j        ¦  «         |                     | j        ¦  «         t1          |dd¦  «        }t3          |¦  «        r || j        ¦  «         |                     | j        ¦  «         |                     |                      |j        ¦  «        ¦  «         | j         |_         |  !                    ||d¬¦  «        ƒ d{V —†}	|	�r|| j"        |<   |  #                    |¦  «         tI          |d¦  «        r| j%        |_&        | j"        | j'        _"        | j        |= |  (                    |j        ddd¬¦  «         t                               d|j        ¦  «         	 ddl)m*}
  |
| j"        ¦  «        ƒ d{V —† n# tV          $ r Y nw xY w	 |  ,                    |¬¦  «         �n:# tV          $ r& t           -                    d|j        d¬¦  «         Y �nw xY w|j.        rs|j/        sl|  (                    |j        d|j0        |j1        ¬¦  «         t                               d|j        |j1        ¦  «         te          |¦  «        ƒ d{V —† | j        |= n�|  (                    |j        d|j0        |j1        pd¬¦  «         tg          |¦  «        }||d<   t          j        ¦   «         |z   |d<   t                               d|j        |¦  «         te          |¦  «        ƒ d{V —† �Œ,# tV          $ rœ}|�te          |¦  «        ƒ d{V —† |  (                    |j        ddti          |¦  «        ¬¦  «         tg          |¦  «        }||d<   t          j        ¦   «         |z   |d<   t                               d|j        ||¦  «         Y d}~�ŒÍd}~ww xY wt	          d¦  «        D ]&}| j        s dS t          j        d¦  «        ƒ d{V —† Œ'| j        �°“dS dS )u7  Background task that periodically retries connecting failed platforms.

        Uses exponential backoff: 30s â†’ 60s â†’ 120s â†’ 240s â†’ 300s (cap).
        Retryable failures (network/DNS blips) keep retrying at the backoff
        cap indefinitely â€” they self-heal once connectivity returns, so a
        transient outage never requires manual intervention. Non-retryable
        failures (bad auth, etc.) drop out of the queue immediately. The
        circuit breaker (``_pause_failed_platform`` / ``/platform pause``)
        remains available for manual operator control via ``/platform list``
        and ``/platform resume <name>``, but is no longer triggered
        automatically â€” auto-pausing a recovered platform was the cause of
        bots silently staying dead after a transient DNS failure.
        rG  Nr  r(   rI	  rœ  rz   r›  zKReconnect %s: no bot credential on queued config, removing from retry queuezReconnecting %s (attempt %d)...zGReconnect %s: adapter creation returned None, removing from retry queuer`  Tr'  rb  rÚ  r°  u   âœ“ %s reconnected successfullyr   ri  r…   z3resume-pending reschedule after %s reconnect failedrß   r¯  zAReconnect %s: non-retryable error (%s), removing from retry queuer®  zfailed to reconnectz&Reconnect %s failed, next retry in %dsz)Reconnect %s error: %s, next retry in %ds)5r  r–  r’  r«  r  rU   r—  r½  rž  rv   rÇ  r3   rã   r­   rz  r˜  rš  r›  rœ  r˜  r�  r›  rž  r
  rV   r/  r’  rŸ  rf  r   r¡  r�   r&  r-  r°  r  rá   r¢  rb  r‘  r¶  r¥  rj  r2   rû
  r4   r£  rŸ  r´  rµ  r  r  rw   )r  rK  rŒ  r�   rz  rÀ  r  r1  rÒ  r/  rj  rã  r¨  s                r>   r°  z)GatewayRunner._platform_reconnect_watcherp1  s7  è è € õ Œm˜BÑÔÐÐÐÐÐÐÐØŒmñ B	'ØÔ)ð å˜r™œð +ð +�AØœ=ð Ø˜˜ØÔ-ð Ø˜Ý!œ-¨Ñ*Ô*Ð*Ð*Ð*Ð*Ð*Ð*Ð*Ð*Øå”.Ñ"Ô"ˆCÝ  Ô!7×!<Ò!<Ñ!>Ô!>Ñ?Ô?ð mñ m�Ø”}ð Ø�F�FØÔ-×1Ò1°(Ñ;Ô;�Ø�<ð
 ð —8’8˜HÑ%Ô%ð ØØ˜˜lÔ+Ò+Ð+Øà"& x¤.�Ø˜zÔ*¨QÑ.�õ 4°H¸oÑNÔNð Ý—N’Nð4à œñô ð ð
 Ô.¨xÐ8ØÝ—’Ø5Ø”N Gñô ð ð
 �ðIØ"×2Ò2°8¸_ÑMÔM�GØ"ð !ÝŸšØeØ$œNñô ð ð !Ô2°8Ð<Ø à×/Ò/°×0MÒ0MÑ0OÔ0OÑPÔPÐPØ×3Ò3°DÔ4TÑUÔUÐUØ×-Ò-¨dÔ.@ÑAÔAÐAØ×4Ò4°TÔ5]Ñ^Ô^Ð^Ý$+¨GÐ5KÈTÑ$RÔ$R�MÝ Ñ.Ô.ð CØ%˜ dÔ&AÑBÔBÐBØ×1Ò1°$Ô2XÑYÔYÐYØ×3Ò3°D×4QÒ4QÐRYÔRbÑ4cÔ4cÑdÔdÐdØ.2Ô.B�GÔ+ð
 %)×$FÒ$FØ ¸ð %Gñ %ô %ð ð ð ð ð ð �Gð ñ P?Ø29˜œ hÑ/Ø×>Ò>¸wÑGÔGÐGå" 7Ð,CÑDÔDð ]Ø<@Ô<\˜GÔ9Ø8<¼˜Ô,Ô5Ø Ô2°8Ð<Ø×<Ò<Ø$œNØ+6Ø'+Ø*.ð	 =ñ ô ð õ ŸšÐ$EÀxÄ~ÑVÔVÐVð!ØYÐYÐYÐYÐYÐYØ"9Ð"9¸$¼-Ñ"HÔ"HÐHÐHÐHÐHÐHÐHÐHÐHøÝ(ð !ð !ð !Ø ˜Dð!øøøðØ ×BÒBÈHÐBÑUÔUÐUÑUøÝ(ð ð ð Ý"ŸLšLØ UØ (¤Ø)-ð )ñ ô ð ð ñ ðøøøð !Ô0ð *?¸Ô9Vð *?Ø×<Ò<Ø$œNØ+2Ø'.Ô'?Ø*1Ô*Eð	 =ñ ô ð õ ŸšØ_Ø$œN¨GÔ,Gñô ð õ 6°gÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ø Ô2°8Ð<Ð<à×<Ò<Ø$œNØ+5Ø'.Ô'?Ø*1Ô*EÐ*^ÐI^ð	 =ñ ô ð õ #5°WÑ"=Ô"=˜Ø+2˜˜ZÑ(Ý-1¬^Ñ-=Ô-=ÀÑ-G˜˜\Ñ*ÝŸšØDØ$œN¨Gñô ð õ 6°gÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>ùøõ !ð ð ð ØÐ*õ 6°gÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ø×8Ò8Ø œØ'1Ø#'Ý&)¨!¡f¤fð	 9ñ ô ð õ 1°Ñ9Ô9�GØ'.�D˜Ñ$Ý)-¬Ñ)9Ô)9¸GÑ)C�D˜Ñ&Ý—N’NØCØ œ¨¨7ñô ð ð ð ð ð ñ øøøøð%øøøõ6 ˜2‘Y”Yð 'ð '�Ø”}ð Ø�F�FÝ”m AÑ&Ô&Ð&Ð&Ð&Ð&Ð&Ð&Ð&Ð&ðE Œmñ B	'ð B	'ð B	'ð B	'ð B	'sj   Å"A SÆ#F+SÍM,Í+SÍ,
M9Í6SÍ8M9Í9SÍ=NÎSÎ,OÏSÏOÏD
SÓ
U7ÓBU2Õ2U7c              ƒ   óª  K  — | j         }t          |t          ¦  «        sdS t          j        ¦   «         }g }|                     ¦   «         D ]v}t          |t          ¦  «        sŒ|                     ¦   «         D ]I}t          |t          j        ¦  «        r-||ur)|                     ¦   «         s|                     |¦  «         ŒJŒw|D ]}| 	                    ¦   «          Œ|  
                    ¦   «         }|rO|dk    rIt          j        ||¬¦  «        ƒ d{V —†\  }}|r(t                               dt          |¦  «        ¦  «         |                     ¦   «          dS )a¿  Cancel profile-scoped reconnects before tearing down their registry.

        A reconnect can be waiting in adapter setup while shutdown begins. It
        must not republish an adapter after the secondary registry is drained.
        Waiting is bounded by the same adapter-cleanup budget; if a task does
        not finish in time, the stopped runner state still prevents it from
        installing an adapter when it eventually resumes.
        Nr   r  zLTimed out waiting for %d secondary profile reconnect task(s) during shutdown)r4  rt   ru   r  rÿ
  r•  ÚTaskr  r”   r  r  rB  r3   rã   r7   r4  )	r  r5  r‘  r—  Úprofile_pendingrÝ   rÓ  rì  Ú
unfinisheds	            r>   Ú)_cancel_secondary_profile_reconnect_tasksz7GatewayRunner._cancel_secondary_profile_reconnect_tasksC2  st  è è € ð Ô0ˆÝ˜'¥4Ñ(Ô(ð 	ØˆFÝÔ&Ñ(Ô(ˆØ$&ˆØ&Ÿ~š~Ñ/Ô/ð 	'ð 	'ˆOÝ˜o­tÑ4Ô4ð ØØ'×.Ò.Ñ0Ô0ð 'ð '�Ý˜d¥G¤LÑ1Ô1ð '°dÀ'Ð6IÐ6IÐRV×R[ÒR[ÑR]ÔR]Ð6IØ—L’L Ñ&Ô&Ð&øð'ð ð 	ð 	ˆDØ�KŠK‰MŒMˆMˆMØ×7Ò7Ñ9Ô9ˆØð 	�W˜q’[�[Ý&-¤l°5À'Ð&JÑ&JÔ&JÐ JÐ JÐ JÐ JÐ JÐ JÑˆE�:Øð Ý—’ØbÝ˜
‘O”Oñô ð ð 	�Š‰ŒˆˆˆrM   c                 óÒ   — | j         r| j        j        dk    rdS | j        �dS ddlm}  |d¬¦  «        }|                     ¦   «         sdS || _        |                     d¦  «         dS )zAStart sd_notify only after a configured gateway is truly running.r   FNT)ÚSystemdWatchdog)Úconfig_enabledzHermes Gateway running)r’  rz   Úsystemd_watchdog_secondsr5  Úgateway.systemd_notifyrZ  r§  Úready)r  rZ  r  s      r>   Ú_start_systemd_watchdogz%GatewayRunner._start_systemd_watchdogc2  s‰   € àŒ}ð 	 ¤Ô DÈÒ IÐ IØ�5ØÔ!Ð-Ø�4à:Ð:Ð:Ð:Ð:Ð:à"�?°$Ð7Ñ7Ô7ˆØ�~Š~ÑÔð 	Ø�5Ø!)ˆÔØ�ŠÐ/Ñ0Ô0Ð0ØˆtrM   c              ƒ   ób   K  — | j         }|€dS d| _         |                     ¦   «         ƒ d{V —† dS )z;Stop heartbeats before any potentially long shutdown drain.N)r5  r¨  )r  r  s     r>   Ú_stop_systemd_watchdogz$GatewayRunner._stop_systemd_watchdogs2  sG   è è € àÔ)ˆØÐØˆFØ!%ˆÔØ�mŠm‰oŒoÐÐÐÐÐÐÐÐÐrM   rÃ
  r	  rÄ
  rÅ
  c             ƒ   ó2  ‡ ‡K  — t          ‰ dd¦  «        }t          |¦  «        r
 |¦   «          |rd‰ _        |‰ _        |‰ _        ‰ j        �‰ j        ƒ d{V —† dS dˆˆ fd„}dˆ fd„Št          j         |¦   «         ¦  «        ‰ _        ‰ j        ƒ d{V —† dS )z-Stop the gateway and disconnect all adapters.r	  NTr-   c               “   ó„  •‡K  — dt           dd fd„} t          j        ¦   «         }|‰_        i Šdt          fˆˆfd„}t
          j                             d¦  «        s%t          t          ‰j
        ¦  «        ||d¬¦  «         	  ‰| ‰¦  «        ƒ d {V —† |                     ¦   «          d S # |                     ¦   «          w xY w)NÚphaser-   c                 óØ  — 	 ddl m} |                     ¦   «         }|rt                               d| |¦  «         n3# t
          $ r&}t                               d| |¦  «         Y d}~nd}~ww xY w	 ddlm}  |d| › d�¦  «        }|r=t           	                    d	| t          |¦  «        d
                     |¦  «        ¦  «         n3# t
          $ r&}t                               d| |¦  «         Y d}~nd}~ww xY w	 ddlm}  |d| › d�¬¦  «        }|rt                               d| |¦  «         n3# t
          $ r&}t                               d| |¦  «         Y d}~nd}~ww xY w	 ddlm}  |¦   «          n3# t
          $ r&}t                               d| |¦  «         Y d}~nd}~ww xY w	 ddlm}	  |	¦   «          dS # t
          $ r'}t                               d| |¦  «         Y d}~dS d}~ww xY w)uw  Kill tool subprocesses + tear down terminal envs + browsers.

                Called twice in the shutdown path: once eagerly after a
                drain timeout forces agent interrupt (so we reclaim bash/
                sleep children before systemd TimeoutStopSec escalates to
                SIGKILL on the cgroup â€” #8202), and once as a final
                catch-all at the end of _stop_impl() for the graceful
                path or anything respawned mid-teardown.

                All steps are best-effort; exceptions are swallowed so
                one subsystem's failure doesn't block the rest.
                r   r*  z,Shutdown (%s): killed %d tool subprocess(es)z(process_registry.kill_all (%s) error: %sN)Úmark_running_jobs_interruptedzGateway shutdown (z;) killed the job's tool subprocess before the run finished.z>Shutdown (%s): marked %d in-flight cron job(s) interrupted: %sr  z,mark_running_jobs_interrupted (%s) error: %s)Úinterrupt_allzgateway shutdown (rŠ  r  z6Shutdown (%s): interrupted %d background delegation(s)z"async interrupt_all (%s) error: %s)Úcleanup_all_environmentsz'cleanup_all_environments (%s) error: %s)Úcleanup_all_browsersz#cleanup_all_browsers (%s) error: %s)r-  r+  Úkill_allr3   rz  r2   r4   rc  rf  rã   r7   rf   rÌ  rg  Útools.terminal_toolrh  Útools.browser_toolri  )
rd  r+  Ú_killedrÄ  rf  Ú_interruptedÚ_interrupt_asyncÚ_async_nrh  ri  s
             r>   Ú_kill_tool_subprocesseszGGatewayRunner.stop.<locals>._stop_impl.<locals>._kill_tool_subprocesses‘2  s  € ð	XØGÐGÐGÐGÐGÐGØ.×7Ò7Ñ9Ô9�GØð ÝŸšØJØ! 7ñô ð øøõ !ð Xð Xð XÝ—L’LÐ!KÈUÐTVÑWÔWÐWÐWÐWÐWÐWÐWøøøøðXøøøð\ð MÐLÐLÐLÐLÐLØ#@Ð#@ð>¨Uð >ð >ð >ñ$ô $�Lð $ð ÝŸšØ\Ø!¥3 |Ñ#4Ô#4°d·i²iÀÑ6MÔ6Mñô ð øøõ !ð \ð \ð \Ý—L’LÐ!OÐQVÐXZÑ[Ô[Ð[Ð[Ð[Ð[Ð[Ð[øøøøð\øøøð	RØXÐXÐXÐXÐXÐXØ/Ð/Ð7TÈEÐ7TÐ7TÐ7TÐUÑUÔU�HØð ÝŸšØTØ! 8ñô ð øøõ !ð Rð Rð RÝ—L’LÐ!EÀuÈbÑQÔQÐQÐQÐQÐQÐQÐQøøøøðRøøøðWØLÐLÐLÐLÐLÐLØ,Ð,Ñ.Ô.Ð.Ð.øÝ ð Wð Wð WÝ—L’LÐ!JÈEÐSUÑVÔVÐVÐVÐVÐVÐVÐVøøøøðWøøøðSØGÐGÐGÐGÐGÐGØ(Ð(Ñ*Ô*Ð*Ð*Ð*øÝ ð Sð Sð SÝ—L’LÐ!FÈÈrÑRÔRÐRÐRÐRÐRÐRÐRÐRøøøøðSøøøsv   ‚8; »
A+ÁA&Á&A+Á/AC Ã
C4ÃC/Ã/C4Ã84D- Ä-
EÄ7EÅEÅ!E2 Å2
F"Å<FÆF"Æ&F8 Æ8
G)ÇG$Ç$G)c            
      ó|  •— ‰                      d¦  «        } t          ‰j        ¦  «        t          ‰j        ¦  «        t          ‰j        ¦  «        ‰                     ¦   «         ‰                     ¦   «         ‰                     ¦   «         ‰j        t          ‰j        ¦  «        | �t          j        ¦   «         | z
  nd dœ	S )Nr   )	r9	  r	  r	  r:	  Úactive_cron_jobsÚactive_api_runsr"  Úwatchdog_delay_sÚphase_elapsed_s)rv   rº   r,  r*  r’  r¼  r¾  r¿  r'  r}  rU   r—  )ÚstartedÚ_stop_started_at_boxr  s    €€r>   Ú_shutdown_watchdog_snapshotzKGatewayRunner.stop.<locals>._stop_impl.<locals>._shutdown_watchdog_snapshotÜ2  s¯   ø€ Ø.×2Ò2°3Ñ7Ô7�å)-¨dÔ.EÑ)FÔ)FÝ $ T¤^Ñ 4Ô 4Ý# D¤MÑ2Ô2Ø%)×%>Ò%>Ñ%@Ô%@Ø(,×(CÒ(CÑ(EÔ(EØ'+×'AÒ'AÑ'CÔ'CØ-1Ô-HÝ(GØÔ3ñ)ô )ð 7>Ð6I�œÑ(Ô(¨7Ñ2Ð2Ètðð ð rM   ÚPYTEST_CURRENT_TESTr(   )Ú
done_eventÚsnapshot_fnr8  )rw   r¤  r¹  rU  ru   r’   r“   rv   r{  r}  r'  r•   )rq  Ú_watchdog_donery  rx  Ú_stop_impl_bodyr  s      @€€r>   Ú
_stop_implz&GatewayRunner.stop.<locals>._stop_impl�2  s.  øøè è € ð?S­sð ?S°tð ?Sð ?Sð ?Sð ?SõN 'œ_Ñ.Ô.ˆNØ+9ˆDÔ(Ø57Ð ðµð ð ð ð ð ð ð õ$ ”:—>’>Ð"7Ñ8Ô8ð Ý%Ý3°DÔ4OÑPÔPØ-Ø ;Øð	ñ ô ð ð%Ø%�oØ+Ø(ñô ð ð ð ð ð ð ð ð
 ×"Ò"Ñ$Ô$Ð$Ð$Ð$ø�×"Ò"Ñ$Ô$Ð$Ð$øøøs   ÂB) Â)B?c              “   óX  •‡!K  — t                                d‰"j        rdnd¦  «         t          j        ¦   «         Š!‰!|d<   dt
          fˆ!fd„}d‰"_        d‰"_        t          ‰"d	d ¦  «        }t          |¦  «        r |¦   «         ƒ d {V —† ‰" 
                    ¦   «         ƒ d {V —† ‰"                     ¦   «         ƒ d {V —† t                                d
 |¦   «         ¦  «         ‰"j        }g }t          ‰"j                             ¦   «         ¦  «        D ]‚\  }}|t           u rŒ	 ‰"j                             |‰"j        rdnd¦  «        ƒ d {V —† |                     |¦  «         ŒP# t(          $ r&}t                                d||¦  «         Y d }~Œ{d }~ww xY w‰"                     ¦   «         }	‰"                     ¦   «         }
t          j        ¦   «         }‰"                     |¦  «        ƒ d {V —†\  }}t                                d |¦   «         t          j        ¦   «         |z
  |t3          |¦  «        ‰"                     ¦   «         |	‰"                     ¦   «         |
‰"                     ¦   «         ¦
  «
         |sc|D ]`}|‰"j        vrU	 ‰"j                             |¦  «        ƒ d {V —† Œ-# t(          $ r&}t                                d||¦  «         Y d }~ŒXd }~ww xY wŒa|�r|t                                d|‰"                     ¦   «         ‰"                     ¦   «         ‰"                     ¦   «         ¦  «         ‰"j        rdnd}t          ‰"j                             ¦   «         ¦  «        D ]d\  }}|t           u rŒ	 ‰"j                             ||¦  «        ƒ d {V —† Œ2# t(          $ r&}t                                d||¦  «         Y d }~Œ]d }~ww xY w‰"                     ‰"j        rt<          nt>          ¦  «         tA          j!        ¦   «                              ¦   «         dz   }‰"j        s‰"                     ¦   «         rœtA          j!        ¦   «                              ¦   «         |k     rs‰" "                    d¦  «         tA          j#        d¦  «        ƒ d {V —† ‰"j        s‰"                     ¦   «         r)tA          j!        ¦   «                              ¦   «         |k     °s‰"j        s‰"                     ¦   «         rB‰"                     ‰"j        rt<          nt>          ¦  «         t                                d¦  «          | d¦  «         t                                d |¦   «         ¦  «         ‰"j        rU‰"j$        rN	 ‰" %                    ¦   «         ƒ d {V —† n2# t(          $ r%}t            &                    d|¦  «         Y d }~nd }~ww xY w‰" '                    |¦  «        ƒ d {V —† t          ‰"dd ¦  «        }t          ‰"dd ¦  «        }|�’|��|5  t          | (                    ¦   «         ¦  «        }| )                    ¦   «          d d d ¦  «         n# 1 swxY w Y   |D ]>}tU          |tV          ¦  «        r|d         n|}‰" ,                    |d¬¦  «        ƒ d {V —† Œ?t          ‰"j-                             ¦   «         ¦  «        D ]!\  }}‰" .                    ||¦  «        ƒ d {V —† Œ"t          t          ‰"di ¦  «                             ¦   «         ¦  «        D ]^\  }}t          |                     ¦   «         ¦  «        D ]#\  }}‰" .                    |||¬¦  «        ƒ d {V —† Œ$| )                    ¦   «          Œ_t_          ‰"d¦  «        r‰"j0         )                    ¦   «          t                                d  |¦   «         ¦  «         t          ‰"j1        ¦  «        D ]*}|‰"j2        u rŒ|‰"j3        u rŒ| 4                    ¦   «          Œ+‰"j1         )                    ¦   «          ‰"j-         )                    ¦   «          t          ‰"j        ¦  «        D ]}‰" 5                    |¦  «         Œ	 dd!l6m7}  |tq          ‰"j9        ¦  «        d"¬#¦  «         n# t(          $ r Y nw xY w‰"j         )                    ¦   «          ‰"j:         )                    ¦   «          t_          ‰"d$¦  «        r‰"j;         )                    ¦   «          ‰"j9         )                    ¦   «          ‰"j<         )                    ¦   «          t_          ‰"d%¦  «        r‰"j=         )                    ¦   «          ‰"j>         ?                    ¦   «           | d&¦  «         t                                d' |¦   «         ¦  «         	 dd(l@mA}  |¦   «          n2# t(          $ r%}t                                d)|¦  «         Y d }~nd }~ww xY wt          ‰"d*d ¦  «        }t          |d+|¦  «        }|t          t          ‰"d,d ¦  «        d+d ¦  «        fD ]\}|�t_          |d-¦  «        sŒ	 | B                    ¦   «          Œ+# t(          $ r%}t                                d.|¦  «         Y d }~ŒUd }~ww xY wt†           D                    ‰"¦  «         t                                d/ |¦   «         ¦  «         dd0lEmF}mG}   |¦   «           | ¦   «          |s.	 t�          d1z   I                    ¦   «          n*# t(          $ r Y nw xY wt                                d2¦  «         |r4‰" J                    t          | K                    ¦   «         ¦  «        ¦  «         ‰"j        r’‰"jL        €‹	 t›          t�          ¦   «         t          j        ¦   «         tŸ          ‰"jP        ¦  «        tŸ          ‰"j$        ¦  «        d3œd ¬4¦  «         n2# t(          $ r%}t                                d5|¦  «         Y d }~nd }~ww xY w‰"j        r5‰"jP        r.‰" Q                    ¦   «          t¤          ‰"_S        ‰"jT        pd6‰"_T        d‰"_        t          ‰"d7d¦  «        r=‰"j        s6t                                d8¦  «         ‰" "                    d9‰"jT        ¦  «         n‰" "                    d:‰"jT        ¦  «         t«          ‰"¦  «         t                                d; |¦   «         ¦  «         d S )<NzStopping gateway%s...z for restartr®   r   r-   c                  ó0   •— t          j        ¦   «         ‰ z
  S r^   )rU   r—  )Ú_stop_started_ats   €r>   Ú_phase_elapsedzCGatewayRunner.stop.<locals>._stop_impl_body.<locals>._phase_elapsed3  s   ø€ Ý”~Ñ'Ô'Ð*:Ñ:Ð:rM   FTra  z5Shutdown phase: notify_active_sessions done at +%.2fsr—  r˜  z/pre-drain mark_resume_pending failed for %s: %sz¤Shutdown phase: drain done at +%.2fs (drain took %.2fs, timed_out=%s, active_at_start=%d, active_now=%d, cron_at_start=%d, cron_now=%d, api_at_start=%d, api_now=%d)z2clear_resume_pending after drain failed for %s: %sz�Gateway drain timed out after %.1fs with %d active agent(s), %d in-flight cron job(s), and %d api_server run(s); interrupting remaining work.z%mark_resume_pending failed for %s: %sr&   r	  r)
  z?Re-signaled interrupt for work still live at settle-window exitzpost-interruptz7Shutdown phase: post-interrupt tool kill done at +%.2fsz-Failed to launch detached gateway restart: %sr  r  r   zshutdown idle-cacherP
  r}  r  z3Shutdown phase: all adapters disconnected at +%.2fs)Úflush_pending_to_filer	  r  r9  r:  zfinal-cleanupz6Shutdown phase: final-cleanup tool kill done at +%.2fs)Úshutdown_cached_clientsz!shutdown_cached_clients error: %srR   rS   r›  rk
  zSessionDB close error: %sz.Shutdown phase: SessionDB close done at +%.2fs©Úremove_pid_fileÚrelease_gateway_runtime_lockr]  u€   Skipping .clean_shutdown marker â€” drain timed out with interrupted agents; next startup will suspend recently active sessions.)Úrequested_atrÀ
  r¿
  ró  z7Failed to write planned restart notification marker: %szGateway restart requestedr˜  uŠ   Gateway stopped by an unexpected signal â€” persisting gateway_state=running so container_boot auto-starts on the next boot (issue #42675)r	  Ústoppedz&Gateway stopped (total teardown %.2fs))Vr3   rz  r,  rU   r—  ri  r’  r*  rV   r/  rX  rH
  r'  r½  r7  rñ  rž  r8
  Úmark_resume_pendingr”   r2   r4   r¾  r¿  r-
  r7   r¼  ré
  rã   r0
  Ú!_INTERRUPT_REASON_GATEWAY_RESTARTÚ"_INTERRUPT_REASON_GATEWAY_SHUTDOWNr  r!
  r	  r–  r.  r¤
  rP   rV
  r•  r4  rt   r€  rS
  r°  r  rá   r}  r¼  r2  r3  r  rÌ
  rQ
  r„  ru   r<  r8  r9  r@  r:  r”  r•   rm
  r…  rk
  r
  Ú_shutdown_executorr;	  r‡  rˆ  rl  Útouchru
  rž  r1  rz  ro  rº   r/  r»
  r‚  r)  r—  Ú_shutdown_gateway_health_export)#rq  rx  rƒ  Ústop_watchdogrÓ  Ú_pre_drain_keysÚ_skr  rÄ  Ú_cron_at_startÚ_api_at_startÚ_drain_started_atr:	  r,
  Ú_resume_reasonÚinterrupt_deadliner¨  rå  ræ  Ú_idle_agentsÚ_entryr�   r1  Ú_profÚ_amapÚ_taskÚ_session_keyr„  r…  Ú_self_dbrS   r‡  rˆ  r‚  r  s#                                    @€r>   r~  z+GatewayRunner.stop.<locals>._stop_impl_bodyþ2  s¶  øøè è € Ý�KŠKØ'Ø"&Ô"9ÐA��¸rñô ð õ  $œ~Ñ/Ô/ÐØ(8Ð  Ñ%ð;¥Eð ;ð ;ð ;ð ;ð ;ð ;ð "ˆDŒMØ!ˆDŒNå# DÐ*BÀDÑIÔIˆMÝ˜Ñ&Ô&ð &Ø#�m‘o”oÐ%Ð%Ð%Ð%Ð%Ð%Ð%à×@Ò@ÑBÔBÐBÐBÐBÐBÐBÐBÐBð ×:Ò:Ñ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ý�KŠKØGØ�Ñ Ô ñô ð ð
 Ô1ˆGð *,ˆOÝ# DÔ$8×$>Ò$>Ñ$@Ô$@ÑAÔAð 
]ð 
]‘��VØÕ4Ð4Ð4Øð]ØÔ2×FÒFØØ-1Ô-DÐ\Ð)Ð)ÐJ\ñô ð ð ð ð ð ð ð ð $×*Ò*¨3Ñ/Ô/Ð/Ð/øÝ ð ]ð ]ð ]Ý—L’LÐ!RÐTWÐY[Ñ\Ô\Ð\Ð\Ð\Ð\Ð\Ð\øøøøð]øøøð "×8Ò8Ñ:Ô:ˆNØ ×6Ò6Ñ8Ô8ˆMÝ $¤Ñ 0Ô 0ÐØ-1×-FÒ-FÀwÑ-OÔ-OÐ'OÐ'OÐ'OÐ'OÐ'OÐ'OÑ$ˆM˜9Ý�KŠKð/ð �Ñ Ô Ý”Ñ Ô Ð#4Ñ4ØÝ�MÑ"Ô"Ø×)Ò)Ñ+Ô+ØØ×+Ò+Ñ-Ô-ØØ×*Ò*Ñ,Ô,ñô ð ð  ð ð +ð ð �CØ $Ô"6Ð6Ð6ðØ"&Ô":×"OÒ"OÐPSÑ"TÔ"TÐTÐTÐTÐTÐTÐTÐTÐTøÝ(ð ð ð Ý"ŸLšLØ TØ # Rñô ð ð ð ð ð ð øøøøðøøøð 7ð ñ [Ý—’ð3ð Ø×-Ò-Ñ/Ô/Ø×/Ò/Ñ1Ô1Ø×.Ò.Ñ0Ô0ñô ð ð> *.Ô)@ÐXÐ%Ð%ÐFXð õ $(¨Ô(<×(BÒ(BÑ(DÔ(DÑ#EÔ#Eð 	ð 	‘K�C˜ØÕ!8Ð8Ð8Ø ðØ"Ô6×JÒJÈ3ÐP^Ñ_Ô_Ð_Ð_Ð_Ð_Ð_Ð_Ð_Ð_øÝ$ð ð ð ÝŸšØCØ ñô ð ð ð ð ð ð øøøøðøøøð
 ×.Ò.Ø9=Ô9PÐxÕ5Ð5ÕVxñô ð õ &-Ô%=Ñ%?Ô%?×%DÒ%DÑ%FÔ%FÈÑ%LÐ"ð Ô(ð-Ø,0×,FÒ,FÑ,HÔ,Hð-åÔ.Ñ0Ô0×5Ò5Ñ7Ô7Ð:LÒLÐLØ×/Ò/°
Ñ;Ô;Ð;Ý!œ-¨Ñ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,ð Ô(ð-Ø,0×,FÒ,FÑ,HÔ,Hð-åÔ.Ñ0Ô0×5Ò5Ñ7Ô7Ð:LÒLÐLð Ô'ð ¨4×+EÒ+EÑ+GÔ+Gð Ø×2Ò2àÔ2ð@Õ9Ð9å?ñô ð õ
 —L’LØYñô ð ð (Ð'Ð(8Ñ9Ô9Ð9Ý—’ØMØ"�NÑ$Ô$ñô ð ð
 Ô&ð U¨4Ô+Að UðUØ×?Ò?ÑAÔAÐAÐAÐAÐAÐAÐAÐAÐAøÝ ð Uð Uð UÝ—L’LÐ!PÐRSÑTÔTÐTÐTÐTÐTÐTÐTøøøøðUøøøð ×0Ò0°Ñ?Ô?Ð?Ð?Ð?Ð?Ð?Ð?Ð?õ " $Ð(;¸TÑBÔBˆKÝ˜T >°4Ñ8Ô8ˆFØÐ&¨6Ð+=Ø ð #ð #Ý#'¨¯ª©¬Ñ#8Ô#8�LØ—L’L‘N”N�Nð#ð #ð #ñ #ô #ð #ð #ð #ð #ð #ð #øøøð #ð #ð #ð #ð +ð 	ð 	�Få%/°½Ñ%>Ô%>ÐJ˜˜qœ	˜	ÀFð ð ×@Ò@ØÐ(=ð Añ ô ð ð ð ð ð ð ð ð õ &*¨$¬-×*=Ò*=Ñ*?Ô*?Ñ%@Ô%@ð Hð HÑ!�˜'Ø×4Ò4°W¸hÑGÔGÐGÐGÐGÐGÐGÐGÐGÐGõ !%¥W¨TÐ3FÈÑ%KÔ%K×%QÒ%QÑ%SÔ%SÑ TÔ Tð ð ‘��uÝ)-¨e¯kªk©m¬mÑ)<Ô)<ð ð Ñ%�H˜gØ×8Ò8Ø °5ð 9ñ ô ð ð ð ð ð ð ð ð ð —’‘”��Ý�tÐ0Ñ1Ô1ð /ØÔ&×,Ò,Ñ.Ô.Ð.Ý�KŠKØEØ�Ñ Ô ñô ð õ
 ˜dÔ4Ñ5Ô5ð 	ð 	�Ø˜DœOÐ+Ð+ØØ˜DÔ.Ð.Ð.ð
 Ø—’‘”��ØÔ"×(Ò(Ñ*Ô*Ð*àŒM×ÒÑ!Ô!Ð!Ý $ TÔ%9Ñ :Ô :ð @ð @�Ø×1Ò1°,Ñ?Ô?Ð?Ð?ð
ØHÐHÐHÐHÐHÐHØ%Ð%¥d¨4Ô+AÑ&BÔ&BÈ:ÐVÑVÔVÐVÐVøÝð ð ð Ø�ðøøøð Ô ×&Ò&Ñ(Ô(Ð(ØÔ#×)Ò)Ñ+Ô+Ð+Ý�tÐ5Ñ6Ô6ð 4ØÔ+×1Ò1Ñ3Ô3Ð3ØÔ"×(Ò(Ñ*Ô*Ð*ØÔ#×)Ò)Ñ+Ô+Ð+Ý�t˜^Ñ,Ô,ð *ØÔ!×'Ò'Ñ)Ô)Ð)ØÔ ×$Ò$Ñ&Ô&Ð&ð $Ð# OÑ4Ô4Ð4Ý�KŠKØHØ�Ñ Ô ñô ð ðFØJÐJÐJÐJÐJÐJØ'Ð'Ñ)Ô)Ð)Ð)øÝð Fð Fð FÝ—’Ð@À"ÑEÔEÐEÐEÐEÐEÐEÐEøøøøðFøøøõ ˜t ]°DÑ9Ô9ˆHÝ˜x¨°Ñ9Ô9ˆHØ ¥'­'°$¸ÈÑ*NÔ*NÐPUÐW[Ñ"\Ô"\Ð]ð Bð B�Ø�;¥g¨c°7Ñ&;Ô&;�;ØðBØ—I’I‘K”K�K�KøÝ ð Bð Bð BÝ—L’LÐ!<¸bÑAÔAÐAÐAÐAÐAÐAÐAøøøøðBøøøå×,Ò,¨TÑ2Ô2Ð2Ý�KŠKØ@Ø�Ñ Ô ñô ð ð
 UÐTÐTÐTÐTÐTÐTÐTØˆOÑÔÐØ(Ð(Ñ*Ô*Ð*ð ð 
ðÝ!Ð$5Ñ5×<Ò<Ñ>Ô>Ð>Ð>øÝ ð ð ð Ø�Dðøøøõ —’ð'ñô ð ð ð RØ×6Ò6µs¸=×;MÒ;MÑ;OÔ;OÑ7PÔ7PÑQÔQÐQàÔ&ð _¨4Ô+GÐ+Oð_Ý%Ý:Ñ<Ô<å,0¬I©K¬KÝ+/°Ô0IÑ+JÔ+JÝ(,¨TÔ-CÑ(DÔ(Dðð ð
  $ðñ ô ð ð øõ !ð _ð _ð _Ý—L’LÐ!ZÐ\]Ñ^Ô^Ð^Ð^Ð^Ð^Ð^Ð^øøøøð_øøøð Ô&ð U¨4Ô+Dð UØ×5Ò5Ñ7Ô7Ð7õ& #D�”Ø$(Ô$5Ð$TÐ9T�Ô!à"ˆDŒNõ, �tÐ9¸5ÑAÔAð JÈ$ÔJað JÝ—’ð3ñô ð ð
 ×+Ò+¨I°tÔ7HÑIÔIÐIÐIà×+Ò+¨I°tÔ7HÑIÔIÐIÝ+¨DÑ1Ô1Ð1Ý�KŠKÐ@À.À.ÑBRÔBRÑSÔSÐSÐSÐSsß   Ä"?E"Å"
FÅ,FÆFÊ  J!Ê!
KÊ+KËKÍ-!NÎ
N?ÎN:Î:N?Õ#U> Õ>
V-ÖV(Ö(V-×36X5Ø5X9Ø<X9á%a( á(
a5á4a5å6f æ
f6æf1æ1f6èh(è(
iè2iéiê6k ë
k ëk íAn î
o	î$oïo	rŽ  )rV   r/  r,  r.  r/  r2  r  r”  )r  r	  rÄ
  rÅ
  Ú_stop_guardsr  r~  s   `     @r>   r¨  zGatewayRunner.stop{2  s  øøè è € õ ˜tÐ%AÀ4ÑHÔHˆÝ�LÑ!Ô!ð 	ØˆL‰NŒNˆNØð 	8Ø&*ˆDÔ#Ø%5ˆDÔ"Ø(7ˆDÔ%ØŒ?Ð&Ø”/Ð!Ð!Ð!Ð!Ð!Ð!Ð!ØˆFðl	%ð l	%ð l	%ð l	%ð l	%ð l	%ð l	%ð\X	Tð X	Tð X	Tð X	Tð X	Tð X	Tõt "Ô-¨j¨j©l¬lÑ;Ô;ˆŒØŒoÐÐÐÐÐÐÐÐÐrM   c              ƒ   óH   K  — | j                              ¦   «         ƒ d{V —† dS )zWait for shutdown signal.N)r”  rB  rN  s    r>   Úwait_for_shutdownzGatewayRunner.wait_for_shutdown›4  s3   è è € àÔ"×'Ò'Ñ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ð)rM   c              ƒ   óˆ  K  — t          | j        dd¦  «        sdS 	 ddlm}m} n# t
          $ r Y dS w xY w |¦   «         pd}d}i }| j                             ¦   «         D ]@\  }}|                      |¦  «        }|�||||f<   |  	                    ||¦  «        }	|	�|||	<   ŒAt          | di ¦  «         
                    ¦   «         D ]6}
dD ]1}|
                     |¦  «        }t          |t          ¦  «        r|||<   Œ2Œ7 |d	¬
¦  «        D ]š\  }}||k    rŒ	 ||                      |||¦  «        ƒ d{V —†z  }Œ.# t          $ r&}t                                d||¦  «         Y d}~ŒYd}~wt$          $ r ‚ t
          $ r(}t                                d||d	¬¦  «         Y d}~Œ“d}~ww xY w	 ddlm} ddlm} |gt1          | j                             ¦   «         ¦  «        z   }|D ].}|r*|| j        vr!||k    r| j        n ||¬¦  «        | j        |<   Œ/ ||¬¦  «         n,# t
          $ r t                                dd	¬¦  «         Y nw xY w|S )u8  Bring up adapters for every non-active profile this gateway serves.

        Returns the number of secondary adapters that connected. No-op (returns
        0) unless ``gateway.multiplex_profiles`` is on.

        Each profile's adapters are created and connected under that profile's
        HERMES_HOME + secret scope (``_profile_runtime_scope``), stored in
        ``self._profile_adapters[profile]``, and given a message handler that
        stamps ``source.profile`` before delegating to the shared
        ``_handle_message`` â€” so the agent turn resolves that profile's config,
        skills, and credentials. Same-platform credential collisions (two
        profiles polling the same bot token) are detected and refused here, the
        only point that sees every profile's resolved credentials together.
        r½  Fr   )Úprofiles_to_server;  rJ  Nr«  )r�  rž  T©Ú	multiplexzDSkipping secondary profile '%s' due to port-binding config error: %sz-Failed to start adapters for profile '%s': %srß   r7	  rz  r  )Úserved_profilesz could not record served_profiles)rV   rz   r?  r¤  r;  r2   r°  rñ  Ú_adapter_credential_fingerprintr¡  r•  rv   rt   r€  Ú_start_one_profile_adaptersr­  r3   rã   r§  rP   r;	  r8	  r´  r{  r  r}  rž  r¶  rµ  r4   )r  r¤  r;  rö  rÚ  rë
  r#  Ú_adÚfprž  Ú
retry_infoÚ
claim_nameÚretry_claimÚprofile_namer®  r¨  r8	  r{  ÚservedrÖ   s                       r>   r¤  z/GatewayRunner._start_secondary_profile_adaptersŸ4  s¢  è è € õ �t”{Ð$8¸%Ñ@Ô@ð 	Ø�1ð	ØVÐVÐVÐVÐVÐVÐVÐVÐVøÝð 	ð 	ð 	Ø�1�1ð	øøøð )Ð(Ñ*Ô*Ð7¨iˆØˆ	ð %'ˆØœ-×-Ò-Ñ/Ô/ð 	1ð 	1‰JˆE�3Ø×5Ò5°cÑ:Ô:ˆBØˆ~Ø'-�˜ ˜Ñ$Ø!×9Ò9¸%ÀÑEÔEˆNØÐ)Ø*0�˜Ñ'øõ " $Ð(;¸RÑ@Ô@×GÒGÑIÔIð 	2ð 	2ˆJØDð 2ð 2�
Ø(Ÿnšn¨ZÑ8Ô8�Ý˜k­5Ñ1Ô1ð 2Ø+1�G˜KÑ(øð2ð
 +<Ð*;ÀdÐ*KÑ*KÔ*Kð 	ð 	Ñ&ˆL˜,Ø˜vÒ%Ð%ØðØ 4×#CÒ#CØ  ,°ñ$ô $ð ð ð ð ð ð ñ �	�	øõ 3ð ð ð Ý—’ØZØ Øñô ð ð ð ð ð ð øøøøõ
 (ð ð ð ØÝð ð ð Ý—’ØCØ  !¨dð ñ ô ð ð ð ð ð ð øøøøðøøøð	LØ;Ð;Ð;Ð;Ð;Ð;Ø4Ð4Ð4Ð4Ð4Ð4Ø�X¥ tÔ'=×'BÒ'BÑ'DÔ'DÑ EÔ EÑEˆFð
 ð ð �Øð ˜D¨Ô(;Ð;Ð;ð   6š>˜>ð Ô*Ð*à)˜\°$Ð7Ñ7Ô7ð Ô'¨Ñ-øð
 !Ð °Ð8Ñ8Ô8Ð8Ð8øÝð 	Lð 	Lð 	LÝ�LŠLÐ;ÀdˆLÑKÔKÐKÐKÐKð	Løøøð ÐsC   œ% ¥
3²3Ä D4Ä4
FÄ>EÅFÅ6FÆFÆ"A3H È&H?È>H?r¯  r®  r   rë
  c              ƒ   óv  K  — ddl m} t          |¦  «        5   |¦   «         }t          |¦  «        }ddd¦  «         n# 1 swxY w Y   |rt	          d|› d|› d�¦  «        ‚t          d„ |j                             ¦   «         D ¦   «         ¦  «        }|r1d                     |¦  «        }t          d|› d	|› d
|› d|› d�	¦  «        ‚| j
                             |i ¦  «        }	d}
|j                             ¦   «         D �]½\  }}|j        sŒt          | j        dd¦  «        r|t          j        u rŒ3	 t          |¦  «        5  |                      ||¦  «        }ddd¦  «         n# 1 swxY w Y   n;# t$          $ r.}t&                               d||j        |d¬¦  «         Y d}~Œ¥d}~ww xY w|s"t&                               d||j        ¦  «         ŒÑ|                      ||¦  «        }|�A|                     |¦  «        }|�*t&                               d|||j        |j        ¦  «         �Œ*|                      ||¦  «        }|�Q|                     |¦  «        }|�:|dd…         \  }}t&                               d|||j        |||j        |¦  «         �Œ“|                      |||¦  «         	 t          |¦  «        5  |                      ||¦  «        ƒ d{V —†}ddd¦  «         n# 1 swxY w Y   |r:||	|<   |�|||<   |�|||<   |
dz  }
t&                               d|j        |¦  «         n=t&                               d|j        |¦  «         |                      ||¦  «        ƒ d{V —† �Œi# t$          $ rI}t&                               d|j        ||¦  «         |                      ||¦  «        ƒ d{V —† Y d}~�Œ·d}~ww xY w|
S )z>Create+connect one profile's adapters under its runtime scope.r   ©r¾  Nz	Profile 'z
' enables z„. Enable GATEWAY_ALLOW_ALL_USERS or the platform allow-all flag for that profile, or change dm_policy/group_policy away from 'open'.c              3   ól   K  — | ]/\  }}|j         ¯t          |j        |j        ¦  «        ¯&|j        V — Œ0d S r^   )rÓ  Ú_platform_binds_portr­   rÁ  )rb   r�   rÀ  s      r>   rd   z<GatewayRunner._start_one_profile_adapters.<locals>.<genexpr>5  s^   è è € ð (
ð (
á)�˜/ØÔ&ð(
õ % X¤^°_Ô5JÑKÔKð	(
ØŒNð(
ð (
ð (
ð (
ð (
ð (
rM   r  z#' enables port-binding platform(s) z‰, but gateway.multiplex_profiles is on. The default profile owns the single shared HTTP listener and serves every profile through the /p/z:/ URL prefix. Remove these platform entries from profile 'z='s config.yaml or configure them only on the default profile.r½  Fz9[MULTIPLEX] Profile '%s': _create_adapter('%s') raised %sTrß   zQ[MULTIPLEX] Profile '%s': skipping platform '%s' - adapter creation returned Noneu¸   Profile '%s' and '%s' both configure %s with the same credential â€” refusing to start the duplicate (one credential cannot be consumed twice). Give each profile its own %s credential.éþÿÿÿu°   Profile '%s' and '%s' both configure %s sidecars on %s:%s â€” refusing to start the duplicate listener. Set platforms.%s.extra.sidecar_port to a distinct port for profile '%s'.r(   u   âœ“ %s connected (profile: %s)u&   âœ— %s failed to connect (profile: %s)u   âœ— %s error (profile: %s): %s)rÆ  r¾  rº  r¢  r§  r  rE  rñ  rf   r­  r}  Ú
setdefaultrÓ  rV   rz   rÄ  r	  r˜  r2   r3   rP   r­   rã   r   rv   r¡  Ú_configure_profile_adapterr0  rz  r  )r  r¯  r®  rë
  r¾  Úprofile_cfgÚ	violationÚport_binding_platformsÚjoinedÚprofile_maprÚ  r�   rÀ  r1  r¨  r�  Úownerrž  ÚbindÚportr/  s                        r>   r©  z)GatewayRunner._start_one_profile_adapters÷4  sì  è è € ð 	7Ð6Ð6Ð6Ð6Ð6å# LÑ1Ô1ð 	Hð 	HØ-Ð-Ñ/Ô/ˆKÝ:¸;ÑGÔGˆIð	Hð 	Hð 	Hñ 	Hô 	Hð 	Hð 	Hð 	Hð 	Hð 	Hð 	Høøøð 	Hð 	Hð 	Hð 	Hð ð 	Ý&ð˜Lð ð °Ið ð ð ñô ð õ "(ð (
ð (
à-8Ô-B×-HÒ-HÑ-JÔ-Jð(
ñ (
ô (
ñ "
ô "
Ðð "ð 		Ø—Y’YÐ5Ñ6Ô6ˆFÝ1ðB˜Lð Bð BØðBð Bð +7ðBð Bð 9Eð	Bð Bð Bñô ð ð Ô,×7Ò7¸ÀbÑIÔIˆØˆ	Ø)4Ô)>×)DÒ)DÑ)FÔ)Fð [	Gñ [	GÑ%ˆH�oØ"Ô*ð Øõ
 ˜œÐ%9¸5ÑAÔAðà¥¤Ð.Ð.àðÝ+¨LÑ9Ô9ð Nð NØ"×2Ò2°8¸_ÑMÔM�GðNð Nð Nñ Nô Nð Nð Nð Nð Nð Nð Nøøøð Nð Nð Nð Nøøåð ð ð Ý—’ØOØ Ø”NØØ!ð ñ ô ð ð ����øøøøðøøøð ð Ý—’ØgØ Ø”Nñô ð ð
 ð  $×=Ò=¸hÈÑPÔPÐØÐ+ØŸšÐ$4Ñ5Ô5�ØÐ$Ý—L’Lð1ð ˜|¨X¬^¸X¼^ñô ð ñ à!×9Ò9¸(ÀGÑLÔLˆNØÐ)ØŸš NÑ3Ô3�ØÐ$Ø!/°°°Ô!4‘J�D˜$Ý—L’Lð,ð Ø$Ø œØØØ œØ$ñô ð ñ à×+Ò+¨G°\À8ÑLÔLÐLðGÝ+¨LÑ9Ô9ð ð Ø$(×$NÒ$NØ ñ%ô %ð ð ð ð ð ð �Gðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ð 
KØ,3�K Ñ)Ø'Ð3Ø4@˜Ð 0Ñ1Ø%Ð1Ø2>˜ Ñ/Ø ‘N�IÝ—K’KÐ @À(Ä.ÐR^Ñ_Ô_Ð_Ð_å—N’NÐ#KÈXÌ^Ð]iÑjÔjÐjØ×7Ò7¸ÀÑJÔJÐJÐJÐJÐJÐJÐJÐJùøÝð Gð Gð GÝ—’Ð=¸x¼~È|Ð]^Ñ_Ô_Ð_Ø×3Ò3°G¸XÑFÔFÐFÐFÐFÐFÐFÐFÐFÐFÐFÐFÐFÑFøøøøðGøøøð Ðsˆ   ˜>¾AÁAÄ.E,Ä=E ÅE,Å E$	Å$E,Å'E$	Å(E,Å,
F$Å6$FÆF$Ê%M#Ê4KËM#ËK!	Ë!M#Ë$K!	Ë%A<M#Í#
N6Í->N1Î1N6c                 ó  — |                      |                      |¦  «        ¦  «         |                     |                      ||¦  «        ¦  «         |                     | j        ¦  «         |                     | j        ¦  «         t          |dd¦  «        }t          |¦  «        r || j
        ¦  «         |                     | j        ¦  «         |                     |                      ||¬¦  «        ¦  «         | j        |_        dS )zDInstall the profile-scoped handlers shared by startup and reconnect.r`  N)r¯  )rš  Ú_make_profile_message_handlerrœ  Ú!_make_profile_fatal_error_handlerr�  r›  rž  r
  rV   r/  r’  rŸ  rf  r   r¡  r&  )r  r1  r¯  r�   rÒ  s        r>   r·  z(GatewayRunner._configure_profile_adaptery5  s  € ð 	×#Ò# D×$FÒ$FÀ|Ñ$TÔ$TÑUÔUÐUØ×'Ò'Ø×2Ò2°<ÀÑJÔJñ	
ô 	
ð 	
ð 	×!Ò! $Ô"4Ñ5Ô5Ð5Ø×(Ò(¨Ô)QÑRÔRÐRÝ Ð)?ÀÑFÔFˆÝ�MÑ"Ô"ð 	7ØˆM˜$Ô5Ñ6Ô6Ð6Ø×%Ò% dÔ&LÑMÔMÐMØ×'Ò'Ø×)Ò)¨(ÀÐ)ÑNÔNñ	
ô 	
ð 	
ð #'Ô"6ˆÔÐÐrM   c              ƒ   ó¶  K  — d}t          j        ¦   «         }	 | j        �r+d}	 ddlm} ddlm}  ||¦  «        }t          |¦  «        5   |¦   «         j         	                    |¦  «        }	|	�|	j
        sÔ	 ddd¦  «         | j        }
t          |
t          ¦  «        r¤|
 	                    |¦  «        }t          |t          ¦  «        r| 	                    |¦  «        nd}t          |t           j        ¦  «        r||u rIt          |t          ¦  «        r2|                     |d¦  «         |s|
                     |d¦  «         dS dS dS dS dS |                      ||	¦  «        }|€õt"                               d|j        |¦  «         	 ddd¦  «         | j        }
t          |
t          ¦  «        r¤|
 	                    |¦  «        }t          |t          ¦  «        r| 	                    |¦  «        nd}t          |t           j        ¦  «        r||u rIt          |t          ¦  «        r2|                     |d¦  «         |s|
                     |d¦  «         dS dS dS dS dS |                      |||¦  «         |                      ||d¬¦  «        ƒ d{V —†}ddd¦  «         n# 1 swxY w Y   |�r| j        �r	| j                             |i ¦  «        }||v�r|||<   |                      |¦  «         t"                               d|j        |¦  «         	 | j        }
t          |
t          ¦  «        r¤|
 	                    |¦  «        }t          |t          ¦  «        r| 	                    |¦  «        nd}t          |t           j        ¦  «        r||u rIt          |t          ¦  «        r2|                     |d¦  «         |s|
                     |d¦  «         dS dS dS dS dS |                      ||¦  «        ƒ d{V —† 	 | j        }
t          |
t          ¦  «        r¤|
 	                    |¦  «        }t          |t          ¦  «        r| 	                    |¦  «        nd}t          |t           j        ¦  «        r||u rIt          |t          ¦  «        r2|                     |d¦  «         |s|
                     |d¦  «         dS dS dS dS dS |rå|                      ||¦  «        ƒ d{V —† 	 | j        }
t          |
t          ¦  «        r¤|
 	                    |¦  «        }t          |t          ¦  «        r| 	                    |¦  «        nd}t          |t           j        ¦  «        r||u rIt          |t          ¦  «        r2|                     |d¦  «         |s|
                     |d¦  «         dS dS dS dS dS |                      ||¦  «        ƒ d{V —† t7          |d	d
¦  «        rÚt7          |dd¦  «        sÉ	 | j        }
t          |
t          ¦  «        r¤|
 	                    |¦  «        }t          |t          ¦  «        r| 	                    |¦  «        nd}t          |t           j        ¦  «        r||u rIt          |t          ¦  «        r2|                     |d¦  «         |s|
                     |d¦  «         dS dS dS dS dS n~# t           j        $ r  |�|                      ||¦  «        ƒ d{V —† ‚ t:          $ rD |�|                      ||¦  «        ƒ d{V —† t"                               d|j        |d¬¦  «         Y nw xY w| j        sÉ	 | j        }
t          |
t          ¦  «        r¤|
 	                    |¦  «        }t          |t          ¦  «        r| 	                    |¦  «        nd}t          |t           j        ¦  «        r||u rIt          |t          ¦  «        r2|                     |d¦  «         |s|
                     |d¦  «         dS dS dS dS dS |dz  }t?          |¦  «        }t"                               d|j        ||¦  «         t          j         |¦  «        ƒ d{V —† | j        �°+| j        }
t          |
t          ¦  «        r¤|
 	                    |¦  «        }t          |t          ¦  «        r| 	                    |¦  «        nd}t          |t           j        ¦  «        r||u rIt          |t          ¦  «        r2|                     |d¦  «         |s|
                     |d¦  «         dS dS dS dS dS # | j        }
t          |
t          ¦  «        r£|
 	                    |¦  «        }t          |t          ¦  «        r| 	                    |¦  «        nd}t          |t           j        ¦  «        r||u rFt          |t          ¦  «        r0|                     |d¦  «         |s|
                     |d¦  «         w w w w w xY w)zDReconnect a retryable secondary adapter under its own profile scope.r   N©Úget_profile_dirr²  zASecondary %s reconnect skipped: adapter unavailable (profile: %s)Tr'  u    âœ“ %s reconnected (profile: %s)r£  FrŸ  z3Secondary %s reconnect attempt failed (profile: %s)rß   r(   z1Secondary %s reconnect retry in %ds (profile: %s))!r  rÿ
  r’  r?  rÅ  rÆ  r¾  rº  rE  rv   rÓ  r4  rt   ru   rU  rU  r˜  r3   rã   r­   r·  r-  r}  r¶  r  rz  r  rV   r›  r2   r4   r  r–  )r  r¯  r�   r›  rÿ
  r1  rÅ  r¾  r®  Úprofile_configr5  rV  rÝ   r/  r¼  rã  s                   r>   Ú _run_secondary_profile_reconnectz.GatewayRunner._run_secondary_profile_reconnect�5  s^  è è € ð ˆÝÔ+Ñ-Ô-ˆðZ	<Ø”-ñ O-Ø�ðAØCÐCÐCÐCÐCÐCØBÐBÐBÐBÐBÐBà#2 ?°<Ñ#@Ô#@�LÝ/°Ñ=Ô=ð ð Ø)<Ð)<Ñ)>Ô)>Ô)H×)LÒ)LÈXÑ)VÔ)V˜Ø)Ð1¸Ô9OÐ1Ø"ðð ð ñ ô ð ðT Ô4ˆGÝ˜'¥4Ñ(Ô(ð <Ø")§+¢+¨lÑ";Ô";�Ý8BÀ?ÕTXÑ8YÔ8YÐc�×*Ò*¨8Ñ4Ô4Ð4Ð_c�Ý! $­¬Ñ5Ô5ð <¸ÀÐ9MÐ9MÝ! /µ4Ñ8Ô8ð <Ø'×+Ò+¨H°dÑ;Ô;Ð;Ø.ð <Ø#ŸKšK¨°dÑ;Ô;Ð;Ð;Ð;ð<ð <ð<ð <ð :NÐ9Mð<ð <ð[ #'×"6Ò"6°xÀÑ"PÔ"P˜Ø"˜?Ý"ŸNšNØ cØ (¤Ø ,ñô ð ð
 #ðð ð ñ ô ð ðT Ô4ˆGÝ˜'¥4Ñ(Ô(ð <Ø")§+¢+¨lÑ";Ô";�Ý8BÀ?ÕTXÑ8YÔ8YÐc�×*Ò*¨8Ñ4Ô4Ð4Ð_c�Ý! $­¬Ñ5Ô5ð <¸ÀÐ9MÐ9MÝ! /µ4Ñ8Ô8ð <Ø'×+Ò+¨H°dÑ;Ô;Ð;Ø.ð <Ø#ŸKšK¨°dÑ;Ô;Ð;Ð;Ð;ð<ð <ð<ð <ð :NÐ9Mð<ð <ðK ×7Ò7Ø# \°8ñô ð ð )-×(JÒ(JØ# X¸Dð )Kñ )ô )ð #ð #ð #ð #ð #ð #˜ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð& ñ  4¤=ñ Ø&*Ô&<×&GÒ&GÈÐVXÑ&YÔ&Y˜Ø#¨;Ð6Ñ6Ø4;˜K¨Ñ1Ø ×BÒBÀ7ÑKÔKÐKÝ"ŸKšKØ BØ (¤Ø ,ñô ð ð
 #ðZ Ô4ˆGÝ˜'¥4Ñ(Ô(ð <Ø")§+¢+¨lÑ";Ô";�Ý8BÀ?ÕTXÑ8YÔ8YÐc�×*Ò*¨8Ñ4Ô4Ð4Ð_c�Ý! $­¬Ñ5Ô5ð <¸ÀÐ9MÐ9MÝ! /µ4Ñ8Ô8ð <Ø'×+Ò+¨H°dÑ;Ô;Ð;Ø.ð <Ø#ŸKšK¨°dÑ;Ô;Ð;Ð;Ð;ð<ð <ð<ð <ð :NÐ9Mð<ð <ðc #×;Ò;¸GÀXÑNÔNÐNÐNÐNÐNÐNÐNÐNØðR Ô4ˆGÝ˜'¥4Ñ(Ô(ð <Ø")§+¢+¨lÑ";Ô";�Ý8BÀ?ÕTXÑ8YÔ8YÐc�×*Ò*¨8Ñ4Ô4Ð4Ð_c�Ý! $­¬Ñ5Ô5ð <¸ÀÐ9MÐ9MÝ! /µ4Ñ8Ô8ð <Ø'×+Ò+¨H°dÑ;Ô;Ð;Ø.ð <Ø#ŸKšK¨°dÑ;Ô;Ð;Ð;Ð;ð<ð <ð<ð <ð :NÐ9Mð<ð <ðW ð Ø"×;Ò;¸GÀXÑNÔNÐNÐNÐNÐNÐNÐNÐNØðD Ô4ˆGÝ˜'¥4Ñ(Ô(ð <Ø")§+¢+¨lÑ";Ô";�Ý8BÀ?ÕTXÑ8YÔ8YÐc�×*Ò*¨8Ñ4Ô4Ð4Ð_c�Ý! $­¬Ñ5Ô5ð <¸ÀÐ9MÐ9MÝ! /µ4Ñ8Ô8ð <Ø'×+Ò+¨H°dÑ;Ô;Ð;Ø.ð <Ø#ŸKšK¨°dÑ;Ô;Ð;Ð;Ð;ð<ð <ð<ð <ð :NÐ9Mð<ð <ðO ×7Ò7¸ÀÑJÔJÐJÐJÐJÐJÐJÐJÐJå Ð):¸EÑBÔBðå '¨Ð1HÈ$Ñ OÔ Oðð ð6 Ô4ˆGÝ˜'¥4Ñ(Ô(ð <Ø")§+¢+¨lÑ";Ô";�Ý8BÀ?ÕTXÑ8YÔ8YÐc�×*Ò*¨8Ñ4Ô4Ð4Ð_c�Ý! $­¬Ñ5Ô5ð <¸ÀÐ9MÐ9MÝ! /µ4Ñ8Ô8ð <Ø'×+Ò+¨H°dÑ;Ô;Ð;Ø.ð <Ø#ŸKšK¨°dÑ;Ô;Ð;Ð;Ð;ð<ð <ð<ð <ð :NÐ9Mð<ð <øøõC Ô-ð ð ð ØÐ*Ø"×;Ò;¸GÀXÑNÔNÐNÐNÐNÐNÐNÐNÐNØÝ ð ð ð ØÐ*Ø"×;Ò;¸GÀXÑNÔNÐNÐNÐNÐNÐNÐNÐNÝ—L’LØMØ œØ$Ø!%ð	 !ñ ô ð ð ð ðøøøð ”}ð Øð Ô4ˆGÝ˜'¥4Ñ(Ô(ð <Ø")§+¢+¨lÑ";Ô";�Ý8BÀ?ÕTXÑ8YÔ8YÐc�×*Ò*¨8Ñ4Ô4Ð4Ð_c�Ý! $­¬Ñ5Ô5ð <¸ÀÐ9MÐ9MÝ! /µ4Ñ8Ô8ð <Ø'×+Ò+¨H°dÑ;Ô;Ð;Ø.ð <Ø#ŸKšK¨°dÑ;Ô;Ð;Ð;Ð;ð<ð <ð<ð <ð :NÐ9Mð<ð <ð# ˜A‘�Ý,¨XÑ6Ô6�Ý—’ØGØ”NØØ ñ	ô ð õ ”m GÑ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,ð_ ”-ñ O-ðb Ô4ˆGÝ˜'¥4Ñ(Ô(ð <Ø")§+¢+¨lÑ";Ô";�Ý8BÀ?ÕTXÑ8YÔ8YÐc�×*Ò*¨8Ñ4Ô4Ð4Ð_c�Ý! $­¬Ñ5Ô5ð <¸ÀÐ9MÐ9MÝ! /µ4Ñ8Ô8ð <Ø'×+Ò+¨H°dÑ;Ô;Ð;Ø.ð <Ø#ŸKšK¨°dÑ;Ô;Ð;Ð;Ð;ð<ð <ð<ð <ð :NÐ9Mð<ð <øð Ô4ˆGÝ˜'¥4Ñ(Ô(ð <Ø")§+¢+¨lÑ";Ô";�Ý8BÀ?ÕTXÑ8YÔ8YÐc�×*Ò*¨8Ñ4Ô4Ð4Ð_c�Ý! $­¬Ñ5Ô5ð <¸ÀÐ9MÐ9MÝ! /µ4Ñ8Ô8ð <Ø'×+Ò+¨H°dÑ;Ô;Ð;Ø.ð <Ø#ŸKšK¨°dÑ;Ô;Ð;Ð;ð<ð<ð :Nð<øøøs†   ™
d ¤&Z& Á
-JÁ7Z& Å
:JÆZ& É5JÊZ& ÊJÊZ& ÊJÊ A)Z& ÏZ& Ò7Z& Ö>Z& Ú%d Ú&A8\!Üd Ü \!Ü!
d ß4Ad äCgc                 óð  — | j         r|j        sdS | j        }t          |t          ¦  «        s	i }|| _        |                     |i ¦  «        }||v rdS t          j        |                      ||¦  «        d|› d|j	        › �¬¦  «        }|||<   t          | dd¦  «        }t          |t          ¦  «        st          ¦   «         }|| _        |                     |¦  «         |                     |j        ¦  «         dS )zDSchedule one runner-owned reconnect without sharing primary secrets.Nzsecondary-reconnect:rÉ  )rÖ   r¼  )r’  rŸ  r4  rt   ru   r¶  r  r”  rÇ  r­   rV   r•   r¼  r—   rä  rü  )r  r¯  r�   r1  r5  rV  rÝ   Úbackground_taskss           r>   Ú%_schedule_secondary_profile_reconnectz3GatewayRunner._schedule_secondary_profile_reconnectñ5  s  € ð Œ}ð 	 GÔ$Að 	ØˆFØÔ0ˆÝ˜'¥4Ñ(Ô(ð 	5ØˆGØ-4ˆDÔ*Ø!×,Ò,¨\¸2Ñ>Ô>ˆØ�Ð&Ð&ØˆFÝÔ"Ø×1Ò1°,ÀÑIÔIØG¨ÐGÐG°x´~ÐGÐGð
ñ 
ô 
ˆð %)ˆ˜Ñ!Ý" 4Ð)<¸dÑCÔCÐÝÐ*­CÑ0Ô0ð 	6Ý"™uœuÐØ%5ˆDÔ"Ø×Ò˜TÑ"Ô"Ð"Ø×ÒÐ/Ô7Ñ8Ô8Ð8Ð8Ð8rM   c                 ó.   ‡ ‡‡— dt           ddfˆˆˆ fd„}|S )zGRoute a secondary-profile fatal error to that profile's reconnect slot.r1  r-   Nc              “   óF   •K  — ‰                      ‰‰| ¦  «        ƒ d {V —† d S r^   )Ú#_handle_profile_adapter_fatal_error)r1  r�   r¯  r  s    €€€r>   Ú_handlerzAGatewayRunner._make_profile_fatal_error_handler.<locals>._handler6  s8   øè è € Ø×:Ò:¸<ÈÐSZÑ[Ô[Ð[Ð[Ð[Ð[Ð[Ð[Ð[Ð[Ð[rM   ©rG  )r  r¯  r�   rÎ  s   ``` r>   rÂ  z/GatewayRunner._make_profile_fatal_error_handler
6  sM   øøø€ ð	\Õ$7ð 	\¸Dð 	\ð 	\ð 	\ð 	\ð 	\ð 	\ð 	\ð 	\ð ˆrM   c              ƒ   óæ  K  — t          | di ¦  «                             |¦  «        }t          |t          ¦  «        r|                     |¦  «        |ur#t                               d|j        |¦  «         dS |                     |d¦  «         |                      ||¦  «        ƒ d{V —† | j	        sdS |  
                    |||¦  «         t                               d|j        ||j        pd¦  «         dS )am  Remove a failed multiplexed adapter without touching the primary slot.

        Secondary adapters are owned by ``_profile_adapters`` rather than
        ``self.adapters``. The primary-only fatal handler intentionally ignores
        them; without this route, a fatal secondary Discord client stayed live
        forever after its liveness sampler stopped.
        r}  zBIgnoring stale fatal error from secondary %s adapter (profile: %s)Nz6Fatal %s adapter error for multiplexed profile %s (%s)r¼  )rV   rv   rt   ru   r3   r4   r­   rU  r  r’  rÊ  rP   r´  )r  r¯  r�   r1  r¼  s        r>   rÍ  z1GatewayRunner._handle_profile_adapter_fatal_error6  s  è è € õ ˜dÐ$7¸Ñ<Ô<×@Ò@ÀÑNÔNˆÝ˜+¥tÑ,Ô,ð 	°·²ÀÑ0IÔ0IÐQXÐ0XÐ0XÝ�LŠLØTØ”Øñô ð ð
 ˆFØ�Š˜ $Ñ'Ô'Ð'Ø×+Ò+¨G°XÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>ØŒ}ð 	ØˆFØ×2Ò2°<ÀÈ7ÑSÔSÐSÝ�ŠØDØŒNØØÔ$Ð1¨	ñ		
ô 	
ð 	
ð 	
ð 	
rM   c                 ód   ‡ ‡‡— ddl m} 	  |‰¦  «        Šn# t          $ r dŠY nw xY wˆˆˆ fd„}|S )at  Return a message handler that stamps source.profile then delegates.

        Auth runs inside ``_handle_message`` *before* the agent-turn scope is
        installed. For secondary profiles under multiplex, wrap the whole
        handler in ``_profile_runtime_scope`` so allowlists/tokens from that
        profile's ``.env`` are visible to ``get_secret`` / authz.
        r   rÄ  Nc              “   ó<  •K  — 	 t          | dd ¦  «        �| j        j        s‰| j        _        n# t          $ r Y nw xY w‰�Bt	          ‰¦  «        5  ‰                     | ¦  «        ƒ d {V —†cd d d ¦  «         S # 1 swxY w Y   ‰                     | ¦  «        ƒ d {V —†S )Nr(  )rV   r(  r  r2   rº  rü  )rÖ  r®  r¯  r  s    €€€r>   rÎ  z=GatewayRunner._make_profile_message_handler.<locals>._handlerE6  s
  øè è € ðÝ˜5 (¨DÑ1Ô1Ð=ÀeÄlÔFZÐ=Ø+7�E”LÔ(øøÝð ð ð Ø�ðøøøàÐ'Ý+¨LÑ9Ô9ð =ð =Ø!%×!5Ò!5°eÑ!<Ô!<Ð<Ð<Ð<Ð<Ð<Ð<ð=ð =ð =ð =ñ =ô =ð =ð =ð =ð =ð =ð =øøøð =ð =ð =ð =à×-Ò-¨eÑ4Ô4Ð4Ð4Ð4Ð4Ð4Ð4Ð4s   …)/ ¯
<»<ÁA8Á8A<Á?A<)r?  rÅ  r2   )r  r¯  rÅ  rÎ  r®  s   ``  @r>   rÁ  z+GatewayRunner._make_profile_message_handler66  s}   øøø€ ð 	8Ð7Ð7Ð7Ð7Ð7ð	 Ø*˜?¨<Ñ8Ô8ˆLˆLøÝð 	 ð 	 ð 	 ØˆLˆLˆLð	 øøøð		5ð 		5ð 		5ð 		5ð 		5ð 		5ð 		5ð ˆs   ‹ —&¥&c                 óL   ‡ ‡— t          t          ¦   «         ¦  «        Šˆˆ fd„}|S )z@Scope a multiplexed default-profile message from ingress onward.c              “   ó�   •K  — t          ‰¦  «        5  ‰                     | ¦  «        ƒ d {V —†cd d d ¦  «         S # 1 swxY w Y   d S r^   )rº  rü  )rÖ  r®  r  s    €€r>   rÎ  zEGatewayRunner._make_default_profile_message_handler.<locals>._handlerV6  sœ   øè è € Ý'¨Ñ5Ô5ð 9ð 9Ø!×1Ò1°%Ñ8Ô8Ð8Ð8Ð8Ð8Ð8Ð8ð9ð 9ð 9ð 9ñ 9ô 9ð 9ð 9ð 9ð 9ð 9ð 9øøøð 9ð 9ð 9ð 9ð 9ð 9s   “;»?Á?)r   rx  )r  rÎ  r®  s   ` @r>   Ú%_make_default_profile_message_handlerz3GatewayRunner._make_default_profile_message_handlerR6  s<   øø€ å�OÑ-Ô-Ñ.Ô.ˆð	9ð 	9ð 	9ð 	9ð 	9ð 	9ð ˆrM   c                 ód   — t          | j        dd¦  «        r|                      ¦   «         S | j        S )z:Return the correctly scoped handler for a primary adapter.r½  F)rV   rz   rÕ  rü  rN  s    r>   r›  z&GatewayRunner._primary_message_handler\6  s5   € å�4”;Ð 4°eÑ<Ô<ð 	@Ø×=Ò=Ñ?Ô?Ð?ØÔ#Ð#rM   c                 óF   — t                                |¦  «        }|€dS | |fS )z?Return the exclusive credential resource claimed by an adapter.N)r
  r¨  )r�   r1  Úfingerprints      r>   r   z'GatewayRunner._adapter_credential_claimb6  s-   € õ
 $×CÒCÀGÑLÔLˆØÐØ�4Ø˜+Ð&Ð&rM   c                 óp  — t          | dd¦  «        dk    rdS t          |dd¦  «        }t          |dd¦  «        }t          |t          ¦  «        r|                     ¦   «         sdS 	 t	          |¦  «        }n# t
          t          f$ r Y dS w xY wdd|                     ¦   «                              ¦   «         |fS )a¢  Return the exclusive listener resource claimed by an adapter.

        Photon sidecars are per-profile processes. Even when two profiles use
        different project credentials, their sidecars cannot share a bind and
        port. Represent that endpoint as a claim so multiplex startup rejects
        the later adapter before either ``connect()`` or ``disconnect()`` can
        disturb the first profile.
        r­   NÚphotonÚ_sidecar_bindÚ_sidecar_portÚlistener)rV   rt   rw   rx   rh  rw  rj  ry   )r�   r1  r¾  r¿  s       r>   r¡  z%GatewayRunner._adapter_listener_claiml6  sÄ   € õ �8˜W dÑ+Ô+¨xÒ7Ð7Ø�4Ý�w °Ñ6Ô6ˆÝ�w °Ñ6Ô6ˆÝ˜$¥Ñ$Ô$ð 	¨D¯JªJ©L¬Lð 	Ø�4ð	Ý�t‘9”9ˆDˆDøÝ�:Ð&ð 	ð 	ð 	Ø�4�4ð	øøøà˜H d§j¢j¡l¤l×&8Ò&8Ñ&:Ô&:¸DÐAÐAs   Á&A6 Á6BÂ
Bc                 óà  — d}dD ]R}t          | |d¦  «        }t          |t          ¦  «        r*|                     ¦   «         r|                     ¦   «         } nŒS|sht          | dd¦  «        }|�UdD ]R}t          ||d¦  «        }t          |t          ¦  «        r*|                     ¦   «         r|                     ¦   «         } nŒS|s_t          | dd¦  «        }t          |dd¦  «        }t          |t          ¦  «        r(|                     ¦   «         r|                     ¦   «         }|sdS ddl}|                     d|z                        d¦  «        ¦  «                             ¦   «         dd	…         S )
as  Return a stable, log-safe fingerprint of an adapter's credential.

        Used only to detect two profiles claiming the same platform credential.
        Returns a salted hash (never the credential itself) of the adapter's
        primary credential, or None when no credential is discoverable (in
        which case we don't attempt conflict detection for it).
        N)rÄ  Ú	bot_tokenÚ_tokenÚ	api_tokenÚ
_bot_tokenÚ_project_secretrz   )rÄ  rß  rÄ  r   zhermes-mux:rQ  é   )rV   rt   rw   rx   ÚhashlibÚsha256ÚencodeÚ	hexdigest)r1  rÄ  ÚattrÚvalrœ  rz   rå  s          r>   r¨  z-GatewayRunner._adapter_credential_fingerprint‚6  s€  € ð ˆð

ð 	ð 	ˆDõ ˜' 4¨Ñ.Ô.ˆCÝ˜#�sÑ#Ô#ð ¨¯	ª	©¬ð ØŸ	š	™œ�Ø�øð ð 	Ý˜' 8¨TÑ2Ô2ˆCØˆØ2ð ð �DÝ! # t¨TÑ2Ô2�CÝ! #¥sÑ+Ô+ð °·	²	±´ð Ø #§	¢	¡¤˜Ø˜øØð 	$Ý˜W h°Ñ5Ô5ˆFÝ˜& '¨4Ñ0Ô0ˆCÝ˜#�sÑ#Ô#ð $¨¯	ª	©¬ð $ØŸ	š	™œ�Øð 	Ø�4ØˆˆˆØ�~Š~˜}¨uÑ4×<Ò<¸WÑEÔEÑFÔF×PÒPÑRÔRÐSVÐTVÐSVÔWÐWrM   c                 óÎ  — t          |d¦  «        rnt          |j        t          ¦  «        rT|j                             d| j        j        ¦  «         |j                             dt          | j        dd¦  «        ¦  «         	 ddlm	} | 
                    |j        ¦  «        rH|                     |j        |¦  «        }|�	| |_        |S t                               d|j        ¦  «         dS n8# t           $ r+}t                               d	|j        |¦  «         Y d}~nd}~ww xY w|t$          j        k    r9dd
lm}m}  |¦   «         st                               d¦  «         dS  ||¦  «        S |t$          j        k    rbddlm}m}	m}
  |	¦   «         st                               d¦  «         dS  |
|¦  «        st                               d¦  «         dS  ||¦  «        S |t$          j        k    r9ddlm}m }  |¦   «         st                               d¦  «         dS  ||¦  «        S |t$          j!        k    rBddl"m#}m$}  |¦   «         st                               d¦  «         dS  ||¦  «        }| |_        |S |t$          j%        k    rBddl&m'}m(}  |¦   «         st                               d¦  «         dS  ||¦  «        }| |_        |S |t$          j)        k    r9ddl*m+}m,}  |¦   «         st                               d¦  «         dS  ||¦  «        S |t$          j-        k    r9ddl.m/}m0}  |¦   «         st                               d¦  «         dS  ||¦  «        S |t$          j1        k    r9ddl2m3}m4}  |¦   «         st                               d¦  «         dS  ||¦  «        S |t$          j5        k    r1ddl6m7}m8} |st                               d¦  «         dS  ||¦  «        S dS )zÃCreate the appropriate adapter for a platform.

        Checks the platform_registry first (plugin adapters), then falls
        through to the built-in if/elif chain for core platforms.
        rÁ  r<  r=  Fr   rM  NzWPlatform '%s' is registered but adapter creation failed (check dependencies and config)z,Platform registry lookup for '%s' failed: %s)ÚWhatsAppCloudAdapterÚ!check_whatsapp_cloud_requirementsu@   WhatsApp Cloud: aiohttp/httpx missing â€” reinstall hermes-agent)ÚSignalAdapterÚcheck_signal_requirementsÚvalidate_signal_configz$Signal: runtime requirements not metz8Signal: SIGNAL_HTTP_URL or SIGNAL_ACCOUNT not configured)ÚWeixinAdapterÚcheck_weixin_requirementsz*Weixin: aiohttp/cryptography not installed)ÚAPIServerAdapterÚcheck_api_server_requirementsz!API Server: aiohttp not installed)ÚWebhookAdapterÚcheck_webhook_requirementszWebhook: aiohttp not installed)ÚMSGraphWebhookAdapterÚ"check_msgraph_webhook_requirementsz&MSGraph webhook: aiohttp not installed)ÚBlueBubblesAdapterÚcheck_bluebubbles_requirementsz`BlueBubbles: aiohttp/httpx missing or BLUEBUBBLES_SERVER_URL/BLUEBUBBLES_PASSWORD not configured)Ú	QQAdapterÚcheck_qq_requirementszIQQBot: aiohttp/httpx missing or QQ_APP_ID/QQ_CLIENT_SECRET not configured)ÚYuanbaoAdapterÚWEBSOCKETS_AVAILABLEz>Yuanbao: websockets not installed. Run: pip install websockets)9rá   rt   rÁ  ru   r¶  rz   r<  rV   r‘  rN  Úis_registeredr­   Úcreate_adapterÚgateway_runnerr3   rP   r2   r4   rÄ  ÚWHATSAPP_CLOUDÚ gateway.platforms.whatsapp_cloudrì  rí  rã   ÚSIGNALÚgateway.platforms.signalrî  rï  rð  ÚWEIXINÚgateway.platforms.weixinrñ  rò  rÒ  Úgateway.platforms.api_serverró  rô  rÓ  Úgateway.platforms.webhookrõ  rö  rË  Ú!gateway.platforms.msgraph_webhookr÷  rø  ÚBLUEBUBBLESÚgateway.platforms.bluebubblesrù  rú  ÚQQBOTÚgateway.platforms.qqbotrû  rü  ÚYUANBAOÚgateway.platforms.yuanbaorý  rþ  )r  r�   rz   rN  r1  r¨  rì  rí  rî  rï  rð  rñ  rò  ró  rô  rõ  rö  r÷  rø  rù  rú  rû  rü  rý  rþ  s                            r>   r˜  zGatewayRunner._create_adapter³6  sD  € õ �6˜7Ñ#Ô#ð 	­
°6´<ÅÑ(FÔ(Fð 	ØŒL×#Ò#Ø)Ø”Ô3ñô ð ð ŒL×#Ò#Ø*Ý˜œÐ%?ÀÑGÔGñô ð ð	\ØCÐCÐCÐCÐCÐCØ ×.Ò.¨x¬~Ñ>Ô>ð Ø+×:Ò:¸8¼>È6ÑRÔR�ØÐ&ð .2�GÔ*Ø"�Nõ —’ð6à”Nñô ð ð
 �tð'øõ( ð 	\ð 	\ð 	\Ý�LŠLÐGÈÌÐYZÑ[Ô[Ð[Ð[Ð[Ð[Ð[Ð[øøøøð	\øøøð •xÔ.Ò.Ð.ðð ð ð ð ð ð ð ð 5Ð4Ñ6Ô6ð Ý—’ØVñô ð ð �tØ'Ð'¨Ñ/Ô/Ð/à�œÒ(Ð(ðð ð ð ð ð ð ð ð ð ð
 -Ð,Ñ.Ô.ð Ý—’ÐEÑFÔFÐFØ�tØ)Ð)¨&Ñ1Ô1ð Ý—’ÐYÑZÔZÐZØ�tØ �= Ñ(Ô(Ð(à�œÒ(Ð(ØYÐYÐYÐYÐYÐYÐYÐYØ,Ð,Ñ.Ô.ð Ý—’ÐKÑLÔLÐLØ�tØ �= Ñ(Ô(Ð(à�Ô,Ò,Ð,ØdÐdÐdÐdÐdÐdÐdÐdØ0Ð0Ñ2Ô2ð Ý—’ÐBÑCÔCÐCØ�tØ&Ð& vÑ.Ô.ˆGØ%)ˆGÔ"ØˆNà�Ô)Ò)Ð)Ø\Ð\Ð\Ð\Ð\Ð\Ð\Ð\Ø-Ð-Ñ/Ô/ð Ý—’Ð?Ñ@Ô@Ð@Ø�tØ$�n VÑ,Ô,ˆGØ%)ˆGÔ"ØˆNà�Ô1Ò1Ð1ðð ð ð ð ð ð ð ð 6Ð5Ñ7Ô7ð Ý—’ÐGÑHÔHÐHØ�tØ(Ð(¨Ñ0Ô0Ð0à�Ô-Ò-Ð-ØhÐhÐhÐhÐhÐhÐhÐhØ1Ð1Ñ3Ô3ð Ý—’ð   Bñ  Cô  Cð  CØ�tØ%Ð% fÑ-Ô-Ð-à�œÒ'Ð'ØPÐPÐPÐPÐPÐPÐPÐPØ(Ð(Ñ*Ô*ð Ý—’ÐjÑkÔkÐkØ�tØ�9˜VÑ$Ô$Ð$à�Ô)Ò)Ð)ØVÐVÐVÐVÐVÐVÐVÐVØ'ð Ý—’Ð_Ñ`Ô`Ð`Ø�tØ!�> &Ñ)Ô)Ð)àˆts   Â AC) Ã C) Ã)
DÃ3!DÄDc           	      ó†   ‡ ‡‡— 	 	 ddt           dt          t                    dt          t                    dt          fˆˆˆ fd„}|S )u@  Build a platform-bound auth callback for adapter use.

        Adapters that fetch external context (e.g. Slack
        ``conversations.replies``) call this through
        ``BasePlatformAdapter._is_sender_authorized`` to mark non-allowlisted
        senders as unverified in LLM context, mitigating indirect prompt
        injection from third parties in shared threads/channels.

        The returned callback delegates to :meth:`_is_user_authorized` so the
        full auth chain â€” platform allowlists, group allowlists, pairing
        store, allow-all flags â€” stays the single source of truth.

        ``profile_name`` binds the callback to the secondary adapter's own
        multiplex profile, so its ``SessionSource`` resolves that profile's
        secret scope instead of falling back to the active profile.
        Nr¹  r´  r2  r-   c                 óf   •— | sdS t          ‰|pd|pd| ‰¬¦  «        }‰                     |¦  «        S )NFr®   rð   )r�   r2  r´  r¹  r  )r[  rí	  )r¹  r´  r2  r(  r�   r¯  r  s       €€€r>   Úcheckz5GatewayRunner._make_adapter_auth_check.<locals>.checkK7  sT   ø€ ð
 ð Ø�uÝ"Ø!Ø˜ 2Ø#Ð. wØØ$ðñ ô ˆFð ×+Ò+¨FÑ3Ô3Ð3rM   rT  )rw   r   rº   )r  r�   r¯  r  s   ``` r>   r¡  z&GatewayRunner._make_adapter_auth_check67  sm   øøø€ ð. (,Ø%)ð	4ð 	4Ýð	4å¥”}ð	4õ �c”]ð	4õ ð		4ð 	4ð 	4ð 	4ð 	4ð 	4ð 	4ð 	4ð ˆrM   r4  c           	   ƒ   ó$  K  — |                       |¦  «        }|sdS t          | dd¦  «        }|rjt          |dd¦  «        t          j        k    rKt	          |t          |dd¦  «        ¦  «        r,t
                               dt          |dd¦  «        ¦  «         dS d}|r*t          |d¦  «        r|                     |j	        ¦  «        }|  
                    |¦  «        }|dk    r‹t          |d	d¦  «        rz	 |                     |j        |j        ||¬
¦  «        ƒ d{V —†}t          |dd¦  «        rdS n<# t          $ r/ t
                               dt          |dd¦  «        d¬¦  «         Y nw xY w|                     |j        ||¬
¦  «        ƒ d{V —† dS )zIDeliver a setup/operational notice using platform-specific privacy rules.Nrz   r�   r2  z@Skipping Slack platform notice for configured ignored channel %sÚpublicÚget_notice_deliveryÚprivater¹  r.  r/  Fz7[%s] send_private_notice failed, falling back to publicr¿  Trß   )r@  rV   rÄ  rÅ  rÐ  r3   rz  rá   r  r�   rî	  Úsend_private_noticer2  r¹  r2   r4   r0  )r  r(  r4  r1  rz   Únotice_deliveryr¯   r·  s           r>   r/  z&GatewayRunner._deliver_platform_noticea7  s  è è € à×*Ò*¨6Ñ2Ô2ˆØð 	ØˆFå˜˜x¨Ñ.Ô.ˆàð		å˜ 
¨DÑ1Ô1µX´^ÒCÐCÝ)¨&µ'¸&À)ÈTÑ2RÔ2RÑSÔSð Dõ �KŠKØRÝ˜ 	¨4Ñ0Ô0ñô ð ð ˆFà"ˆØð 	J•g˜fÐ&;Ñ<Ô<ð 	JØ$×8Ò8¸¼ÑIÔIˆOà×3Ò3°FÑ;Ô;ˆØ˜iÒ'Ð'­G°F¸IÀtÑ,LÔ,LÐ'ðØ&×:Ò:Ø”NØ”NØØ%ð	  ;ñ  ô  ð ð ð ð ð ð �õ ˜6 9¨eÑ4Ô4ð Ø�Fðøåð ð ð Ý—’ØMÝ˜F J°Ñ4Ô4Ø!ð ñ ô ð ð ð ðøøøð �lŠl˜6œ>¨7¸XˆlÑFÔFÐFÐFÐFÐFÐFÐFÐFÐFÐFs   Ã4:D1 Ä16E*Å)E*r\  Úpinned_session_idc              ƒ   ó¢  K  — t          t          | j        ¦  «        }|€t                               d¦  «         dS d}	 |                     |¦  «        ƒ d{V —†}n-# t          $ r  t                               d|d¬¦  «         Y nw xY w|€t                               d|¦  «         dS |}d}|                     d¦  «        �rä|                     d	¦  «        d
k    r1t                               d||                     d	¦  «        ¦  «         dS d}	 | 	                    |¦  «        ƒ d{V —†}n/# t          $ r" t                               d|d¬¦  «         d}Y nw xY w|r||k    rt                               d|¦  «         dS 	 |                     |¦  «        ƒ d{V —†}n# t          $ r d}Y nw xY w|�|                     d¦  «        r"t                               d||€dnd¦  «         dS |j
        ||hv }|sŒ	 |                     |j
        ¦  «        ƒ d{V —†}	|	�N|	                     d¦  «        r9|	                     d	¦  «        d
k    r | 	                    |j
        ¦  «        ƒ d{V —†nd}
n# t          $ r d}
Y nw xY w|
|k    }|s$t                               d|||j
        ¦  «         dS ||j
        k    r|S |j
        }|r(| j                             |j        ||¦  «        ƒ d{V —†}n&| j                             |j        |¦  «        ƒ d{V —†}|€#t                               d|j        |¦  «         dS t                               d|||j        ¦  «         |S )a©  Resolve an async completion to its verified owning gateway session.

        A compression rotation ends the physical parent row while continuing
        the same logical conversation in a child.  Follow that lineage, but
        never let a late completion override an unrelated /new or restored
        route.  Unknown ownership remains fail-closed; the result is still
        available in the delegation records.
        Nz]Async-delegation completion has no session database; dropping injection (#55578 fail-closed).z,Async-delegation parent lookup failed for %sTrß   zeAsync-delegation completion has unknown spawning session %s; dropping injection (#55578 fail-closed).FÚended_atÚ
end_reasonrm   z‹Async-delegation completion pinned to ended session %s (end_reason=%r); dropping injection instead of resurrecting it (#55578 fail-closed).z5Async-delegation compression-tip lookup failed for %szgAsync-delegation completion pinned to compressed session %s without a continuation; dropping injection.zGAsync-delegation compression continuation %s is %s; dropping injection.r¼  ÚendedzoAsync-delegation completion for compression lineage %s -> %s does not own current route %s; dropping injection.zcAsync-delegation completion could not bind routing key %s to owning session %s; dropping injection.z\Pinned async-delegation completion to owning session %s (was %s) for routing key %s (#57498))r   r   rR   r3   rã   r�  r2   r4   rv   Úget_compression_tiprN   r8
  Úadvance_compression_sessionr+   rú  rz  )r  r\  r  rX   Ú
pinned_rowÚtarget_session_idÚfollows_compressionÚtip_rowÚroute_owns_lineageÚ	route_rowÚ	route_tipÚprior_session_idr  s                r>   Ú!_resolve_async_delegation_sessionz/GatewayRunner._resolve_async_delegation_session‹7  sí  è è € õ �#˜tÔ/Ñ0Ô0ˆ
ØÐÝ�NŠNð;ñô ð ð �4àˆ
ð	Ø)×5Ò5Ð6GÑHÔHÐHÐHÐHÐHÐHÐHˆJˆJøÝð 	ð 	ð 	Ý�LŠLØ>Ø!Øð ñ ô ð ð ð ð	øøøð ÐÝ�NŠNð;à!ñô ð ð
 �4à-ÐØ#ÐØ�>Š>˜*Ñ%Ô%ñ J	Ø�~Š~˜lÑ+Ô+¨}Ò<Ð<Ý—’ð,ð &Ø—N’N <Ñ0Ô0ñô ð ð �tà"&Ðð
)Ø*4×*HÒ*HØ%ñ+ô +ð %ð %ð %ð %ð %ð %Ð!Ð!øõ ð )ð )ð )Ý—’ØKØ%Ø!ð ñ ô ð ð
 %)Ð!Ð!Ð!ð)øøøð %ð Ð(9Ð=NÒ(NÐ(NÝ—’ðBà%ñô ð ð
 �tðØ *× 6Ò 6Ð7HÑ IÔ IÐIÐIÐIÐIÐIÐI��øÝð ð ð Ø���ðøøøàˆ '§+¢+¨jÑ"9Ô"9ˆÝ—’ð*à%Ø!( �I�I°gñ	ô ð ð �tà!.Ô!9Ø!Ø!ð>ð "Ðð &ð Dð
%Ø&0×&<Ò&<¸]Ô=UÑ&VÔ&VÐ VÐ VÐ VÐ VÐ VÐ V�Ið %Ð0Ø%ŸMšM¨*Ñ5Ô5ð 1à%ŸMšM¨,Ñ7Ô7¸=ÒHÐHð )×<Ò<¸]Ô=UÑVÔVÐVÐVÐVÐVÐVÐVÐVð "ð �Iøõ !ð %ð %ð %Ø $�I�I�Ið%øøøà%.Ð2CÒ%CÐ"à%ð Ý—’ðIà%Ø%Ø!Ô,ñô ð ð �tà Ô 8Ò8Ð8Ø Ð à(Ô3ÐØð 
	Ø!Ô5×QÒQØÔ)Ø Ø!ñô ð ð ð ð ð ð ˆHˆHð "Ô5×DÒDØÔ)Ø!ñô ð ð ð ð ð ð ˆHð ÐÝ�NŠNð9àÔ)Ø!ñ	ô ð ð �4å�Šð3àØØÔ%ñ	
ô 	
ð 	
ð ˆsH   ¾A Á'BÂBÄD) Ä))EÅEÅ>F ÆF)Æ(F)Ç3A2I& É&I5É4I5u=   Agent is running â€” wait or /stop first, then switch models.u>   Agent is running â€” wait or /stop first, then change runtime.u8   Agent is running â€” wait or /stop first, then run /moa.)r  úcodex-runtimeÚmoaÚ_BUSY_REJECT_TEXTÚ	quick_keyc              ƒ   ó  K  — |j         }t          |dd¦  «        }t          |dd¦  «        }|rs| j        | j        | j        | j        | j        | j        | j        dœ 	                    |¦  «        }|� ||||¦  «        ƒ d{V —†S | j
         	                    |¦  «        }	|	�|	S |dv rÛi d| j        “d| j        “d	| j        “d
| j        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “d| j        “| j        | j        dœ¥ 	                    |¦  «        }
|
� |
|¦  «        ƒ d{V —†S t<                               d||¦  «         d|› d�S )u`  Dispatch a recognized slash command while an agent is running.

        Resolution order:
          1. ``busy_handler`` â€” special mid-run variant (e.g. /goal's
             control-verb whitelist, /queue's FIFO enqueue, /model's
             custom reject text).
          2. ``busy_policy == "dispatch"`` â€” the command's normal handler.
          3. Catch-all busy-reject text. Rejecting is required rather than
             falling through to interrupt + discard: commands like /model,
             /reasoning, /voice, /insights, /title, /resume, /retry,
             /undo, /compress, /usage, /reload-mcp, /sethome, /reset (all
             registered as Discord slash commands) would interrupt the
             agent AND get silently discarded by the slash-command safety
             net, producing a zero-char response. See #5057, #6252, #10370.
        Úbusy_policyrÜ	  Úbusy_handlerN)r§  r¨  r   r™  r	  ÚegressÚgoal)ÚdispatchÚinterrupt_then_dispatchÚstatusrÙ   r	  rÖ	  rÛ	  ÚpauseÚagentsÚ
backgroundÚkanbanÚsubgoalÚ	heartbeatÚyolor'  ÚfooterÚhelpÚcommandsr  )rI  ÚversionuM   busy_policy=%s for /%s has no mid-run handler â€” falling back to busy-rejectu   â�³ Agent is running â€” `/zE` can't run mid-turn. Wait for the current response or `/stop` first.) rÖ   rV   Ú_busy_start_commandÚ_busy_stop_commandÚ_busy_new_commandÚ_busy_queue_commandÚ_busy_steer_commandÚ_busy_egress_commandÚ_busy_goal_commandrv   r,  Ú_handle_status_commandÚ_handle_context_commandÚ_handle_restart_commandrð	  rñ	  Ú_handle_pause_commandÚ_handle_agents_commandÚ_handle_background_commandÚ_handle_kanban_commandÚ_handle_subgoal_commandÚ_handle_heartbeat_commandÚ_handle_yolo_commandÚ_handle_verbose_commandÚ_handle_footer_commandÚ_handle_help_commandÚ_handle_commands_commandÚ_handle_profile_commandÚ_handle_update_commandÚ_handle_version_commandr3   rã   )r  rÖ  Úcmd_defr-  r(  rÖ   ÚpolicyÚhandler_keyÚspecialÚreject_textÚplains              r>   Ú_dispatch_busy_slash_commandz*GatewayRunner._dispatch_busy_slash_command58  ss  è è € ð$ Œ|ˆÝ˜ -°Ñ:Ô:ˆÝ˜g ~°tÑ<Ô<ˆàð 	#àÔ1ØÔ/ØÔ-ØÔ1ØÔ1ØÔ3ØÔ/ðð ÷ Šc�+ÑÔð ð Ð"Ø$˜W U¨I°vÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>ØÔ0×4Ò4°[ÑAÔAˆKØÐ&Ø"Ð"àÐ<Ð<Ð<ðØ˜$Ô5ðà˜4Ô7ðð ˜4Ô7ðð ˜4Ô7ð	ð
 ˜Ô1ðð ˜Ô3ðð ˜$Ô5ðð ˜dÔ=ðð ˜$Ô5ðð ˜4Ô7ðð ˜TÔ;ðð ˜Ô1ðð ˜4Ô7ðð ˜$Ô5ðð ˜Ô1ðð  ˜DÔ9ð!ð" ˜4Ô7ð#ð$ Ô5ØÔ7ð'ð ð ÷( Šc�$‰iŒið) ð* Ð Ø"˜U 5™\œ\Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ý�NŠNð.Ø/5°tñô ð ðI¨$ð Ið Ið Ið	
rM   c              ƒ   óˆ  K  — ddl m} |                     ¦   «         pd                     ¦   «         }|                     ¦   «         dv r|                     ¦   «         rdS dS |                     ¦   «         }|�'|s%|                     d¦  «        }|rd	|› d
�nd}d|› d�S |                     |pd¬¦  «         |rd	|› d
�nd}d|› d�S )u\  `/pause [reason]` engages the global emergency stop; `/pause off`
        (aliases: resume/stop) lifts it.

        This is the in-band resume path for messaging-only operators â€” the
        estop gate above deliberately lets recognized slash commands through
        while paused so a user without host-shell access is never locked out.
        r   )Úestopr®   >   r  r¨  ÚresumeÚ	disengageu.   â–¶ï¸� Resumed â€” new work is accepted again.zHermes wasn't paused.Nr•  z
 (reason: rŠ  u   â�¸ï¸� Hermes is already pausedz. Use `/pause off` to resume.r  u   â�¸ï¸� Pausedzh. New cron/kanban/gateway work is on hold; in-flight work finishes normally. Use `/pause off` to resume.)	rµ   ra  Úget_command_argsrx   ry   rc  Ú	get_staterv   Úengage)r  rÖ  ra  r¸  r;   r•  r  s          r>   rK  z#GatewayRunner._handle_pause_command€8  s$  è è € ð 	 ÐÐÐÐÐà×&Ò&Ñ(Ô(Ð.¨B×5Ò5Ñ7Ô7ˆØ�:Š:‰<Œ<ÐAÐAÐAØ�ŠÑ Ô ð HØGÐGØ*Ð*Ø—’Ñ!Ô!ˆØÐ TÐØ—Y’Y˜xÑ(Ô(ˆFØ/5Ð=Ð+ &Ð+Ð+Ð+Ð+¸2ˆFð.°&ð .ð .ð .ðð 	�Š˜D˜L DˆÑ)Ô)Ð)Ø)-Ð5Ð%˜dÐ%Ð%Ð%Ð%°2ˆðL˜Fð Lð Lð Lð	
rM   c              ƒ   ó@   K  — t                                d|¦  «         dS )Nz3Ignoring /start platform ping for active session %sr®   ©r3   rz  ©r  rÖ  r-  r(  s       r>   rA  z!GatewayRunner._busy_start_commandž8  s"   è è € õ 	�ŠÐIÈ9ÑUÔUÐUØˆrrM   c              ƒ   ó&   K  — ddl m}  |¦   «         S )Nr   ©Úformat_status_text)Úhermes_cli.proxy_clirl  )r  rÖ  r-  r(  rl  s        r>   rF  z"GatewayRunner._busy_egress_command¥8  s'   è è € Ø;Ð;Ð;Ð;Ð;Ð;à!Ð!Ñ#Ô#Ð#rM   c              ƒ   ó¼   K  — |                       ||t          d¬¦  «        ƒ d {V —† t                               d|¦  «         t	          t          d¦  «        ¦  «        S )NÚstop_command©Úinterrupt_reasonÚinvalidation_reasonu@   STOP for session %s â€” agent interrupted, session lock releasedzgateway.stop.stopped)Ú_interrupt_and_clear_sessionÚ_INTERRUPT_REASON_STOPr3   rz  rq  r   ri  s       r>   rB  z GatewayRunner._busy_stop_commandª8  s~   è è € ð ×/Ò/ØØÝ3Ø .ð	 0ñ 
ô 
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
õ 	�ŠÐVÐXaÑbÔbÐbÝ�aÐ 6Ñ7Ô7Ñ8Ô8Ð8rM   c              ƒ   ó„   K  — |                       ||t          d¬¦  «        ƒ d {V —† |                      |¦  «        ƒ d {V —†S )NÚnew_commandrp  )rs  Ú_INTERRUPT_REASON_RESETÚ_handle_reset_commandri  s       r>   rC  zGatewayRunner._busy_new_command¹8  sw   è è € ð ×/Ò/ØØÝ4Ø -ð	 0ñ 
ô 
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð ×/Ò/°Ñ6Ô6Ð6Ð6Ð6Ð6Ð6Ð6Ð6rM   c              ƒ   ó   K  — |                      ¦   «                              ¦   «         }t          t          |dd ¦  «        ¦  «        }|s|sdS |                      |¦  «        }|rät          di d|“d|r|j        nt          j        “d|j	        “d|j
        “d|j        “dt          t          |dg ¦  «        pg ¦  «        “dt          t          |dg ¦  «        pg ¦  «        “d	|j        “d
|j        “d|j        “d|j        “d|j        “d|j        “d|j        “d|j        “d|j        “d|j        “Ž}|                      |||¦  «         |                      ||                      |¦  «        ¬¦  «        }|dk    rdS d|› d�S )Nrì  úUsage: /queue <prompt>rè   rÚ  r(  Úraw_messagerj  rÕ  r5
  Úreply_to_textÚreply_to_author_idÚreply_to_author_nameÚreply_to_is_own_messageÚ
auto_skillr´  Úchannel_contextrã	  rg  r   r(   zQueued for the next turn.zQueued for the next turn. (z queued)rN  )rd  rx   rº   rV   r@  rr  rÚ  rs  rÀ	  r(  r{  rj  r½  r5
  r|  r}  r~  r  r€  r´  r�  rã	  rg  r	  r'	  )	r  rÖ  r-  r(  Úqueued_textÚ	has_mediar1  r	  rÓ   s	            r>   rD  z!GatewayRunner._busy_queue_commandÌ8  s  è è € ð
 ×,Ò,Ñ.Ô.×4Ò4Ñ6Ô6ˆõ
 � ¨°dÑ;Ô;Ñ<Ô<ˆ	Øð 	, 9ð 	,Ø+Ð+Ø×*Ò*¨6Ñ2Ô2ˆØð 	AÝ'ð ð ð Ø �[ðà3<ÐR˜UÔ/Ð/Å+ÔBRøðð ”|�|ðð "Ô-Ð-ð	ð
 !Ô+Ð+ðõ  ¥¨¨|¸RÑ @Ô @Ð FÀBÑGÔGÐGðõ !¥¨°¸rÑ!BÔ!BÐ!HÀbÑIÔIÐIðð %*Ô$=Ð$=ðð $Ô1Ð1ðð $)Ô#;Ð#;ðð &+Ô%?Ð%?ðð ).Ô(EÐ(Eðð !Ô+Ð+ðð  %Ô3Ð3ðð !&Ô 5Ð 5ðð  œ˜ð!ð"  œ/˜/ð#ˆLð& ×Ò˜y¨,¸Ñ@Ô@Ð@Ø×!Ò! )°T×5MÒ5MÈfÑ5UÔ5UÐ!ÑVÔVˆØ�AŠ:ˆ:Ø.Ð.Ø<¨UÐ<Ð<Ð<Ð<rM   c              ƒ   ó\  K  — |                      ¦   «                              ¦   «         }|sdS |                      |¦  «        }|r|j        j        nd }|t
          u rc|                      |¦  «        }|rJt          |t          j	        |j
        |j        |j        |j        ¬¦  «        }|                      |||¦  «         dS |r‹t          |d¦  «        r{	 |                     |¦  «        }	n8# t"          $ r+}
t$                               d||
¦  «         d|
› �cY d }
~
S d }
~
ww xY w|	r(|d d…         t)          |¦  «        dk    rdnd	z   }d
|› d�S dS |                      |¦  «        }|rJt          |t          j	        |j
        |j        |j        |j        ¬¦  «        }|                      |||¦  «         dS )NzUsage: /steer <prompt>)rè   rÚ  r(  rj  r´  r�  u9   Agent still starting â€” /steer queued for the next turn.r	  zSteer failed for session %s: %su   âš ï¸� Steer failed: rø  r  r®   u8   â�© Steer queued â€” arrives after the next tool call: 'rV  zSteer rejected (empty payload).u4   No active agent â€” /steer queued for the next turn.)rd  rx   rA   rJ  rµ   rž  r@  rr  rs  rÀ	  r(  rj  r´  r�  r	  rá   r	  r2   r3   rã   r7   )r  rÖ  r-  r(  r
  Ú_steer_stater«	  r1  r	  Úacceptedr<   r  s               r>   rE  z!GatewayRunner._busy_steer_commandô8  s  è è € ð ×+Ò+Ñ-Ô-×3Ò3Ñ5Ô5ˆ
Øð 	,Ø+Ð+Ø×/Ò/°	Ñ:Ô:ˆØ3?ÐI˜Ô)Ô/Ð/ÀTˆØÕ3Ð3Ð3à×.Ò.¨vÑ6Ô6ˆGØð 	EÝ+Ø#Ý!,Ô!1Ø œ<Ø$Ô/Ø#(Ô#7Ø$)Ô$9ð ñ  ô  �ð ×"Ò" 9¨l¸GÑDÔDÐDØNÐNØð 		5�W ]°GÑ<Ô<ð 		5ð5Ø(×.Ò.¨zÑ:Ô:��øÝð 5ð 5ð 5Ý—’Ð@À)ÈSÑQÔQÐQØ4¨sÐ4Ð4Ð4Ð4Ð4Ð4Ð4Ð4øøøøð5øøøð ð ]Ø$ S b Sœ/µc¸*±o´oÈÒ6JÐ6J¨U¨UÐPRÑS�Ø\ÐRYÐ\Ð\Ð\Ð\Ø4Ð4à×*Ò*¨6Ñ2Ô2ˆØð 		AÝ'ØÝ(Ô-Ø”|Ø Ô+Ø$Ô3Ø %Ô 5ðñ ô ˆLð ×Ò˜y¨,¸Ñ@Ô@Ð@ØEÐEs   ÃC' Ã'
DÃ1 DÄDÄDc              ƒ   ó  K  — |                      ¦   «         pd                     ¦   «                              ¦   «         }|r|                     d d¦  «        d         nd}| p|dv p|dv }|r|                      |¦  «        ƒ d {V —†S dS )Nr®   r(   r   >   r  r¨  r4  r6  rb  r5  Úunwait>   ÚgaterB  ui   Agent is running â€” use /goal status / pause / clear / wait mid-run, or /stop before setting a new goal.)rd  rx   ry   re   Ú_handle_goal_command)r  rÖ  r-  r(  Ú	_goal_argÚ
_goal_verbÚ_is_controls          r>   rG  z GatewayRunner._busy_goal_command%9  s¶   è è € ð ×+Ò+Ñ-Ô-Ð3°×:Ò:Ñ<Ô<×BÒBÑDÔDˆ	Ø4=ÐE�Y—_’_ T¨1Ñ-Ô-¨aÔ0Ð0À2ˆ
ð ˆMð .ØÐ\Ð\ð.àÐ-Ð-ð 	ð
 ð 	:Ø×2Ò2°5Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9ØzÐzrM   c              ƒ   óL\  ‡ ‡‡¦‡§K  — ‰j         }	 ddlm}  |¦   «          n,# t          $ r t                               dd¬¦  «         Y nw xY wt          t          ‰dd¦  «        ¦  «        }|syt          |dd	¦  «        t          j	        k    rZt          t          ‰ d
d	¦  «        t          |dd	¦  «        ¦  «        r,t                               dt          |dd	¦  «        ¦  «         d	S t          ‰ dd¦  «        r*|s(t          ‰dd¦  «        s‰                      ‰¦  «         d	S |s‰                      ¦   «          |�s4	 ddlm}  |d‰‰ t          ‰ dd	¦  «        ¬¦  «        }n4# t          $ r'}t                               d|¦  «         g }Y d	}~nd	}~ww xY w|D ]×}t#          |t$          ¦  «        sŒ|                     d¦  «        }	|	dk    rMt                               d|                     d¦  «        |j        r|j        j        nd|j        pd¦  «          d	S |	dk    rI|                     d¦  «        }
t#          |
t.          ¦  «        rt1          j        ‰|
¬¦  «        Š‰j         } n	|	dk    r nŒØ|r�n|j        €>‰                      |¦  «        s't                               d|j        j        ¦  «         d	S �nÕ‰                      |¦  «        �s¿t                               d|j        |j        |j        j        ¦  «         |j        dk    �r€‰                      |j        |j        ¬ ¦  «        d!k    �rZ|j        r|j        j        nd}‰                       |¦  «        }|€t           !                    d"|¦  «         d	S | "                    ||j        ¦  «        rd	S | #                    ||j        |j        pd#¦  «        }|r|‰  $                    |¦  «        }|rdt          |d$d	¦  «        }t#          |t.          ¦  «        r|r|d%k    rd&|› d'�nd#}| %                    |j        d(|› d)|› d*|› d'|› d+�	¦  «        ƒ d	{V —† nS‰  $                    |¦  «        }|r!| %                    |j        d,¦  «        ƒ d	{V —† | &                    ||j        ¦  «         d	S |�sf	 dd-l'm(}  |¦   «         }n# tR          $ r d	}Y nw xY w|��?d}d	}	 ‰ *                    ¦   «         }n# t          $ r d	}Y nw xY w|r'	 dd.l+m,}  ||¦  «        d	u}n# t          $ r d}Y nw xY w|s™	 ‰  -                    |¦  «        }‰  .                    |¦  «        }|�|j/        j0        rd}|s‰  1                    |¦  «        rd}|sdd/l2m3} | 4                    |¦  «        rd}|sdd0l5m6}  ||¦  «        rd}n# t          $ r Y nw xY w|sMt                               d1t          t          |dd	¦  «        d2d¦  «        t          |dd	¦  «        pd¦  «         |S ‰  -                    |¦  «        }‰  .                    |¦  «        }|��>|j/        j0        �r1‰j7        pd# 8                    ¦   «         }‰ *                    ¦   «         }|d3v rd4}nX|d5v rd6}nQd	}|rF	 dd.l+m,}  n# t          $ r d	} Y nw xY w| �*	  | |¦  «        }!|!r|!j9        nd	}n# t          $ r d	}Y nw xY w|rd#}n|}|rØtt          d7z  }"tt          d8z  }#	 |" ;                    d9¦  «        }$|$ <                    |d:¬;¦  «         |$                     |"¦  «         |# =                    d¬<¦  «         n7# t|          $ r*}%t                               d=|%¦  «         d>|%› �cY d	}%~%S d	}%~%ww xY wd|j/        _0        t          |¦  «        d?k    r|n|d	d?…         d@z   }&dA|&› dB�S |rÇtt          d7z  }"tt          d8z  }#	 |" ;                    d9¦  «        }$|$ <                    d#d:¬;¦  «         |$                     |"¦  «         |# =                    d¬<¦  «         t                               dC||¦  «         n2# t|          $ r%}%t                               dD|%¦  «         Y d	}%~%nd	}%~%ww xY wd|j/        _0        d	}'	 ddEl2m@}' |' A                    |d¬F¦  «        }(n# t          $ r d	}(Y nw xY w|(��|'��t          ‰  B                    ‰¦  «        ¦  «        })‰  C                    ‰¦  «        ƒ d	{V —†}*|)r%|*s#t                               dG||(jD        ¦  «         d#S |*r¯|* E                    dH¦  «        sš|' F                    ||*¦  «        }+|+r‚t                               dI||(jD        ¦  «         ‰  $                    |¦  «        },|,rH	 |, G                    |j        ¦  «         n,# t          $ r t                               dJd¬¦  «         Y nw xY wd#S dd/l2m3}- |- 4                    |¦  «        }.d}/	 dd0l5m6}0  |0|¦  «        }/n# t          $ r d}/Y nw xY w|.rÎ|/sÌ‰j7        pd# 8                    ¦   «         }1|1 H                    dK¦  «         I                    ¦   «         }2‰ *                    ¦   «         }3d	}4|3dLv rdM}4n"|3dNv rdO}4n|3dPv rdQ}4n|2dRv rdM}4n|2dSv rdO}4n|2dTv rdQ}4|4�4|- J                    ||.                     dU¦  «        |4¦  «        ƒ d	{V —†}+|+pd#S |- K                    |¦  «         t™          dVdW¦  «        }5‰  .                    |¦  «        }6|6r|6jM        jN        nd}7|6��y|6jM        jO        ��l|7�rit¡          jP        ¦   «         |7z
  }8|6jM        jO        }9t£          dX¦  «        }:d#};|9r¤t¥          |9dY¦  «        r”	 |9 S                    ¦   «         }<|<                     dZt£          dX¦  «        ¦  «        }:d[|<                     d\d¦  «        › d]|:d^›d_|<                     d`d¦  «        › dH|<                     dad¦  «        › �};n# t          $ r Y nw xY w|5dk    rt©          |5dbz  dc¦  «        nt£          dX¦  «        }=|9tª          uo|5dk    r|:|5k    p|8|=k    }>|>rKt                               dd||8|:|5|;¦  «         ‰  V                    |de¬f¦  «         ‰  W                    |¦  «         ‰  1                    |¦  «        �r±dd.l+m,}? ‰ *                    ¦   «         }@|@r |?|@¦  «        nd	}A|Ar&|Aj9        dgk    r‰  X                    ‰¦  «        ƒ d	{V —†S |Ar&|Aj9        dhk    r‰  Y                    ‰¦  «        ƒ d	{V —†S |@r!|A�‰  Z                    ||Aj9        ¦  «        }B|B�|BS |Ar‰  [                    ‰|A||¦  «        ƒ d	{V —†S ‰j\        tº          j^        k    rJt                               di|¦  «         ‰  $                    |¦  «        }|rt¿          |j`        |‰¦  «         d	S t£          tÃ          jb        djdk¦  «        ¦  «        }C‰  .                    |¦  «        }D|Dr|DjM        jN        nd}E|j        t          jc        k    r»‰j\        tº          jd        k    r¦|Cdk    r |Eržt¡          jP        ¦   «         |Ez
  |Ck    r„t                               dlt¡          jP        ¦   «         |Ez
  |¦  «         ‰  $                    |¦  «        }|r;‰ je        dmk    r‰  f                    |‰|¦  «         nt¿          |j`        |‰d¬n¦  «         d	S ‰  .                    |¦  «        }F|Fr|FjM        jO        nd	}G|Gtª          u rˆ‰ *                    ¦   «         dok    r?‰  W                    |¦  «         t                               dp|¦  «         tÏ          dq¦  «        S ‰  $                    |¦  «        }|rt¿          |j`        |‰d¬n¦  «         d	S ‰ jh        rn‰  i                    ¦   «         r‰  j                    |‰¦  «         ‰  i                    ¦   «         rdr‰  k                    ¦   «         › ds�ndt‰  k                    ¦   «         › du�S ‰ je        dmk    r3t                               dv|¦  «         ‰  j                    |‰¦  «         d	S ‰ je        dwk    rý‰j7        pd# 8                    ¦   «         }Hd}I‰j\        tº          jd        k    ry‰jl        sr‰jm        sk|Hrit¥          |Gdw¦  «        rY	 t          |G n                    |H¦  «        ¦  «        }In5# t          $ r(}Jt                               dx||J¦  «         d}IY d	}J~Jnd	}J~Jww xY w|Irt                               dy|¦  «         d	S t                               dz|¦  «         ‰  j                    |‰¦  «         d	S ‰  o                    |G¦  «        r3t                               d{|¦  «         ‰  j                    |‰¦  «         d	S ‰  p                    |¦  «        ƒ d	{V —†r3t                               d||¦  «         ‰  j                    |‰¦  «         d	S ‰j\        tº          jd        k    r±‰jl        sª‰jm        s£t          |Gd}d¦  «        du r�t¥          |Gd~¦  «        r€	 |G q                    ‰j7        pd# 8                    ¦   «         ¦  «        rt                               d|¦  «         d	S n3# t          $ r&}Jt                               d€||J¦  «         Y d	}J~Jnd	}J~Jww xY wt                               d�|¦  «         ‰j7        }Kt          ‰d‚d	¦  «        pg }L‰  B                    ‰¦  «        r>‰  r                    ‰‰  $                    |¦  «        |‰j7        pd#dƒ¬„¦  «        ƒ d	{V —†\  }K}Mn|Ks|Lrtç          ‰¦  «        }K|G t                    |K¦  «         d	S ‰ *                    ¦   «         }Ndd…l+mu}Omv}Pm,}Q |Nr |Q|N¦  «        nd	}!|!r|!j9        n|N}R|N�re|!�€bt#          ‰ jw        t$          ¦  «        r‰ jw                             d†i ¦  «        pi }Snt          ‰ jw        d†i ¦  «        pi }St#          |St$          ¦  «        rý|N|Sv rù|S|N         }T|T                     d‡¦  «        dˆk    rØ|T                     d‰¦  «        pd# 8                    ¦   «         }U|Ur­|U E                    dH¦  «        r|UndH|U› �}U|U H                    dH¦  «        }V‰ x                    ¦   «          8                    ¦   «         }W|U› d'|W› � 8                    ¦   «         ‰_7        |Vr|V y                    ¦   «         d         n|V}N|Nr |Q|N¦  «        nd	}!|!r|!j9        n|N}R|Nr'|Rr% |P|R¦  «        r‰  Z                    ||R¦  «        }B|B�|BS |N�rg |P|R¦  «        �r[‰ x                    ¦   «          8                    ¦   «         }X|j        r|j        j        nd#|j        |R|N|X|XdŠœ}Y	 ‰ jz         {                    d‹|R› �|Y¦  «        ƒ d	{V —†}Zn5# t          $ r(}[t                               dŒ|R|[¦  «         g }ZY d	}[~[nd	}[~[ww xY w|ZD �]µ}\t#          |\t$          ¦  «        sŒt/          |\                     d�d#¦  «        ¦  «         8                    ¦   «          I                    ¦   «         }]|]r|]dk    rŒi|]dŽk    r8|\                     d�¦  «        }^t#          |^t.          ¦  «        r|^r|^c S d�|N› d‘�c S |]d’k    r2|\                     d�¦  «        }^t#          |^t.          ¦  «        r|^r|^nd	c S |]dk    rÐt/          |\                     d“d#¦  «        ¦  «         8                    ¦   «          H                    dH¦  «        }_|_s�Œ1t/          |\                     d”d#¦  «        ¦  «         8                    ¦   «         }`dH|_› d'|`› � 8                    ¦   «         ‰_7        ‰ *                    ¦   «         }N|Nr |Q|N¦  «        nd	}!|!r|!j9        n|N}R n�Œ·|Rd•k    r‰  |                    ‰¦  «        ƒ d	{V —†S |Rd–k    rZtû          j~        ‰ j        |¦  «        ƒ d	{V —†r‰  €                    ¦   «         S ˆˆ fd—„}a‰  �                    ‰d–d˜d™|a¬š¦  «        ƒ d	{V —†S |Rd›k    r‰  ‚                    ‰¦  «        ƒ d	{V —†S |Rdœk    r‰  ƒ                    ‰¦  «        ƒ d	{V —†S |Rd�k    rt                               dž|¦  «         d#S |RdŸk    r‰  „                    ‰¦  «        ƒ d	{V —†S |Rd$k    r‰  …                    ‰¦  «        ƒ d	{V —†S |Rd k    r‰  †                    ‰¦  «        ƒ d	{V —†S |Rdgk    r‰  X                    ‰¦  «        ƒ d	{V —†S |Rd¡k    rdd¢l‡mˆ}b  |b¦   «         S |Rdhk    r‰  Y                    ‰¦  «        ƒ d	{V —†S |Rd£k    r‰  ‰                    ‰¦  «        ƒ d	{V —†S |Rdk    r‰  Š                    ‰¦  «        ƒ d	{V —†S |Rd¤k    r‰  ‹                    ‰¦  «        ƒ d	{V —†S |Rdok    r‰  Œ                    ‰¦  «        ƒ d	{V —†S |Rd¥k    r‰  �                    ‰¦  «        ƒ d	{V —†S |Rd¦k    r‰  Ž                    ‰¦  «        ƒ d	{V —†S |Rd§k    r‰  �                    ‰¦  «        ƒ d	{V —†S |Rd¨k    rßdd©l�m‘}c ‰ x                    ¦   «          8                    ¦   «         }d|drdªnd«}e	 ‰  $                    |¦  «        }|rE‰  ’                    |¦  «        }f| %                    t/          |j        ¦  «        |e|f¬¬¦  «        ƒ d	{V —† n,# t          $ r t                               d­d¬¦  «         Y nw xY w	  |c|d¦  «        ‰_7        n# t          $ r Y d®S w xY w|Rd¯k    rädd°l“m”}g ‰ x                    ¦   «          8                    ¦   «         }h	  |g|h¬±¦  «        }in# t          $ r Y d²S w xY wd³|iv rd´ndµ}e	 ‰  $                    |¦  «        }|rE‰  ’                    |¦  «        }f| %                    t/          |j        ¦  «        |e|f¬¬¦  «        ƒ d	{V —† n,# t          $ r t                               d¶d¬¦  «         Y nw xY w|i‰_7        |Rd·k    r‰  •                    ‰¦  «        ƒ d	{V —†S |Rd¸k    r‰  –                    ‰¦  «        ƒ d	{V —†S |Rd¹k    r‰  —                    ‰¦  «        ƒ d	{V —†S |Rdºk    r‰  ˜                    ‰¦  «        ƒ d	{V —†S |Rd»k    r‰  ™                    ‰¦  «        ƒ d	{V —†S |Rd¼k    r‰  š                    ‰¦  «        ƒ d	{V —†S |Rd½k    r‰  ›                    ‰¦  «        ƒ d	{V —†S |Rd¾k    r‰  œ                    ‰¦  «        ƒ d	{V —†S |Rd¿k    r‰  �                    ‰¦  «        ƒ d	{V —†S |RdÀk    r‰  ž                    ‰¦  «        ƒ d	{V —†S |RdÁk    �r‰  Ÿ                    ‰¦  «        ƒ d	{V —†}jt          |jdÂd	¦  «        }k|krËt          |jdd#¦  «        pd#}e|erŠ	 ‰  $                    |¦  «        }|rE‰  ’                    |¦  «        }f| %                    t/          |j        ¦  «        |e|f¬¬¦  «        ƒ d	{V —† n,# t          $ r t                               dÃd¬¦  «         Y nw xY w	 |k‰_7        n6# t          $ r t          |jdd#¦  «        pd	cY S w xY wt          |jdd#¦  «        pd	S |RdÄk    r‰                       ‰¦  «        ƒ d	{V —†S |RdÅk    r±ˆˆ fdÆ„}ldÇ}m‰ x                    ¦   «          8                    ¦   «         }n|nrS	 t©          dÇ�tC          |n y                    ¦   «         d         ¦  «        ¦  «        }mn# �tD          �tF          f$ r dÇ}mY nw xY w|mdÇk    rdÈndÉ|m› dÊ�}o‰  �                    ‰dÅdË|o|l¬š¦  «        ƒ d	{V —†S |RdÌk    r‰  ¤                    ‰¦  «        ƒ d	{V —†S |RdÍk    r‰  ¥                    ‰¦  «        ƒ d	{V —†S |RdÎk    r‰  ¦                    ‰¦  «        ƒ d	{V —†S |RdÏk    r‰  §                    ‰¦  «        ƒ d	{V —†S |RdÐk    r‰  ¨                    ‰¦  «        ƒ d	{V —†S |RdÑk    r‰  ©                    ‰¦  «        ƒ d	{V —†S |RdÒk    r‰  ª                    ‰¦  «        ƒ d	{V —†S |RdÓk    r‰  «                    ‰¦  «        ƒ d	{V —†S |RdÔk    r‰  ¬                    ‰¦  «        ƒ d	{V —†S |RdŽk    r‰  ­                    ‰¦  «        ƒ d	{V —†S |RdÕk    r‰  ®                    ‰¦  «        ƒ d	{V —†S |RdÖk    r‰  ¯                    ‰¦  «        ƒ d	{V —†S |Rd×k    r‰  °                    ‰¦  «        ƒ d	{V —†S |RdØk    r‰  ±                    ‰¦  «        ƒ d	{V —†S |RdÙk    r‰  ²                    ‰¦  «        ƒ d	{V —†S |RdÚk    r‰  ³                    ‰¦  «        ƒ d	{V —†S |RdÛk    r‰  ´                    ‰¦  «        ƒ d	{V —†S |RdÜk    r‰  µ                    ‰¦  «        ƒ d	{V —†S |RdÝk    r‰  ¶                    ‰¦  «        ƒ d	{V —†S |RdÞk    r‰  ·                    ‰¦  «        ƒ d	{V —†S |Rdmk    rC‰ x                    ¦   «          8                    ¦   «         }p|psdßS 	 |p‰_7        n# t          $ r Y nw xY w|Rdwk    rC‰ x                    ¦   «          8                    ¦   «         }q|qsdàS 	 |q‰_7        n# t          $ r Y nw xY w|Rdák    r‰  ¸                    ‰¦  «        ƒ d	{V —†S |Rdâk    r‰  ¹                    ‰¦  «        ƒ d	{V —†S |Rdãk    r‰  º                    ‰¦  «        ƒ d	{V —†S |Rdäk    �rddål»m¼}rm½}s ddæl¾m¿}t ‰ x                    ¦   «          8                    ¦   «         }u|us
 |r¦   «         S 	  |t¦   «         }v |st#          |vt$          ¦  «        r|v                     dä¦  «        ni ¦  «        }wn# t          $ r  |si ¦  «        }wY nw xY w|wdç         }x	 |u‰_7        ‰  À                    |¦  «        }y|yjÁ        jÂ        ‰_Ã        dä|xdèdédêdëœ|yjÁ        _Â        ‰  Ä                    |¦  «         d‰_Å        n# t          $ r Y dìS w xY w|Rdík    r‰  Æ                    ‰¦  «        ƒ d	{V —†S |Rdîk    r‰  Ç                    ‰¦  «        ƒ d	{V —†S ‰ jh        rdt‰  k                    ¦   «         › dï�S |N�r–t#          ‰ jw        t$          ¦  «        r‰ jw                             d†i ¦  «        pi }Snt          ‰ jw        d†i ¦  «        pi }St#          |St$          ¦  «        si }S|N|Sv �r*‰  Z                    ||N¦  «        }B|B�|BS |S|N         }T|T                     d‡¦  «        dðk    �r
|T                     dñd#¦  «        }z|zrì	 ddòlÈmÉ}{  |{¦   «         }|tû          jÊ        |ztú          jË        jÌ        tú          jË        jÌ        ||¬ó¦  «        ƒ d	{V —†}}tû          jÍ        |} Î                    ¦   «         dô¬õ¦  «        ƒ d	{V —†\  }~}|~p| Ï                    ¦   «          8                    ¦   «         }€|€rddölÐmÑ}�  |�|€¦  «        }€|€r|€nd÷S # tú          jÒ        $ r Y døS t          $ r}%dù|%› �cY d	}%~%S d	}%~%ww xY wdú|N› dû�S |T                     d‡¦  «        dˆk    rÅ|T                     d‰¦  «        pd# 8                    ¦   «         }U|Ur”|U E                    dH¦  «        r|UndH|U› �}U|U H                    dH¦  «        }V‰ x                    ¦   «          8                    ¦   «         }W|U› d'|W› � 8                    ¦   «         ‰_7        |Vr|V y                    ¦   «         d         n|V}Nndú|N› dü�S dú|N› dý�S |Nr½	 ddþlÓmÔ}‚  |‚|N                     dÿ�d ¦  «        ¦  «        }ƒ|ƒr`‰ x                    ¦   «          8                    ¦   «         }W |ƒ|W¦  «        }„tû          jÕ        |„¦  «        r|„ƒ d	{V —†}„|„rt/          |„¦  «        nd	S n3# t          $ r&}%t                               �d|%¦  «         Y d	}%~%nd	}%~%ww xY w|NrÜd}…	 d�dlÖm×}†mØ}‡  |‡|N¦  «        }ˆ|ˆ��‰ x                    ¦   «          8                    ¦   «         }‰|j        r|j        j        nd	}Š |†|ˆ|‰||Š�¬¦  «        }‹|‹rB|‹\  }Œ}�}Ž|Œ‰_7        d}…|Žr1t                               �d|ˆ�d Ù                    |Ž¦  «        ¦  «         n3# t          $ r&}Jt                               �d|J¦  «         Y d	}J~Jnd	}J~Jww xY w|N�r!�tµ          ¦   «                              �dd¦  «        �sü	 d�dlÛmÜ}�mÝ}�mÞ}‘  |�¦   «         Š§ |‘|N¦  «        }’|’��>‰§|’                              �d	d#¦  «        }“|j        r|j        j        nd	}”|”r$|“r"d�d
lßmà}• |“ |•|”�¬¦  «        v r�d|“› �d|”› �d�S ‰ x                    ¦   «          8                    ¦   «         }‰	 d�dlÛmá}–mâ}—  |—|‰¦  «        \  }˜}™n# t          $ r	 d	}–g |‰}™}˜Y nw xY w|˜rH|”rFd�d
lßmà}•  |•|”�¬¦  «        Š¦ˆ¦ˆ§f�d„|˜D ¦   «         }š|šr �d�d Ù                    |š¦  «        › �d|”› �d�S |˜r,|–�* |–|’g|˜¢|™|�¬¦  «        }›|›r|›\  }Œ}�}œ|Œ‰_7        n‡�d|N› �d�S  |�|’|‰|�¬¦  «        }Œ|Œr|Œ‰_7        nf�tÇ          |N¦  «        }�|�r|�S |N                     dÿ�d ¦  «        |Ovr9t                               �d|N|j        r|j        j        n�d¦  «         �d|N› �d�S n3# t          $ r&}%t                               �d|%¦  «         Y d	}%~%nd	}%~%ww xY w|sKtû          j~        ‰ j        |¦  «        ƒ d	{V —†r+‰  ä                    |¦  «        r‰  å                    ¦   «         S d	S ‰ jæ        r"|s t                               �d|¦  «         	 �dS ‰  ç                    ||¦  «        \  }ž}Ÿ|Ÿ�t                               �d|¦  «         |ŸS ‰  À                    |¦  «        } |ž�|ž| jM        _è        tª          | jM        _O        t¡          jP        ¦   «         | jM        _N        ‰  é                    ¦   «          ‰  ê                    |¦  «        }¡	 	 ‰  ë                    ‰|||¡¦  «        ƒ d	{V —†}¢n®# �tØ          $ r }Jt           !                    �d||Jjí        ¦  «         	 Y d	}J~J‰  î                    ‰|¦  «         ‰  ï                    |¦  «         ‰  ð                    ‰¦  «        ƒ d	{V —† ‰  W                    |¦  «         ‰  ñ                    ||¡¦  «         �dS d	}J~Jww xY w	 d#}£t#          |¢t$          ¦  «        r&t/          |¢                     �d ¦  «        pd#¦  «        }£nt#          |¢t.          ¦  «        r|¢}£|£ 8                    ¦   «         rU	 ‰ jò         ó                    |¦  «        ƒ d	{V —†}¤n# t          $ r d	}¤Y nw xY w|¤�‰  ô                    |¤||£�¬!¦  «        ƒ d	{V —† n3# t          $ r&}¥t                               �d"|¥¦  «         Y d	}¥~¥nd	}¥~¥ww xY w|¢‰  î                    ‰|¦  «         ‰  ï                    |¦  «         ‰  ð                    ‰¦  «        ƒ d	{V —† ‰  W                    |¦  «         ‰  ñ                    ||¡¦  «         S # ‰  î                    ‰|¦  «         ‰  ï                    |¦  «         ‰  ð                    ‰¦  «        ƒ d	{V —† ‰  W                    |¦  «         ‰  ñ                    ||¡¦  «         w xY w(#  a‘  
        Handle an incoming message from any platform.
        
        This is the core message processing pipeline:
        1. Check user authorization
        2. Check for commands (/new, /reset, etc.)
        3. Check for running agent and interrupt if needed
        4. Get or create session
        5. Build context for agent
        6. Run agent conversation
        7. Return response
        r   )Úreset_session_varsz*reset_session_vars failed at handler entryTrß   rã	  Fr�   Nrz   r2  z9Dropping Slack message from configured ignored channel %sr6  rÓ
  )Úinvoke_hookÚpre_gateway_dispatchr›  )rÖ  r9   r›  z*pre_gateway_dispatch invocation failed: %sr?
  Úskipz8pre_gateway_dispatch skip: reason=%s platform=%s chat=%sr•  r¼  Úrewriterè   r  Úallowz(Ignoring message with no user_id from %sz Unauthorized user: %s (%s) on %srµ  r  Úpairz1Cannot offer pairing code on %s: no pairing storer®   r  rJ  z-p r™  z;Hi~ I don't recognize you yet!

Here's your pairing code: `z%`

Ask the bot owner to run:
`hermes zpairing approve r  z<Too many pairing requests right now~ Please try again later!)Úpaused_reply©Úresolve_command©Úslash_confirmrÐ	  zBGateway turn paused by global emergency stop (platform=%s chat=%s)r­   >   rq   rÖ	  rÓ	  >   rÚ	  rÛ	  rÙ	  ú.update_responseú.update_prompt.jsonz.tmprQ  r‚  rs  z#Failed to write update response: %su/   âœ— Failed to send response to update process: é   õ   â€¦u
   âœ“ Sent `z` to the update process.ziRecognized /%s during pending update prompt for %s; cancelled prompt with default and dispatching commandz=Failed to write cancel response for pending update prompt: %srE  )Úinclude_choice_promptszfGateway retained pending clarify after voice transcription produced no usable text (session=%s, id=%s)r]  z=Gateway intercepted clarify text response (session=%s, id=%s)z.Failed to resume typing after clarify responsez!/>   rÔ	  rq   rÖ	  r×	  Úonce>   rÞ	  ÚrememberrÞ	  >   rÚ	  rÛ	  r  Ú	nevermindr  >   úapprove oncer   rÖ	  >   rÞ	  rß	  >   rÚ	  r  r¢  Ú
confirm_idr  r  rK	  r>  r?  z | last_activity=r@  rê	  ú.0fzs ago) | iteration=rç	  r  rG  i   zWEvicting stale _running_agents entry for %s (age: %.0fs, idle: %.0fs, timeout: %.0fs)%sÚstale_running_agent_evictionr  r5  rÙ   uF   PRIORITY photo follow-up for session %s â€” queueing without interruptÚ&HERMES_TELEGRAM_FOLLOWUP_GRACE_SECONDSz3.0uV   Telegram follow-up arrived %.2fs after run start for %s â€” queueing without interruptr™  r¾	  r¨  u7   HARD STOP (pending) for session %s â€” sentinel cleareduE   âš¡ Force-stopped. The agent was still starting â€” session unlocked.rÌ	  rÍ	  rÎ	  rÏ	  z'PRIORITY queue follow-up for session %sr	  z(PRIORITY steer failed for session %s: %szPRIORITY steer for session %sz/PRIORITY steer-fallback-to-queue for session %szjPRIORITY interrupt demoted to queue for session %s because the running agent has active subagents (#30170)zdPRIORITY interrupt demoted to queue for session %s because context compression is in flight (#56391)rä	  rå	  z PRIORITY redirect for session %sz+PRIORITY redirect failed for session %s: %sz!PRIORITY interrupt for session %srì  zVoice-priority-interruptrÄ	  )ÚGATEWAY_KNOWN_COMMANDSÚis_gateway_known_commandr˜  Úquick_commandsrÎ   Úaliasr  )r�   r¹  r   Úraw_commandr¸  ra	  zcommand:z/command:%s hook dispatch failed (non-fatal): %sÚdecisionrÛ	  r$  z
Command `/z` was blocked by a hook.Úhandledr_  ra	  r6  r   c               “   ó>   •K  — ‰                      ‰ ¦  «        ƒ d {V —†S r^   )rx  ©rÖ  r  s   €€r>   Ú	_do_resetz0GatewayRunner._handle_message.<locals>._do_resetd<  s-   øè è € Ø!×7Ò7¸Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>rM   z/newzJThis starts a fresh session and discards the current conversation history.)rÖ  r   rÏ  ÚdetailÚexecuteÚtopicr>  r§  z,Ignoring /start platform ping for session %sr?  Úwhoamir1  rk  r7  r	  rŸ  ÚmemoryÚskillsÚlearn)Úbuild_learn_promptu+   Learning a skill from what you describedâ€¦u*   Learning a skill from this conversationâ€¦r.  zlearn ack send failedu,   Could not start /learn â€” please try again.Úinit)Úbuild_init_prompt_for_cwd)rÁ  u+   Could not start /init â€” please try again.zUPDATE the existing AGENTS.mdu)   Updating AGENTS.md from a project scanâ€¦u+   Generating AGENTS.md from a project scanâ€¦zinit ack send failedrw	  r'  r=  r<  re  r  r*  Úpersonalityr9  ÚsuggestionsÚ	blueprintÚ
agent_seedzblueprint ack send failedÚretryÚundoc               “   ó>   •K  — ‰                      ‰ ¦  «        ƒ d {V —†S r^   )Ú_handle_undo_commandr°  s   €€r>   Ú_do_undoz/GatewayRunner._handle_message.<locals>._do_undo=  s-   øè è € Ø!×6Ò6°uÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=rM   r(   z;This removes the last user/assistant exchange from history.zThis removes the last z user turns from history.z/undoÚsethomeÚcompressÚusageÚtopupÚinsightsz
reload-mcpzreload-skillsÚbundlesrÖ	  rI  r@  r4   rÏ  rb  r“  ÚbranchÚrollbackÚdiffr8  rz  zJUsage: /steer <prompt>  (no agent is running; sending as a normal message)r2  r;  Úrefiner+  )Ú	moa_usageÚnormalize_moa_configrc  Údefault_presetzmoa://localzmoa-virtual-providerÚchat_completions)r  r  r  rÅ  r·  zFailed to prepare MoA turn.r:  r  z) and is not accepting new work right now.Úexecr   r�
  r†
  r  r  rê   zCommand returned no output.zQuick command timed out (30s).zQuick command error: zQuick command '/z' has no command defined.z' has no target defined.z4' has unsupported type (supported: 'exec', 'alias').)Úget_plugin_command_handlerrK  rW  z"Plugin command dispatch failed: %s)Úbuild_bundle_invocation_messageÚresolve_bundle_command_key)r'  r�   z$Bundle %s skipped missing skills: %sr  zBundle dispatch failed: %sÚ_bundle_handled)Úget_skill_commandsÚbuild_skill_invocation_messageÚresolve_skill_command_keyrÖ   )Úget_disabled_skill_namesr…   rd  z** skill is disabled for z(.
Enable it with: `hermes skills config`)Ú&build_stacked_skill_invocation_messageÚsplit_stacked_skill_commandsc                 ó¼   •— g | ]X}‰                      |i ¦  «                              d d¦  «        ‰v ¯.‰                      |i ¦  «                              d d¦  «        ‘ŒYS )rÖ   r®   rr  )rb   rè  Ú_plat_disabledÚ
skill_cmdss     €€r>   r  z1GatewayRunner._handle_message.<locals>.<listcomp>_>  sj   ø€ ð +ð +ð +à !Ø)Ÿ~š~¨a°Ñ4Ô4×8Ò8¸ÀÑDÔDÈÐVÐVð 'ŸNšN¨1¨bÑ1Ô1×5Ò5°f¸bÑAÔAàVÐVÐVrM   z8** skill(s) in this stacked invocation are disabled for z*.
Enable them with: `hermes skills config`©r'  z#Failed to load stacked skills for /r
  uO   Unrecognized slash command /%s from %s â€” replying with unknown-command noticer¿  zUnknown command `/zl`. Type /commands to see what's available, or resend without the leading slash to send as a regular message.z*Skill command check failed (non-fatal): %su;   Refusing new turn for session %s â€” external drain active.u‘   â�³ This agent is draining for a maintenance action and isn't accepting new turns right now. It'll be back in a moment â€” please resend shortly.z@Rejecting new active session %s: max_concurrent_sessions reachedz‚Rejecting turn for routing key %s on session %s after turn-lease timeout; transcript load was not started and the user must resendu¡   â�³ Another turn is still running on this session. To protect the transcript, this message was not processed. Wait for the active turn to finish, then resend it.rò  )r\  r(  rò  z!goal continuation hook failed: %s)õr(  Úgateway.session_contextr�  r2   r3   r4   rº   rV   rÄ  rÅ  rÐ  rz  rÑ
  r	  rR
  r�  rã   rt   ru   rv   r�   r­   r2  rw   ri  rl  r¹  rí	  r)  r´  Ú_get_unauthorized_dm_behaviorr  Ú_pairing_store_forrP   Ú_is_rate_limitedÚgenerate_coder@  r0  Ú_record_rate_limitÚagent.estopr–  r\  Úget_commandr`  r˜  rA  rA   r0   Úupdate_prompt_pendingrK  r»  rš  Úget_pendingrÃ  rÑ	  rè   rx   rÖ   rl  Úwith_suffixrö  ru  r–   r7   rF  Úget_pending_for_sessionrÆ	  Ú_prepare_clarify_reply_textrH  r!  Ú!resolve_text_response_for_sessionÚresume_typing_for_chatr#  ry   r�   Úclear_if_staler„  rJ  rô	  rµ   rU   ri  rá   r>  rC  rž  Ú"_invalidate_session_run_generationrÌ
  rH  rI  Ú_check_slash_accessr_  rÚ  rs  rÛ  rw  r<  r’   rÆ  rÍ  rÀ	  r%  r	  rq  r*  r	  rÂ	  r	  rì  rÕ  r	  r±	  r¸	  rå	  rÇ	  rð  r$  r¨  r©  rz   rd  re   r¸  Úemit_collectrK  r  r  rK  rV  Ú _maybe_confirm_destructive_slashÚ_handle_topic_commandrT  rU  rV  Ú_handle_whoami_commandrm  rl  rL  Ú_handle_platform_commandrJ  Ú_handle_stop_commandÚ_handle_reasoning_commandÚ_handle_memory_commandÚ_handle_skills_commandÚagent.learn_promptr¹  rî	  Úhermes_cli.init_commandr»  Ú_handle_fast_commandrR  rS  rQ  Ú_handle_approvals_commandÚ_handle_model_commandÚ_handle_codex_runtime_commandÚ_handle_personality_commandrN  Ú_handle_suggestions_commandÚ_handle_blueprint_commandÚ_handle_retry_commandrh  rj  Ú
IndexErrorÚ_handle_set_home_commandÚ_handle_compress_commandÚ_handle_usage_commandÚ_handle_topup_commandÚ_handle_insights_commandÚ_handle_reload_mcp_commandÚ_handle_reload_skills_commandÚ_handle_bundles_commandrð	  rñ	  rW  rX  Ú_handle_debug_commandÚ_handle_title_commandÚ_handle_resume_commandÚ_handle_sessions_commandÚ_handle_branch_commandÚ_handle_rollback_commandÚ_handle_diff_commandrM  rŠ  rP  Ú_handle_refine_commandÚhermes_cli.moa_configrÏ  rÐ  r˜  rd  r/   rm  rn  Ú_moa_restore_overriderû  Ú_moa_disable_after_turnrO  Ú_handle_voice_commandr•
  r‚
  Úcreate_subprocess_shellr  r  r  r  r  ró   rë   r,  r“  rÔ  r	  Úagent.skill_bundlesrÕ  rÖ  rf   ÚlocalsÚagent.skill_commandsrØ  rÙ  rÚ  rg  rÛ  rÜ  rÝ  rq  rR  rT  r+  rª	  Úleaser=	  Ú_begin_session_run_generationÚ_handle_message_with_agentrh  rN   Ú_restore_moa_one_shotÚ(_restore_pending_one_turn_model_overrideÚ_clear_durable_active_turnÚ_release_turn_leaser8
  rù  Ú_post_turn_goal_continuation)¨r  rÖ  r(  r�  Úis_internalÚ_invoke_hookÚ_hook_resultsÚ	_hook_excÚ_resultÚ_actionÚ	_new_textr_  rµ  Úcoder1  Ústore_profileÚprofile_argÚ_estop_paused_replyÚ_paused_noticeÚ_estop_allowÚ
_estop_cmdÚ_resolve_estop_cmdÚ
_estop_keyÚ_estop_stateÚ_estop_confirm_modÚ_estop_has_approvalÚ
_quick_keyÚ	_up_staterx  rù   r  Ú_recognized_cmdÚ_resolve_update_cmdÚ_cmd_defÚresponse_pathÚprompt_pathÚtmpr¨  ÚlabelrU  Ú_pending_clarifyÚ_clarify_has_audioÚ_raw_clarify_replyÚ	_resolvedÚ_clarify_adapterÚ_slash_confirm_modÚ_pending_confirmÚ_tool_approval_liverÑ	  Ú
_raw_replyÚ_norm_replyÚ
_cmd_replyÚ_confirm_choiceÚ_raw_stale_timeoutÚ_quick_stateÚ	_stale_tsÚ
_stale_ageÚ_stale_agentÚ_stale_idleÚ_stale_detailÚ_saÚ	_wall_ttlÚ_should_evictÚ_resolve_cmd_innerÚ_evt_cmdÚ_cmd_def_innerÚ_deniedÚ_telegram_followup_graceÚ_grace_stateÚ_started_atÚ	_ra_stater«	  r
  r
  r<   r
  r
  rK  r   r¨  r©  Ú_resolve_cmdÚ	canonicalrª  Úqcmdr  Útarget_commandÚ	user_argsra	  Úhook_ctxÚhook_resultsÚ	_hook_errÚhook_resultr­  r$  rv  Únew_argsr±  rl  r¹  Ú
_learn_reqÚ_ackÚ	_ack_metar»  Ú_init_notesÚ_init_promptÚ_blueprint_resultÚ_blueprint_seedrÄ  Ú_undo_nÚ	_undo_rawÚ_undo_detailÚqueue_payloadÚsteer_payloadrÏ  rÐ  rd  Úmoa_payloadrœ  Úmoa_cfgÚpresetÚ
_moa_stateÚexec_cmdr‚
  Úsanitized_envr!  r  r  rÀ  rë   rÔ  Úplugin_handlerr·  r×  rÕ  rÖ  Ú
bundle_keyÚuser_instructionÚ_bundle_platÚbundle_resultr§  Ú_loadedÚmissingrØ  rÙ  rÚ  Úcmd_keyÚ_skill_namer#  Ú_get_plat_disabledÚ_build_stackedrÝ  Ú
extra_keysÚstacked_instructionÚ_disabled_extraÚstacked_resultÚ_missingÚ_unavail_msgÚ_active_session_leaseÚ_limit_messageÚ_claim_stateÚ_run_generationÚ_agent_resultÚ_final_textr\  Ú	_goal_excrß  rà  s¨   ``                                                                                                                                                                    @@r>   rü  zGatewayRunner._handle_message:9  sØ?  øøøøè è € ð ”ˆð	VØBÐBÐBÐBÐBÐBØÐÑ Ô Ð Ð øÝð 	Vð 	Vð 	VÝ�LŠLÐEÐPTˆLÑUÔUÐUÐUÐUð	Vøøøõ
 �7 5¨*°eÑ<Ô<Ñ=Ô=ˆð ð	å˜ 
¨DÑ1Ô1µX´^ÒCÐCÝ)Ý˜˜h¨Ñ-Ô-­w°v¸yÈ$Ñ/OÔ/Oñô ð Dõ
 �KŠKØKÝ˜ 	¨4Ñ0Ô0ñô ð ð �4õ �DÐ8¸%Ñ@Ô@ð	àð	õ ˜EÐ#CÀUÑKÔKð	ð
 ×-Ò-¨eÑ4Ô4Ð4Ø�4ð ð 	4Ø×1Ò1Ñ3Ô3Ð3ð ñ #	ð#ØLÐLÐLÐLÐLÐLØ , Ø*ØØ õ #*¨$°ÀÑ"FÔ"Fð!ñ !ô !��øõ ð #ð #ð #Ý—’ÐKÈYÑWÔWÐWØ "������øøøøð#øøøð )ð ð �Ý! '­4Ñ0Ô0ð ØØ!Ÿ+š+ hÑ/Ô/�Ø˜fÒ$Ð$Ý—K’KØRØŸš HÑ-Ô-Ø17´ÐO˜œÔ-Ð-ÀiØœÐ3¨)ñ	ô ð ð  ˜4˜4Ø˜iÒ'Ð'Ø '§¢¨FÑ 3Ô 3�IÝ! )­SÑ1Ô1ð .Ý +Ô 3°EÀ	Ð JÑ JÔ J˜Ø!&¤˜Ø�EØ˜gÒ%Ð%Ø�Eð &ð ð D	ÙØŒ^Ð#ð ×+Ò+¨FÑ3Ô3ð Ý—’ÐGÈÌÔI^Ñ_Ô_Ð_Ø�tñð ×)Ò)¨&Ñ1Ô1ñ 8	Ý�NŠNÐ=¸v¼~ÈvÔO_ÐagÔapÔavÑwÔwÐwð Ô  DÒ(Ñ(Ø×6Ò6Ø”OØ"œNð 7ñ ô ð ò	ñ ð :@¼Ð W ¤Ô 5Ð 5Èi�Ø $× 7Ò 7¸Ñ ?Ô ?�Ø Ð(Ý—L’LØKØ%ñô ð ð  ˜4ð !×1Ò1°-ÀÄÑPÔPð  Ø˜4Ø$×2Ò2Ø! 6¤>°6Ô3CÐ3IÀrñô �ð ð TØ"×6Ò6°vÑ>Ô>�GØð Ý(/°¸yÈ$Ñ(OÔ(O˜õ  *¨-½Ñ=Ô=ð$à -ð$ð !.°Ò :Ð :ð 3 -Ð2Ð2Ð2Ð2ð "$ð $ð &ŸlšlØ"œNð7Ø:>ð7ð 7ð (3ð7ð 7ð  -ð	7ð 7ð 04ð	7ð 7ð 7ñô ð ð ð ð ð ð ð øð #×6Ò6°vÑ>Ô>�GØð Ø%ŸlšlØ"œNð6ñô ð ð ð ð ð ð ð ð "×4Ò4°]ÀFÄNÑSÔSÐSØ�4ð$ ñ 5	*ð&ØKÐKÐKÐKÐKÐKØ!4Ð!4Ñ!6Ô!6��øÝð &ð &ð &Ø!%���ð&øøøàÑ)Ø$�Ø!�
ð&Ø!&×!2Ò!2Ñ!4Ô!4�J�JøÝ ð &ð &ð &Ø!%�J�J�Jð&øøøàð -ð-ðð ð ð ð ð ð (:Ð'9¸*Ñ'EÔ'EÈTÐ'Q˜˜øÝ$ð -ð -ð -Ø',˜˜˜ð-øøøà#ð ðØ%)×%AÒ%AÀ&Ñ%IÔ%I˜
Ø'+×'?Ò'?À
Ñ'KÔ'K˜à(Ð4Ø ,Ô 7Ô Mð 5ð ,0˜LØ+ð 0°×0HÒ0HÈÑ0TÔ0Tð 0ð ,0˜LØ+ð 4ØQÐQÐQÐQÐQÐQØ1×=Ò=¸jÑIÔIð 4Ø/3 Ø+ð 4ðð ð ð ð ð ð  3Ð2°:Ñ>Ô>ð 4Ø/3 øøÝ$ð ð ð Ø˜ðøøøà#ð *Ý—K’KØ\Ý¥¨°
¸DÑ AÔ AÀ7ÈIÑVÔVÝ ¨	°4Ñ8Ô8ÐE¸Iñô ð ð
 *Ð)ð ×1Ò1°&Ñ9Ô9ˆ
Ø×,Ò,¨ZÑ8Ô8ˆ	ØÑ  YÔ%9Ô%OÑ Ø”:Ð# ×*Ò*Ñ,Ô,ˆCà×#Ò#Ñ%Ô%ˆCØÐ(Ð(Ð(Ø #��Ø˜Ð&Ð&Ø #��à"&�Øð 
3ð3Ø^Ð^Ð^Ð^Ð^Ð^Ð^øÝ$ð 3ð 3ð 3Ø.2Ð+Ð+Ð+ð3øøøà*Ð6ð3Ø':Ð':¸3Ñ'?Ô'?˜HØ?GÐ.Q¨h¬m¨mÈT˜O˜OøÝ(ð 3ð 3ð 3Ø.2˜O˜O˜Oð3øøøà"ð (Ø$&�M�Mà$'�MØð DÝ ,Ð/AÑ A�Ý*Ð-BÑB�ðQØ'×3Ò3°FÑ;Ô;�CØ—N’N =¸7�NÑCÔCÐCØ—K’K Ñ.Ô.Ð.Ø×&Ò&°$Ð&Ñ7Ô7Ð7Ð7øÝð Qð Qð QÝ—N’NÐ#HÈ!ÑLÔLÐLØPÈQÐPÐPÐPÐPÐPÐPÐPÐPøøøøðQøøøð >C�	Ô$Ô:Ý),¨]Ñ);Ô);¸rÒ)AÐ)A˜˜À}ÐUXÐVXÐUXÔGYÐ\aÑGa�ØC EÐCÐCÐCÐCð ð CÝ ,Ð/AÑ A�Ý*Ð-BÑB�ðØ'×3Ò3°FÑ;Ô;�CØ—N’N 2°�NÑ8Ô8Ð8Ø—K’K Ñ.Ô.Ð.Ø×&Ò&°$Ð&Ñ7Ô7Ð7Ý—K’KðPà'Ø"ñ	ô ð ð øõ ð ð ð Ý—N’NØWØñô ð ð ð ð ð ð øøøøðøøøð
 >C�	Ô$Ô:ð ˆð	$Ø=Ð=Ð=Ð=Ð=Ð=Ø+×CÒCØ°4ð  Dñ  ô  ÐÐøõ ð 	$ð 	$ð 	$Ø#ÐÐÐð	$øøøàÑ'¨LÑ,DÝ!% d×&EÒ&EÀeÑ&LÔ&LÑ!MÔ!MÐØ'+×'GÒ'GÈÑ'NÔ'NÐ!NÐ!NÐ!NÐ!NÐ!NÐ!NÐØ!ð Ð*<ð Ý—’ðBàØ$Ô/ñ	ô ð ð �rð
 "ð Ð*<×*GÒ*GÈÑ*LÔ*Lð Ø(×JÒJØÐ 2ñô �	ð ð Ý—K’KØWØ"Ð$4Ô$?ñô ð ð (,×'?Ò'?ÀÑ'GÔ'GÐ$Ø'ð ðØ,×CÒCÀFÄNÑSÔSÐSÐSøÝ(ð ð ð Ý"ŸLšLØ PØ)-ð )ñ ô ð ð ð ðøøøð ˜2ð 	>Ð=Ð=Ð=Ð=Ð=Ø-×9Ò9¸*ÑEÔEÐØ#Ðð	(Ø<Ð<Ð<Ð<Ð<Ð<Ø"7Ð"7¸
Ñ"CÔ"CÐÐøÝð 	(ð 	(ð 	(Ø"'ÐÐÐð	(øøøàð 	:Ð$7ð 	:Øœ*Ð*¨×1Ò1Ñ3Ô3ˆJð %×+Ò+¨DÑ1Ô1×7Ò7Ñ9Ô9ˆKØ×*Ò*Ñ,Ô,ˆJØ"ˆOØÐ@Ð@Ð@Ø"(��ØÐ5Ð5Ð5Ø"*��ØÐDÐDÐDØ"*��ØÐ CÐCÐCØ"(��ØÐ <Ð<Ð<Ø"*��ØÐ =Ð=Ð=Ø"*�ØÐ*Ø"4×"<Ò"<ØÐ 0× 4Ò 4°\Ñ BÔ BÀOñ#ô #ð ð ð ð ð ð �	ð !� BÐ&ð ×-Ò-¨jÑ9Ô9Ð9õ (Ð(>ÀÑEÔEÐØ×/Ò/°
Ñ;Ô;ˆØ4@ÐG�LÔ%Ô0Ð0Àaˆ	ØÑ#¨Ô(9Ô(?Ñ(KÐPYÑ(KÝœ™œ yÑ0ˆJØ'Ô,Ô2ˆLõ   ™,œ,ˆKØˆMØð 
¥¨Ð6LÑ MÔ Mð 
ð	Ø&×;Ò;Ñ=Ô=�CØ"%§'¢'Ð*BÅEÈ%ÁLÄLÑ"QÔ"Q�Kðe¨C¯GªGÐ4HÈ)Ñ,TÔ,Tð eð eØ'Ð4ðeð eà'*§w¢wÐ/?ÀÑ'CÔ'Cðeð eàFIÇgÂgÐN^Ð`aÑFbÔFbðeð eð "�Møõ
 !ð ð ð Ø�Dðøøøð
 ?QÐSTÒ>TÐ>T�Ð.°Ñ3°TÑ:Ô:Ð:ÕZ_Ð`eÑZfÔZfˆIàÕ$;Ð;ð à'¨!Ò+ÐQ°Ð?QÒ0Qð .Ø! IÒ-ð	 ð ð >Ý—’ðBà 
¨KØ&¨ñ	ô ð ð ×7Ò7ØØ9ð 8ñ ô ð ð ×1Ò1°*Ñ=Ô=Ð=à×#Ò# JÑ/Ô/ñ H	ð RÐQÐQÐQÐQÐQØ×(Ò(Ñ*Ô*ˆHØ=EÐOÐ/Ð/°Ñ9Ô9Ð9È4ˆNð ð @ .Ô"5¸Ò"AÐ"AØ!×8Ò8¸Ñ?Ô?Ð?Ð?Ð?Ð?Ð?Ð?Ð?Øð A .Ô"5¸Ò"BÐ"BØ!×9Ò9¸%Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@Ð@ð ð #˜NÐ6Ø×2Ò2°6¸>Ô;NÑOÔO�ØÐ&Ø"�Nð ð Ø!×>Ò>Ø˜>¨:°vñô ð ð ð ð ð ð ð ð Ô!¥[Ô%6Ò6Ð6Ý—’ÐeÐgqÑrÔrÐrØ×2Ò2°6Ñ:Ô:�Øð ^Ý/°Ô0IÈ:ÐW\Ñ]Ô]Ð]Ø�tå',Ý”	ÐBÀEÑJÔJñ(ô (Ð$ð  ×3Ò3°JÑ?Ô?ˆLØ:FÐM˜,Ô+Ô6Ð6ÈAˆKà”¥8Ô#4Ò4Ð4ØÔ&­+Ô*:Ò:Ð:Ø,¨qÒ0Ð0Øð 1å”Y‘[”[ ;Ñ.Ð3KÒKÐKå—’ØlÝ”I‘K”K +Ñ-Øñô ð ð
 ×2Ò2°6Ñ:Ô:�Øð 	ØÔ,°Ò7Ð7Ø×*Ò*¨:°u¸gÑFÔFÐFÐFå3Ø#Ô5Ø&Ø!Ø'+ð	ñ ô ð ð �tà×0Ò0°Ñ<Ô<ˆIØ4=ÐG˜IœNÔ0Ð0À4ˆMØÕ 7Ð7Ð7à×$Ò$Ñ&Ô&¨&Ò0Ð0à×5Ò5°jÑAÔAÐAÝ—K’KÐ YÐ[eÑfÔfÐfÝ)Ð*qÑrÔrÐrð ×2Ò2°6Ñ:Ô:�Øð Ý/ØÔ1Ø"ØØ#'ð	ñ ô ð ð �tØŒ~ð Ø×3Ò3Ñ5Ô5ð LØ×8Ò8¸ÀUÑKÔKÐKð ×7Ò7Ñ9Ô9ðwÐs 4×#=Ò#=Ñ#?Ô#?ÐsÐsÐsÐsàv¨4×+EÒ+EÑ+GÔ+GÐvÐvÐvðð
 Ô$¨Ò/Ð/Ý—’ÐFÈ
ÑSÔSÐSØ×4Ò4°ZÀÑGÔGÐGØ�tØÔ$¨Ò/Ð/ð $œjÐ.¨B×5Ò5Ñ7Ô7�
Ø�àÔ&­+Ô*:Ò:Ð:Ø!Ô,ð ;à!Ô-ð ;ð #ð ;õ   ¨wÑ7Ô7ð	 ;ð(Ý"& }×':Ò':¸:Ñ'FÔ'FÑ"GÔ"G˜˜øÝ$ð (ð (ð (ÝŸšÐ'QÐS]Ð_bÑcÔcÐcØ"'˜˜˜˜˜˜øøøøð(øøøð ð  Ý—L’LÐ!@À*ÑMÔMÐMØ˜4Ý—’ÐNÐPZÑ[Ô[Ð[Ø×4Ò4°ZÀÑGÔGÐGØ�tð ×/Ò/°Ñ>Ô>ð Ý—’ðNàñô ð ð
 ×4Ò4°ZÀÑGÔGÐGØ�tð ×<Ò<¸ZÑHÔHÐHÐHÐHÐHÐHÐHð Ý—’ðHàñô ð ð
 ×4Ò4°ZÀÑGÔGÐGØ�tð
 Ô"¥kÔ&6Ò6Ð6ØÔ(ð 7àÔ)ð 7õ ˜MÐ+KÈUÑSÔSØðð å˜M¨:Ñ6Ô6ðð	Ø$×-Ò-¨u¬zÐ/?¸R×.FÒ.FÑ.HÔ.HÑIÔIð $ÝŸšÐ%GÈÑTÔTÐTØ#˜tð$øõ !ð ð ð Ý—N’NØEØ"Øñô ð ð ð ð ð ð øøøøðøøøõ �LŠLÐ<¸jÑIÔIÐIØ#œjˆOÝ! %¨°tÑ<Ô<ÐBÀˆKØ×.Ò.¨uÑ5Ô5ð 	BØ+/×+RÒ+RØØ×,Ò,¨VÑ4Ô4ØØ”JÐ$ "Ø :ð ,Sñ ,ô ,ð &ð &ð &ð &ð &ð &Ñ"�  ð %ð B¨ð BÝ":¸5Ñ"AÔ"A�Ø×#Ò# OÑ4Ô4Ð4ð �4ð ×#Ò#Ñ%Ô%ˆð	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð -4Ð=�<�< Ñ(Ô(Ð(¸ˆØ%-Ð:�H”M�M°7ˆ	ð ñ 	K�xÑ'Ý˜$œ+¥tÑ,Ô,ð RØ!%¤§¢Ð1AÀ2Ñ!FÔ!FÐ!LÈ"��å!(¨¬Ð6FÈÑ!KÔ!KÐ!QÈr�Ý˜.­$Ñ/Ô/ð K°G¸~Ð4MÐ4MØ% gÔ.�Ø—8’8˜FÑ#Ô# wÒ.Ð.Ø"Ÿhšh xÑ0Ô0Ð6°B×=Ò=Ñ?Ô?�FØð KØ+1×+<Ò+<¸SÑ+AÔ+AÐ!S  À|È6À|À|˜Ø)/¯ª°sÑ);Ô);˜Ø$)×$:Ò$:Ñ$<Ô$<×$BÒ$BÑ$DÔ$D˜	Ø(.Ð%<Ð%<°Ð%<Ð%<×%BÒ%BÑ%DÔ%D˜œ
Ø?MÐ"a .×"6Ò"6Ñ"8Ô"8¸Ô";Ð";ÐSa˜Ø<CÐ#M < <°Ñ#8Ô#8Ð#8È˜Ø5=Ð$J H¤M MÀ7˜	ð ð 	�yð 	Ð%=Ð%=¸iÑ%HÔ%Hð 	Ø×.Ò.¨v°yÑAÔAˆGØÐ"Ø�ð ñ .	Ð/Ð/°	Ñ:Ô:ñ .	Ø×-Ò-Ñ/Ô/×5Ò5Ñ7Ô7ˆHà5;´_ÐL˜FœOÔ1Ð1È"Ø!œ>Ø$Ø&Ø Ø$ðð ˆHð	"Ø%)¤Z×%<Ò%<Ø*˜yÐ*Ð*¨Hñ&ô &ð  ð  ð  ð  ð  ð  ��øõ ð "ð "ð "Ý—’ØEØ˜yñô ð ð  "������øøøøð"øøøð  ,ð ñ �Ý! +­tÑ4Ô4ð ØÝ˜{Ÿš¨z¸2Ñ>Ô>Ñ?Ô?×EÒEÑGÔG×MÒMÑOÔO�Øð  8¨wÒ#6Ð#6ØØ˜vÒ%Ð%Ø)Ÿošo¨iÑ8Ô8�GÝ! '­3Ñ/Ô/ð '°Gð 'Ø&˜˜˜ØI¨ÐIÐIÐIÐIÐIÐIØ˜yÒ(Ð(Ø)Ÿošo¨iÑ8Ô8�GÝ&0°½#Ñ&>Ô&>ÐTÀ7ÐT˜7˜7ÐPTÐTÐTÐTØ˜yÒ(Ð(Ý"%Ø#Ÿš¨¸Ñ;Ô;ñ#ô #ç’e‘g”gŸfšf S™kœkð  ð 'ð !Ù Ý" ;§?¢?°:¸rÑ#BÔ#BÑCÔC×IÒIÑKÔK�HØ!= [Ð!=Ð!=°8Ð!=Ð!=×!CÒ!CÑ!EÔ!E�E”JØ#×/Ò/Ñ1Ô1�GØ8?ÐI˜|˜|¨GÑ4Ô4Ð4ÀT�HØ19Ð F ¤ ¸w�IØ�Eñ )ð ˜ÒÐØ×3Ò3°EÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:à˜ÒÐÝÔ& tÔ'IÈ6ÑRÔRÐRÐRÐRÐRÐRÐRð ?Ø×<Ò<Ñ>Ô>Ð>ð?ð ?ð ?ð ?ð ?ð ?à×>Ò>ØØØð,ð "ð ?ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð ˜ÒÐØ×3Ò3°EÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:à˜ÒÐØ×2Ò2°5Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9à˜ÒÐÝ�KŠKÐFÈ
ÑSÔSÐSØ�2à˜
Ò"Ð"Ø×6Ò6°uÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=à˜	Ò!Ð!Ø×5Ò5°eÑ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<à˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜Ò Ð Ø?Ð?Ð?Ð?Ð?Ð?à%Ð%Ñ'Ô'Ð'à˜	Ò!Ð!Ø×5Ò5°eÑ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<à˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜
Ò"Ð"Ø×6Ò6°uÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=à˜	Ò!Ð!Ø×5Ò5°eÑ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<à˜ÒÐØ×2Ò2°5Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9à˜Ò#Ð#Ø×7Ò7¸Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>à˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜ÒÐð >Ð=Ð=Ð=Ð=Ð=à×/Ò/Ñ1Ô1×7Ò7Ñ9Ô9ˆJð ðBÐ=Ð=àAð ð
EØ×2Ò2°6Ñ:Ô:�Øð VØ $× @Ò @ÀÑ HÔ H�IØ!Ÿ,š,¥s¨6¬>Ñ':Ô':¸DÈ9˜,ÑUÔUÐUÐUÐUÐUÐUÐUÐUøøÝð Eð Eð EÝ—’Ð4¸t�ÑDÔDÐDÐDÐDðEøøøðFØ/Ð/°
Ñ;Ô;�”
�
øåð Fð Fð FØEÐEÐEðFøøøð ˜ÒÐð JÐIÐIÐIÐIÐIà×0Ò0Ñ2Ô2×8Ò8Ñ:Ô:ˆKðEØ8Ð8¸{ÐKÑKÔK��øÝð Eð Eð EØDÐDÐDðEøøøð 3°lÐBÐBð <Ð;àBð ð
DØ×2Ò2°6Ñ:Ô:�Øð VØ $× @Ò @ÀÑ HÔ H�IØ!Ÿ,š,¥s¨6¬>Ñ':Ô':¸DÈ9˜,ÑUÔUÐUÐUÐUÐUÐUÐUÐUøøÝð Dð Dð DÝ—’Ð3¸d�ÑCÔCÐCÐCÐCðDøøøà%ˆEŒJð ˜ÒÐØ×2Ò2°5Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9à˜	Ò!Ð!Ø×5Ò5°eÑ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<à˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜ÒÐØ×2Ò2°5Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9à˜Ò#Ð#Ø×7Ò7¸Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>à˜ÒÐØ×3Ò3°EÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:à˜Ò'Ð'Ø×;Ò;¸EÑBÔBÐBÐBÐBÐBÐBÐBÐBà˜Ò%Ð%Ø×9Ò9¸%Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@Ð@à˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜Ò%Ð%Ø×9Ò9¸%Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@Ð@à˜Ò#Ñ#Ø&*×&DÒ&DÀUÑ&KÔ&KÐ KÐ KÐ KÐ KÐ KÐ KÐÝ%Ð&7¸ÀtÑLÔLˆOØð Fõ Ð0°&¸"Ñ=Ô=ÐCÀ�Øð QðQØ"&×":Ò":¸6Ñ"BÔ"B˜Ø"ð ^Ø(,×(HÒ(HÈÑ(PÔ(P˜IØ")§,¢,­s°6´>Ñ/BÔ/BÀDÐS\ ,Ñ"]Ô"]Ð]Ð]Ð]Ð]Ð]Ð]Ð]øøÝ$ð Qð Qð QÝŸšÐ%@È4˜ÑPÔPÐPÐPÐPðQøøøðJØ!0�E”J�JøÝ ð Jð Jð JÝ"Ð#4°f¸bÑAÔAÐIÀTÐIÐIÐIðJøøøõ Ð0°&¸"Ñ=Ô=ÐEÀÐEà˜ÒÐØ×3Ò3°EÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:à˜ÒÐð>ð >ð >ð >ð >ð >àˆGØ×.Ò.Ñ0Ô0×6Ò6Ñ8Ô8ˆIØð  ð Ý! !¦S¨¯ªÑ):Ô):¸1Ô)=Ñ%>Ô%>Ñ?Ô?�G�GøÞ"¦JÐ/ð  ð  ð  Ø�G�G�Gð øøøð ˜a’<�<ð NÐMàP¨gÐPÐPÐPð ð
 ×>Ò>ØØØØ#Ø ð ?ñ ô ð ð ð ð ð ð ð ð ˜	Ò!Ð!Ø×6Ò6°uÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=à˜
Ò"Ð"Ø×6Ò6°uÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=à˜ÒÐØ×3Ò3°EÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:à˜ÒÐØ×3Ò3°EÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:à˜
Ò"Ð"Ø×6Ò6°uÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=à˜Ò$Ð$Ø×8Ò8¸Ñ?Ô?Ð?Ð?Ð?Ð?Ð?Ð?Ð?à˜Ò'Ð'Ø×;Ò;¸EÑBÔBÐBÐBÐBÐBÐBÐBÐBà˜	Ò!Ð!Ø×5Ò5°eÑ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<à˜	Ò!Ð!Ø×5Ò5°eÑ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<à˜ÒÐØ×2Ò2°5Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9à˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜	Ò!Ð!Ø×5Ò5°eÑ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<à˜ÒÐØ×3Ò3°EÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:à˜ÒÐØ×3Ò3°EÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:à˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜
Ò"Ð"Ø×6Ò6°uÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=à˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜
Ò"Ð"Ø×6Ò6°uÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=à˜ÒÐØ×2Ò2°5Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9à˜Ò$Ð$Ø×8Ò8¸Ñ?Ô?Ð?Ð?Ð?Ð?Ð?Ð?Ð?à˜ÒÐØ!×2Ò2Ñ4Ô4×:Ò:Ñ<Ô<ˆMØ ð 0Ø/Ð/ðØ*�”
�
øÝð ð ð Ø�ðøøøð ˜ÒÐð "×2Ò2Ñ4Ô4×:Ò:Ñ<Ô<ˆMØ ð dØcÐcðØ*�”
�
øÝð ð ð Ø�ðøøøð ˜ÒÐØ×2Ò2°5Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9à˜Ò#Ð#Ø×7Ò7¸Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ø˜Ò Ð Ø×4Ò4°UÑ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;à˜ÒÑð
ð ð ð ð ð ð ð ð 6Ð5Ð5Ð5Ð5Ð5à×0Ò0Ñ2Ô2×8Ò8Ñ:Ô:ˆKØð #Ø �y‘{”{Ð"ð3Ø!�k‘m”m�Ø.Ð.ÅÈCÕQUÑAVÔAVÐ/^¨s¯wªw°u©~¬~¨~Ð\^Ñ_Ô_��øÝð 3ð 3ð 3Ø.Ð.¨rÑ2Ô2���ð3øøøàÐ-Ô.ˆFð5Ø(�”
Ø!×0Ò0°Ñ<Ô<�
Ø.8Ô.EÔ.T�Ô+à %Ø#Ø -Ø5Ø 2ð:ð :�
Ô'Ô6ð ×(Ò(¨Ñ4Ô4Ð4Ø04�Ô-Ð-øÝð 5ð 5ð 5Ø4Ð4Ð4ð5øøøð ˜	Ò!Ð!Ø×5Ò5°eÑ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<à˜ÒÐØ×3Ò3°EÑ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:àŒ>ð 	mØl T×%?Ò%?Ñ%AÔ%AÐlÐlÐlÐlð ñ ;	lÝ˜$œ+¥tÑ,Ô,ð RØ!%¤§¢Ð1AÀ2Ñ!FÔ!FÐ!LÈ"��å!(¨¬Ð6FÈÑ!KÔ!KÐ!QÈr�Ý˜n­dÑ3Ô3ð $Ø!#�Ø˜.Ð(Ñ(ð ×2Ò2°6¸7ÑCÔC�ØÐ&Ø"�NØ% gÔ.�Ø—8’8˜FÑ#Ô# vÒ-Ñ-Ø#Ÿxšx¨	°2Ñ6Ô6�HØð Uð?ð VÐUÐUÐUÐUÐUØ,@Ð,@Ñ,BÔ,B˜MÝ)0Ô)HØ (Ý'.Ô'9Ô'>Ý'.Ô'9Ô'>Ø$1ð	*ñ *ô *ð $ð $ð $ð $ð $ð $˜Dõ 4;Ô3CÀD×DTÒDTÑDVÔDVÐ`bÐ3cÑ3cÔ3cÐ-cÐ-cÐ-cÐ-cÐ-cÐ-c™N˜F FØ&,Ð&6°×%>Ò%>Ñ%@Ô%@×%FÒ%FÑ%HÔ%H˜Fà%ð GØ NÐ NÐ NÐ NÐ NÐ NØ)>Ð)>¸vÑ)FÔ)F Ø-3Ð#V 6 6Ð9VÐVøÝ&Ô3ð Dð Dð DØ#CÐ#CÐ#CÝ(ð ?ð ?ð ?Ø#>¸1Ð#>Ð#>Ð>Ð>Ð>Ð>Ð>Ð>øøøøð?øøøð  U°'ÐTÐTÐTÐTØ—X’X˜fÑ%Ô%¨Ò0Ð0Ø"Ÿhšh xÑ0Ô0Ð6°B×=Ò=Ñ?Ô?�FØð TØ+1×+<Ò+<¸SÑ+AÔ+AÐ!S  À|È6À|À|˜Ø)/¯ª°sÑ);Ô);˜Ø$)×$:Ò$:Ñ$<Ô$<×$BÒ$BÑ$DÔ$D˜	Ø(.Ð%<Ð%<°Ð%<Ð%<×%BÒ%BÑ%DÔ%D˜œ
Ø?MÐ"a .×"6Ò"6Ñ"8Ô"8¸Ô";Ð";ÐSa˜˜ð  T°'ÐSÐSÐSÐSàk¨gÐkÐkÐkÐkð ð 	HðHØIÐIÐIÐIÐIÐIð "<Ð!;¸G¿OºOÈCÑQTÑ<UÔ<UÑ!VÔ!V�Ø!ð ;Ø %× 6Ò 6Ñ 8Ô 8× >Ò >Ñ @Ô @�IØ+˜^¨IÑ6Ô6�FÝÔ*¨6Ñ2Ô2ð .Ø'-      ˜Ø*0Ð:�3˜v™;œ;˜;°dÐ:ð;øõ ð Hð Hð HÝ—’ÑCÀQÑGÔGÐGÐGÐGÐGÐGÐGøøøøðHøøøð ð !	Bð $ˆOðBðñ ð ð ð ð ð ð ð 8Ð7¸Ñ@Ô@�
ØÐ)Ø',×'=Ò'=Ñ'?Ô'?×'EÒ'EÑ'GÔ'GÐ$ð =C¼OÐ#U 6¤?Ô#8Ð#8ÐQU�LØ$CÐ$CØ"Ð$4¸jØ!-ñ%ñ %ô %�Mð %ð Ø0=Ñ-˜˜W gØ%(˜œ
Ø*.˜Ø"ð Ý"ŸKšKÙ FØ *©D¯IªI°gÑ,>Ô,>ñô ð øøõ
 ð Bð Bð BÝ—’Ñ;¸SÑAÔAÐAÐAÐAÐAÐAÐAøøøøðBøøøð ñ j	Nž6™8œ8Ÿ<š<Ñ(9¸5ÑAÔAñ j	NðiNðñ ð ð ð ð ð ð ð ð ð
 0Ð/Ñ1Ô1�
Ø3Ð3°GÑ<Ô<�ØÑ&ð
 #-¨WÔ"5×"9Ò"9¹&À"Ñ"EÔ"E�KØ5;´_ÐN˜FœOÔ1Ð1È$�EØð  ð ØdÑdÐdÐdÐdÐdØ&Ð*<Ð*<ÀeÑ*LÑ*LÔ*LÐLÐLñ!J¨ð !Jñ !JÈuð !Jñ !Jð !Jðð (-×'=Ò'=Ñ'?Ô'?×'EÒ'EÑ'GÔ'GÐ$ð
Oðñ ð ð ð ð ð ð ð
 9Ð8Ð9IÑJÔJñ 8˜
Ð$7Ð$7øõ %ð Oð Oð OØ)-˜Ø:<Ð>NÐ$7˜
˜
˜
ðOøøøð "ð  eð ð eÑdÐdÐdÐdÐdØ);Ð);ÀUÑ)KÑ)KÔ)K˜ð+ð +ð +ñ +ð +à%/ð+ñ +ô +˜ð
 +ð ñ!L©¯ª°?Ñ)CÔ)Cð !Lñ !LØGLð!Lñ !Lð !Lðð
 "ð - nÐ&@Ø)7¨Ø$Ð2 zÐ2Ø/Ø$.ñ*ñ *ô *˜ð
 *ð TØ5CÑ2˜C ¨(Ø),˜EœJ˜Jñ $TÈÐ#SÑ#SÐ#SÐSà<Ð<Ø#Ð%5¸zññ ô ˜ð ð -Ø),˜EœJøö
 $<¸GÑ#DÔ#D�LØ#ð ,Ø+Ð+ð —’ s©CÑ0Ô0Ð8NÐNÐNÝŸšñCà#Ø5;´_ÐM˜FœOÔ1Ð1É#ñ	ô ð ñ5°ð 5ñ 5ð 5ðøøõ ð Nð Nð NÝ—’ÑIÈ1ÑMÔMÐMÐMÐMÐMÐMÐMøøøøðNøøøð ð 	¥WÔ%6ØÔ.°ñ&
ô &
ð  
ð  
ð  
ð  
ð  
ð  
ð 	ð
 ×8Ò8¸Ñ@Ô@ð AØ×>Ò>Ñ@Ô@Ð@Ø�4ð Ô&ð 		¨{ð 		Ý�KŠKÙMØñô ð ð
)ñð ð 15×0OÒ0OØØñ1
ô 1
Ñ-Ð˜~ð Ð%Ý�KŠKÙRØñô ð ð "Ð!Ø×*Ò*¨:Ñ6Ô6ˆØ Ð,Ø&;ˆLÔÔ#Ý"9ˆÔÔÝ'+¤y¡{¤{ˆÔÔ$Ø×#Ò#Ñ%Ô%Ð%Ø×<Ò<¸ZÑHÔHˆðL	BðØ&*×&EÒ&EØ˜6 :¨ñ'ô 'ð !ð !ð !ð !ð !ð !��øö )ð ð ð õ —’ñ+ð Ø”Nñô ð ðJðð ð ð ðV ×&Ò& u¨jÑ9Ô9Ð9Ø×9Ò9¸*ÑEÔEÐEð ×1Ò1°%Ñ8Ô8Ð8Ð8Ð8Ð8Ð8Ð8Ð8ð ×-Ò-¨jÑ9Ô9Ð9ð ×$Ò$ Z°ÑAÔAÐAÑAÐAøøøøðOøøøð,MØ �Ý˜m­TÑ2Ô2ð 0Ý"% m×&7Ò&7Ñ8HÑ&IÔ&IÐ&OÈRÑ"PÔ"P�K�KÝ ­sÑ3Ô3ð 0Ø"/�Kð ×$Ò$Ñ&Ô&ð 
ð-Ø.2Ô.F×.\Ò.\Ð]cÑ.dÔ.dÐ(dÐ(dÐ(dÐ(dÐ(dÐ(d˜˜øÝ$ð -ð -ð -Ø(,˜˜˜ð-øøøà$Ð0Ø"×?Ò?Ø*7Ø#)Ø+6ñ @ñ ô ð ð ð ð ð ð ð øøõ
 ð Mð Mð MÝ—’Ñ@À)ÑLÔLÐLÐLÐLÐLÐLÐLøøøøðMøøøà ð ×&Ò& u¨jÑ9Ô9Ð9Ø×9Ò9¸*ÑEÔEÐEð ×1Ò1°%Ñ8Ô8Ð8Ð8Ð8Ð8Ð8Ð8Ð8ð ×-Ò-¨jÑ9Ô9Ð9ð ×$Ò$ Z°ÑAÔAÐAÐAøð# ×&Ò& u¨jÑ9Ô9Ð9Ø×9Ò9¸*ÑEÔEÐEð ×1Ò1°%Ñ8Ô8Ð8Ð8Ð8Ð8Ð8Ð8Ð8ð ×-Ò-¨jÑ9Ô9Ð9ð ×$Ò$ Z°ÑAÔAÐAÐAøøøs  �   &A	ÁA	Ä:$E Å
FÅ)FÆFÒR  Ò R/Ò.R/Ò:S ÓSÓSÓ$S8 Ó8TÔTÔBV Ö
V"Ö!V"Ù0Y7 Ù7ZÚZÚZ# Ú#Z2Ú1Z2ÛA\+ Ü+
]Ü5]Ý]Ý]Þ-A3`! à!
aà+aáaá"b  â bâbå$e? å?&f(æ'f(çg çg,ç+g,íBo ï
oïoÁA?"AB" ÁB"
ACÁB,ACÁCACÁHA	AI ÁI
AJÁIAI=ÁI=AJÁU$AU< ÁU<
AV.ÁVAV)ÁV)AV.Áh+AAj Áj&Aj1Áj0Aj1Áj5Ak Ák
AkÁkAkÁl
Al Ál
Al%Ál$Al%Ál1AAn Án&An7Án6An7ÁuAAv3 Áv3&AwÁwAwÁw Aw( Áw(AxÁxAxÁy66Az- Áz-A{Á{A{ÂF;BG ÂG
BGÂGBGÂHBH ÂH
BHÂHBHÂK?BL ÂLBLÂLBLÂL+ABN ÂN
BNÂNBNÂR=B=BU; ÂU;BV%ÂV	BV%ÂVBV ÂVBV%ÂV BV%ÂZBB\ Â\
B]Â\(B]	Â]	B]Â]B%B_< Â_<
B`,Â`B`'Â`'B`,ÂaA:Bh  Âc&Bh  Âc:Bd ÂdBh  ÂdBd%Âd"Bh  Âd$Bd%Âd%ABh  Âe2-Bh  Âf ,Bh  ÂgABh  Âh 
BiÂh*BiÂiBiÂm>Bn ÂnBv0 ÂnBqÂn(#BqÂoBv0 ÂqBqÂqBv0 ÂqA(Bt
 Âr5 Bs ÂsBt
 ÂsBs%Âs"Bt
 Âs$Bs%Âs%$Bt
 Ât	Bv0 Ât

Bt:ÂtBt5Ât0Bv0 Ât5Bt:Ât:Bv0 Âv0A3Bx#c                 óÚ   — t          |dd¦  «        sdS 	 t          |dd¦  «        }||                      |¦  «        j        _        |                      |¦  «         dS # t
          $ r Y dS w xY w)aÇ  Revert a ``/moa <prompt>`` one-shot model override after its turn.

        Called from the ``finally`` of the message-handling path so the revert
        fires whether the turn succeeded, raised, or was interrupted. A no-op
        unless ``event._moa_disable_after_turn`` is set. ``_moa_restore_override``
        carries the prior per-session override (``None`` means the user had no
        override, so the MoA override is cleared outright).
        r  FNr  )rV   r/   rm  rn  rû  r2   )r  rÖ  r-  Ú_restores       r>   r#  z#GatewayRunner._restore_moa_one_shot$?  sŠ   € õ �uÐ7¸Ñ?Ô?ð 	ØˆFð	Ý˜uÐ&=¸tÑDÔDˆHØIQˆD×Ò 	Ñ*Ô*Ô7ÔFØ×$Ò$ YÑ/Ô/Ð/Ð/Ð/øÝð 	ð 	ð 	ØˆDˆDð	øøøs   •AA Á
A*Á)A*c                 ó  — |sdS 	 |                       |¦  «        }|r|j        j        nd}|�d|j        _        |sdS |                      ||¦  «         dS # t          $ r  t
                               dd¬¦  «         Y dS w xY w)zBRestore a per-session model override after ``/model --once`` runs.Nz)Failed to restore one-turn model overrideTrß   )rA   rm  Úone_turn_restoreÚ_restore_session_model_overrider2   r3   r4   )r  r+   Ú
_otr_stater*
  s       r>   r$  z6GatewayRunner._restore_pending_one_turn_model_override6?  s·   € àð 	ØˆFð		UØ×1Ò1°+Ñ>Ô>ˆJØCMÐW�zÔ.Ô?Ð?ÐSWˆHØÐ%Ø;?�
Ô'Ô8Øð Ø�Ø×0Ò0°¸hÑGÔGÐGÐGÐGøÝð 	Uð 	Uð 	UÝ�LŠLÐDÈtˆLÑTÔTÐTÐTÐTÐTð	Uøøøs   †5A ½A Á&A?Á>A?)r+   rÙ  c          
   ƒ   ó@  K  — |pg }t          |d¦  «        }|rt          |dd¦  «        n|j        pd}t          | j        dd¦  «        }t          | j        dd¦  «        }|p|                      |¦  «        }|                      |¦  «         t          |||¬¦  «        }	|	rL|j        rEt          |j        ¦  «        }
|j	        t          j        k    r|j        r|
› d	|j        › d
�}
d|
› d|› �}t          |dd¦  «        r|j        › d|› �}g }g }|j        �r!g }g }t          |j        ¦  «        D ]ä\  }}|t!          |j        ¦  «        k     r|j        |         nd}t%          ||¦  «        r|                     |¦  «         |j        t*          j        k    r|                     |¦  «         n'|s%t/          ||¦  «        r|                     |¦  «         |                     d¦  «        s|s*|j        t*          j        k    r|                     |¦  «         Œå|�rKt5          j        | j        ||¬¦  «        ƒ d{V —†}|dk    rUt;          |¦  «        |                      |¦  «        j        _         tB           "                    dt!          |¦  «        ¦  «         nÎtB           "                    d|t!          |¦  «        ¦  «         d}	 |  #                    ||¬¦  «        \  }}tI          |pi ¦  «        }||d<   n,# tJ          $ r tB           &                    dd¬¦  «         Y nw xY wddl'm(}  ||¦  «        5  |  )                    ||¦  «        ƒ d{V —†}ddd¦  «         n# 1 swxY w Y   |rÔ|  *                    ||¦  «        ƒ d{V —†\  }}|r³|  +                    ¦   «         rŸ|  ,                    |¦  «        }|  -                    ||  .                    |¦  «        ¦  «        }|r_|D ]\}	 | /                    |j0        d|› d�|¬¦  «        ƒ d{V —† Œ+# tJ          $ r%}tB           &                    d|¦  «         Y d}~ŒUd}~ww xY w|rŽddl1m2} |D ]…}tf          j4         5                    |¦  «        }| 6                    dd¦  «        }t!          |¦  «        d k    r|d         n|} to          j8        d!d| ¦  «        }  ||¦  «        }!d"| › d#|!› d$�}"|"› d%|› �}Œ†|rŽddl1m2} |D ]…}#tf          j4         5                    |#¦  «        }| 6                    dd¦  «        }t!          |¦  «        d k    r|d         n|} to          j8        d!d| ¦  «        }  ||#¦  «        }!d&| › d#|!› d'�}"|"› d%|› �}Œ†|j        �rnddl9}$ddl1m2}% h d(£}&t          |j        ¦  «        D �]J\  }}t%          ||¦  «        s tu          ||¦  «        stw          ||¦  «        rŒ7|t!          |j        ¦  «        k     r|j        |         nd}|d)v r]tf          j4         <                    |¦  «        d*          =                    ¦   «         }'|'|&v rd+}n|$ >                    |¦  «        \  }(})|(r|(}nd,}tf          j4         5                    |¦  «        }*|* 6                    dd¦  «        }+t!          |+¦  «        d k    r|+d         n|*},to          j8        d!d|,¦  «        }, |%|¦  «        }-t          |,|-|¦  «        }.|.› d%|› �}�ŒL|�Mt          |d-d¦  «        t          j@        k    r.t          |d.d¦  «        rdd/lAmB}/  |/¦   «         rd0|jC        › d1|› �}t          |d2d¦  «        r8|jD        r1|jE        dd3…         }0t          |d4d¦  «        r	d5|0› d6|› �}nd7|0› d6|› �}d8|v �r6	 dd9lFmG}1 dd:lHmI}2 tf          jJ         K                    d;tf          j4         L                    d<¦  «        ¦  «        }3d}4d}5i }6g }7	 t›          ¦   «         }5|5 K                    di ¦  «        }6t�          |6tH          ¦  «        r&|6 K                    d=¦  «        }8|8�tŸ          |8¦  «        }4	 dd>lPmQ}9  |9|5¦  «        }7n'# tJ          $ r |5 K                    d?¦  «        pg }7Y nw xY wn# tJ          $ r Y nw xY w|  #                    |||5¬@¦  «        \  }:};|; K                    dA¦  «        pd}<t�          |6tH          ¦  «        r*|6 K                    dB¦  «        p|6 K                    d¦  «        n|6}=|:|=k    rd}4|4�€t�          |6tH          ¦  «        rk	 ddClRmS}>  |>dd|6 K                    dA¦  «        |<|6 K                    dD¦  «        |; K                    dD¦  «        ¦  «        ƒ d{V —†rd}4n# tJ          $ r d}4Y nw xY w|7r,|<r*	 ddElPmT}?  |?|:|<|7¬F¦  «        }@|@r|@}4n# tJ          $ r Y nw xY w |2|:|<|; K                    dG¦  «        pd|4|; K                    dD¦  «        pd|7¬H¦  «        ƒ d{V —†}A |1||3|A|3¬I¦  «        ƒ d{V —†}B|BjU        rT|  ,                    |¦  «        }C|Cr;|C /                    |j0        dJ V                    |BjW        ¦  «        pdK¦  «        ƒ d{V —† dS |BjX        r|BjY        }nN# tJ          $ rA}DtB           Z                    dL|D¦  «         tB           &                    dMd¬¦  «         Y d}D~Dnd}D~Dww xY w|S )NaÆ  Prepare inbound event text for the agent.

        Keep the normal inbound path and the queued follow-up path on the same
        preprocessing pipeline so sender attribution, image enrichment, STT,
        document notes, reply context, and @ references all behave the same.

        Side effect: buffers per-session native image paths when the active
        model supports native vision AND the user has images attached. The
        caller consumes and clears that session-scoped buffer at the
        ``run_conversation`` site to build a multimodal user turn. When the
        list is empty, the ``_enrich_message_with_vision`` text path has
        already run and images are represented in-text.
        Ú_gateway_pending_stt_textNr®   r<  Tr=  Fr÷  z | Slack user <@Ú>Ú[rí  r�  z

[New message]
rè  rí  ÚnativezSImage routing: native (model supports vision). %d image(s) will be attached inline.zLImage routing: text (mode=%s). Pre-analyzing %d image(s) via vision_analyze.r  z4vision enrichment: session runtime resolution failedrß   r   )Úscoped_runtime_mainõ	   ðŸŽ™ï¸� "rU  r.  z&Transcript echo failed (non-fatal): %s©Úto_agent_visible_cache_pathrK  r|  r)   z	[^\w.\- ]z*[The user sent an audio file attachment: 'rô  u3  . Its content is not inlined here. If the user's request involves what the audio contains, transcribe or process it yourself â€” for example by passing the path to a transcription or media tool â€” instead of asking the user to describe it. Only ask what to do with it if their intent is genuinely unclear.]r  z$[The user sent a video attachment: 'u1  . Its content is not inlined here. If the user's request involves what the video contains, inspect or process it yourself â€” for example by passing the path to a video analysis or media tool â€” instead of asking the user to describe it. Only ask what to do with it if their intent is genuinely unclear.]>   ú.mdú.cfgú.csvú.iniú.logú.txtú.xmlú.ymlú.jsonú.tomlú.yaml>   r®   úapplication/octet-streamr(   z
text/plainr°  r�   rj  ©Ú_discord_tools_loadedz[Triggering message id: `uG   ` â€” use as `message_id` for reply/react/pin via the discord tools.]

r|  r¡  r  z%[Replying to your previous message: "z"]

z[Replying to: "ú@)Ú#preprocess_context_references_async)Úget_model_context_length_asyncrÒ  Ú~r|  ©Úget_compatible_custom_providersÚcustom_providersrê  r  rJ  ©Úshould_clear_context_pin_asyncr  ©Ú"get_custom_provider_context_length©r  r  r¹  rÅ  ©r  rÅ  Úconfig_context_lengthr  r¹  )rÑ  r|  Úallowed_rootr  zContext injection refused.z(@ context reference expansion failed: %sz,@ context reference expansion failure detail)[rá   rV   rè   rz   rA  rÅ  ra  r)  rb  r�   rÄ  rÅ  r¹  r�  rì  rí  r7   rÕ  rÞ  r”   rÚ  rs  râ  ræ  r!  ré  r  r  Ú_decide_image_input_moder½  r/   r0   Únative_image_pathsr3   rz  r�  ru   r2   r4   rm
  r¡  Ú_enrich_message_with_visionÚ"_enrich_message_with_transcriptionÚ_should_echo_stt_transcriptsr@  rî	  ru  r0  r2  Útools.credential_filesr¤  r’   r™   r˜
  re   r_   rõ   Ú	mimetypesrã  rê  r  ry   Ú
guess_typerõ  r±  rr  r²  rj  r5
  r|  Úagent.context_referencesr´  Úagent.model_metadatarµ  r“   rv   rR	  rs   rt   rh  r˜  r¸  Úhermes_cli.route_identityr»  r½  Úblockedrf   Úwarningsr—  r$  rã   )Er  rÖ  r(  rÙ  r+   Ú_pending_stt_preparedÚmessage_textÚ_group_sessions_per_userÚ_thread_sessions_per_userÚ_is_shared_multi_userÚ_safe_user_nameÚaudio_file_pathsÚvideo_pathsÚimage_pathsÚaudio_pathsrî  r™   rÝ  Ú	_img_modeÚvision_runtimeÚ
turn_modelrÔ  r¡  Ú_successful_transcriptsÚ_echo_adapterÚ
_echo_metaÚ_txÚ	_echo_excÚ_to_agent_pathÚ_apathÚ	_basenamer
  Ú_displayÚ_agent_pathÚ_noteÚ_vpathÚ
_mimetypesr¤  Ú_TEXT_EXTENSIONSÚ_extÚguessedrK  r˜
  rg   rñ  rò  Úcontext_noteÚ_disc_tools_loadedÚreply_snippetr´  rµ  Ú_msg_cwdÚ_msg_config_ctxÚ_msg_cfgÚ_msg_model_cfgÚ_msg_custom_providersÚ_msg_raw_ctxr¸  Ú
_msg_modelÚ_msg_runtimeÚ_msg_base_urlÚ_msg_configured_modelr»  r½  Ú_msg_custom_ctxÚ_msg_ctx_lenÚ_ctx_resultr³  r<   sE                                                                        r>   Ú_prepare_inbound_message_textz+GatewayRunner._prepare_inbound_message_textE?  sp  è è € ð* �-˜RˆÝ '¨Ð/JÑ KÔ KÐð %ð�G�EÐ6¸Ñ=Ô=Ð=à”ðð ð	 	õ
 $+¨4¬;Ð8QÐSWÑ#XÔ#XÐ Ý$+¨D¬KÐ9SÐUZÑ$[Ô$[Ð!ð "ÐI T×%AÒ%AÀ&Ñ%IÔ%Iˆð 	×0Ò0°Ñ=Ô=Ð=å <ØØ$<Ø%>ð!
ñ !
ô !
Ðð
 !ð 	A VÔ%5ð 	Aõ ?¸vÔ?OÑPÔPˆOð Œ¥(¤.Ò0Ð0°V´^Ð0à&ÐIÐI¸¼ÐIÐIÐIð  ð A˜Ð@Ð@°,Ð@Ð@ˆLõ
 �5Ð+¨TÑ2Ô2ð 	WØ#Ô3ÐVÐVÈÐVÐVˆLð ')ÐØ!#ˆàÔñ `	"ØˆKØˆKÝ$ UÔ%5Ñ6Ô6ð -ð -‘��4Ø01µC¸Ô8IÑ4JÔ4JÒ0JÐ0J˜Ô)¨!Ô,Ð,ÐPR�õ )¨°Ñ2Ô2ð -Ø×&Ò& tÑ,Ô,Ð,ð Ô%­Ô):Ò:Ð:Ø$×+Ò+¨DÑ1Ô1Ð1Ð1Ø.ð -Õ3LÈUÐTUÑ3VÔ3Vð -Ø×&Ò& tÑ,Ô,Ð,Ø×#Ò# HÑ-Ô-ð -°eð -ÀÔ@RÕVaÔVgÒ@gÐ@gØ×&Ò& tÑ,Ô,Ð,øàñ 2õ #*Ô"3ØÔ1Ø!Ø +ð#ñ #ô #ð ð ð ð ð ð �	ð
  Ò(Ð(õ 7;¸;Ñ6GÔ6Gð ×'Ò'Ø#ñô ä Ô!3Ý—K’KØmÝ˜KÑ(Ô(ñô ð ð õ
 —K’KØfØ!¥3 {Ñ#3Ô#3ñô ð ð &*�NðØ59×5XÒ5XØ#)Ø(3ð 6Yñ 6ô 6Ñ2˜
 Nõ *.¨nÐ.BÀÑ)CÔ)C˜Ø2<˜ wÑ/Ð/øÝ$ð ð ð ÝŸšØRØ%)ð %ñ ô ð ð ð ðøøøð KÐJÐJÐJÐJÐJà,Ð,¨^Ñ<Ô<ð ð Ø-1×-MÒ-MØ(Ø'ñ.ô .ð (ð (ð (ð (ð (ð (˜ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ð "Ø>B×>eÒ>eØ Øñ?ô ?ð 9ð 9ð 9ð 9ð 9ð 9Ñ5�Ð5ð +ð "¨t×/PÒ/PÑ/RÔ/Rð "Ø$(×$<Ò$<¸VÑ$DÔ$D�MØ!%×!AÒ!AÀ&È$×JfÒJfÐglÑJmÔJmÑ!nÔ!n�JØ$ð "Ø#:ð 
"ð 
"˜Cð	"Ø&3×&8Ò&8Ø$*¤NØ$6°Ð$6Ð$6Ð$6Ø-7ð '9ñ '"ô '"ð !"ð !"ð !"ð !"ð !"ð !"ð !"ð !"øõ
 $-ð "ð "ð "Ý &§¢Ø$LÈiñ!"ô !"ð !"ð !"ð !"ð !"ð !"ð !"øøøøð"øøøð ð 	<Ø\Ð\Ð\Ð\Ð\Ð\Ø*ð <ð <�ÝœG×,Ò,¨VÑ4Ô4�	Ø"Ÿš¨¨aÑ0Ô0�Ý(+¨F©¬°qÒ(8Ð(8˜6 !œ9˜9¸i�Ýœ6 ,°°XÑ>Ô>�Ø,˜n¨VÑ4Ô4�ðFÀð Fð FØ'2ðFð Fð Fð ð #(Ð;Ð;¨\Ð;Ð;��àð 	<Ø\Ð\Ð\Ð\Ð\Ð\Ø%ð <ð <�ÝœG×,Ò,¨VÑ4Ô4�	Ø"Ÿš¨¨aÑ0Ô0�Ý(+¨F©¬°qÒ(8Ð(8˜6 !œ9˜9¸i�Ýœ6 ,°°XÑ>Ô>�Ø,˜n¨VÑ4Ô4�ðF¸8ð Fð FØ'2ðFð Fð Fð ð #(Ð;Ð;¨\Ð;Ð;��àÔñ -	CØ*Ð*Ð*Ð*ØJÐJÐJÐJÐJÐJàyÐyÐyÐÝ$ UÔ%5Ñ6Ô6ð (Cñ (C‘��4õ *¨%°Ñ3Ô3ðå,¨U°AÑ6Ô6ðõ -¨U°AÑ6Ô6ðð
 Ø01µC¸Ô8IÑ4JÔ4JÒ0JÐ0J˜Ô)¨!Ô,Ð,ÐPR�ØÐ<Ð<Ð<Ýœ7×+Ò+¨DÑ1Ô1°!Ô4×:Ò:Ñ<Ô<�DØÐ/Ð/Ð/Ø ,˜˜à%/×%:Ò%:¸4Ñ%@Ô%@™
˜ Ø"ð ?Ø$+˜E˜Eà$>˜Eõ
 œ7×+Ò+¨DÑ1Ô1�Ø Ÿš s¨AÑ.Ô.�Ý+.¨u©:¬:¸ª?¨?˜u Qœx˜xÀ�Ý!œv l°C¸ÑFÔF�ð
 9Ð8¸Ñ>Ô>�
å;¸LÈ*ÐV[Ñ\Ô\�Ø".ÐBÐB°LÐBÐB�‘ð ÐÝ˜ 
¨DÑ1Ô1µXÔ5EÒEÐEÝ˜˜|¨TÑ2Ô2ð Fð TÐSÐSÐSÐSÐSØ!Ð!Ñ#Ô#ð ð&°Ô0@ð &ð &à#ð&ð &ð õ �5˜/¨4Ñ0Ô0ð 	U°UÔ5Nð 	Uð "Ô/°°°Ô5ˆMÝ�uÐ7¸Ñ?Ô?ð Uð&¸Mð &ð &Ø#ð&ð &ð �ð
  U°ÐTÐTÀlÐTÐT�à�,ÐÑðe\ØXÐXÐXÐXÐXÐXØOÐOÐOÐOÐOÐOåœ:Ÿ>š>¨.½"¼'×:LÒ:LÈSÑ:QÔ:QÑRÔR�Ø"&�Ø�Ø!#�Ø(*Ð%ðÝ3Ñ5Ô5�HØ%-§\¢\°'¸2Ñ%>Ô%>�NÝ! .µ$Ñ7Ô7ð @Ø'5×'9Ò'9Ð:JÑ'KÔ'K˜Ø'Ð3Ý.1°,Ñ.?Ô.?˜OðWØUÐUÐUÐUÐUÐUà0OÐ0OÐPXÑ0YÔ0YÐ-Ð-øÝ$ð Wð Wð WØ08·²Ð=OÑ0PÔ0PÐ0VÐTVÐ-Ð-Ð-ðWøøøøøå ð ð ð Ø�Dðøøøð ,0×+NÒ+NØ!Ø +Ø (ð ,Oñ ,ô ,Ñ(�
˜Lð
 !-× 0Ò 0°Ñ <Ô <Ð BÀ�õ " .µ$Ñ7Ô7ð(�N×&Ò& yÑ1Ô1ÐP°^×5GÒ5GÈÑ5PÔ5Pøà'ð &ð
 Ð!6Ò6Ð6Ø&*�OØ"Ð.µ:¸nÍdÑ3SÔ3SÐ.ð/Ø\Ð\Ð\Ð\Ð\Ð\à!?Ð!?Ø Ø Ø*×.Ò.¨zÑ:Ô:Ø)Ø*×.Ò.¨zÑ:Ô:Ø(×,Ò,¨ZÑ8Ô8ñ"ô "ð ð ð ð ð ð ð 3ð /3˜OøøÝ$ð /ð /ð /Ø*.˜˜˜ð/øøøà(ð ¨]ð ðØXÐXÐXÐXÐXÐXà*LÐ*LØ",Ø%2Ø-Bð+ñ +ô +˜ð
 +ð >Ø.=˜OøøÝ$ð ð ð Ø˜ðøøøà%CÐ%CØØ*Ø(×,Ò,¨YÑ7Ô7Ð=¸2Ø*9Ø)×-Ò-¨jÑ9Ô9Ð?¸RØ%:ð&ñ &ô &ð  ð  ð  ð  ð  ð  �ð %HÐ$GØ Ø Ø#/Ø!)ð	%ñ %ô %ð ð ð ð ð ð �ð Ô&ð  Ø#×7Ò7¸Ñ?Ô?�HØð Ø&ŸmšmØ"œNØ ŸIšI kÔ&:Ñ;Ô;Ð[Ð?[ñô ð ð ð ð ð ð ð ð  ˜4ØÔ'ð 7Ø#.Ô#6�LøøÝð \ð \ð \Ý—’ÐIÈ3ÑOÔOÐOÝ—’ÐKÐVZ�Ñ[Ô[Ð[Ð[Ð[Ð[Ð[Ð[øøøøð\øøøð Ðsï   Ê=0K. Ë.&LÌLÌ+MÍMÍMÏ'PÐ
P2ÐP-Ð-P2Ý)Ai Þ;Aa à`- à,a à-!aáa áaáa ái á
a"ái á!a"á"Bi ã8Ae åi åeåi åeåi å'f  å?i æ 
fæ
i æfæB2i éi é
jé7jêjc             ƒ   ó6  K  — t          t          | dd¦  «        dd¦  «        rYt          |                      |¦  «        ¦  «        5  |                      ||||¬¦  «        ƒ d{V —†cddd¦  «         S # 1 swxY w Y   |                      ||||¬¦  «        ƒ d{V —†S )zDRun inbound preprocessing under the routed profile when multiplexed.rz   Nr½  F©rÖ  r(  rÙ  r+   )rV   rº  Ú _resolve_profile_home_for_sourcerü  )r  rÖ  r(  rÙ  r+   s        r>   Ú,_prepare_profile_scoped_inbound_message_textz:GatewayRunner._prepare_profile_scoped_inbound_message_textÝ@  s+  è è € õ •7˜4 ¨4Ñ0Ô0Ð2FÈÑNÔNð 	Ý'¨×(MÒ(MÈfÑ(UÔ(UÑVÔVð ð Ø!×?Ò?ØØ!Ø#Ø +ð	 @ñ ô ð ð ð ð ð ð ðð ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ×7Ò7ØØØØ#ð	 8ñ 
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ð 	
s   ÁA1Á1A5Á8A5c              ƒ   óâ   K  — |                       |¦  «        s|j        pd                     ¦   «         S |                      |d¦  «        ƒ d{V —†\  }}d                     d„ |D ¦   «         ¦  «        S )zDReturn raw text or successful voice transcripts for a clarify reply.r®   Nr  c              3   óf   K  — | ],}|                      ¦   «         ¯|                      ¦   «         V — Œ-d S r^   r»  )rb   Ú
transcripts     r>   rd   z<GatewayRunner._prepare_clarify_reply_text.<locals>.<genexpr>ý@  sT   è è € ð 
ð 
àØ×ÒÑ!Ô!ð
Ø×ÒÑÔð
ð 
ð 
ð 
ð 
ð 
rM   )rÆ	  rè   rx   Ú$_transcribe_pending_audio_event_oncerf   )r  rÖ  rK  rÉ	  s       r>   rî  z)GatewayRunner._prepare_clarify_reply_textõ@  s§   è è € à×.Ò.¨uÑ5Ô5ð 	.Ø”JÐ$ "×+Ò+Ñ-Ô-Ð-à*.×*SÒ*SØ�2ñ+
ô +
ð %
ð %
ð %
ð %
ð %
ð %
Ñ!ˆÐ!ð �{Š{ð 
ð 
à4ð
ñ 
ô 
ñ 
ô 
ð 	
rM   c                 óš   — |                       |¦  «        }|�|j        j        sg S t          |j        j        ¦  «        }g |j        _        |S r^   )rA   r0   rÃ  r½  )r  r+   r;   rL  s       r>   rÅ  z1GatewayRunner._consume_pending_native_image_pathsA  sL   € Ø×(Ò(¨Ñ5Ô5ˆØˆ= Ô 0Ô Cˆ=ØˆIÝ�UÔ%Ô8Ñ9Ô9ˆØ.0ˆÔÔ+ØˆrM   c                 óÜ  — |r|€d S t          | dd ¦  «        }|€t          ¦   «         }|| _        	 t          j        |¦  «        ||<   n.# t
          $ r! t                               d|d¬¦  «         Y d S w xY w	 |                     |¦  «         t          | dd¦  «        }t          |¦  «        |k    r+| 
                    d¬¦  «         t          |¦  «        |k    °)d S d S # t
          $ r Y d S w xY w)	Nr¡  z*Failed to cache live session source for %sTrß   r¢  r`  F©rQ  )rV   r   r¡  ri  rl  r2   r3   r4   r  r7   Úpopitem)r  r+   r(  Úcached_sourcesÚmax_sizes        r>   Ú_cache_session_sourcez#GatewayRunner._cache_session_sourceA  s-  € Øð 	˜f˜nØˆFÝ  Ð'9¸4Ñ@Ô@ˆØÐ!Ý(™]œ]ˆNØ$2ˆDÔ!ð	Ý*5Ô*=¸fÑ*EÔ*EˆN˜;Ñ'Ð'øÝð 	ð 	ð 	Ý�LŠLÐEÀ{Ð]aˆLÑbÔbÐbØˆFˆFð	øøøð	Ø×&Ò& {Ñ3Ô3Ð3Ý˜tÐ%;¸SÑAÔAˆHÝ�nÑ%Ô%¨Ò0Ð0Ø×&Ò&¨EÐ&Ñ2Ô2Ð2õ �nÑ%Ô%¨Ò0Ð0Ð0Ð0Ð0Ð0øåð 	ð 	ð 	ØˆDˆDð	øøøs$   °A Á'A3Á2A3Á7A"C Ã
C+Ã*C+c                 ó~   — t          | dd¦  «        }|�|j        | j        urt          | j        ¦  «        }|| _        |S )z>Return the single async facade for this runner's SessionStore.r�  N)rV   Ú_storer›  rX  r�  )r  Úfacades     r>   r8
  z!GatewayRunner.async_session_store A  sG   € õ ˜Ð5°tÑ<Ô<ˆØˆ>˜Vœ]°$Ô2DÐDÐDÝ& tÔ'9Ñ:Ô:ˆFØ(.ˆDÔ%ØˆrM   c              ƒ   ó  K  — 	 | j                              |¦  «        ƒ d{V —†}n4# t          $ r'}t                               d||¦  «         Y d}~dS d}~ww xY w|sdS t          |d|¦  «         t          |d|¦  «         dS )z=Persist the exact resolved routing key for this running turn.Nz/Could not persist active-turn marker for %s: %sFÚ _gateway_active_turn_session_keyÚ_gateway_active_turn_tokenT)r8
  Úmark_turn_activer2   r3   rã   rÔ
  )r  rÖ  r+   rÄ  r<   s        r>   Ú_mark_durable_active_turnz'GatewayRunner._mark_durable_active_turn)A  s¾   è è € ð	ØÔ2×CÒCÀKÑPÔPÐPÐPÐPÐPÐPÐPˆEˆEøÝð 	ð 	ð 	Ý�NŠNØAØØñô ð ð
 �5�5�5�5�5øøøøð	øøøð ð 	Ø�5õ 	�Ð9¸;ÑGÔGÐGÝ�Ð3°UÑ;Ô;Ð;Øˆts   „ % ¥
A¯AÁAc              ƒ   óÔ  K  — t          |dd¦  «        }t          |dd¦  «        }	 |r|s)	 dD ]#}	 t          ||¦  «         Œ# t          $ r Y Œ w xY wdS d}t          dd¦  «        D ]”}	 t	          | j                             ||¦  «        ƒ d{V —†¦  «        c dD ]#}	 t          ||¦  «         Œ# t          $ r Y Œ w xY wS # t          $ r/}|}|dk     rt           	                    d	|||¦  «         Y d}~Œ�d}~ww xY wt           
                    d
||¦  «         	 dD ]#}	 t          ||¦  «         Œ# t          $ r Y Œ w xY wdS # dD ]#}	 t          ||¦  «         Œ# t          $ r Y Œ w xY ww xY w)z5Best-effort CAS clear of the marker owned by *event*.r  Nr  )r  r  Fr(   r  r)   z5Retrying active-turn marker cleanup for %s (%d/3): %sz>Could not clear active-turn marker for %s after 3 attempts: %s)rV   Údelattrr´	  r  rº   r8
  Úclear_turn_activer2   r3   r4   rã   )r  rÖ  r+   rÄ  ré  Ú
last_errorr  r<   s           r>   r%  z(GatewayRunner._clear_durable_active_turn@A  sv  è è € å˜eÐ%GÈÑNÔNˆÝ˜Ð;¸TÑBÔBˆð%	Øð  eð Øð8ð ð �ðÝ˜E 4Ñ(Ô(Ð(Ð(øÝ%ð ð ð Ø�Dðøøøðð ð7 /3ˆJÝ   A™;œ;ð ð �ðÝØ"Ô6×HÒHØ'¨ñô ð ð ð ð ð ð ñô ð ð ð0ð ð �ðÝ˜E 4Ñ(Ô(Ð(Ð(øÝ%ð ð ð Ø�Dðøøøðøõ' !ð ð ð Ø!$�JØ ’{�{ÝŸšØSØ'Ø#Øñ	ô ð øøøøøøøøøðøøøõ �NŠNØPØØñô ð ð
 ðð ð �ðÝ˜E 4Ñ(Ô(Ð(Ð(øÝ%ð ð ð Ø�Dðøøøðð øð ð ð �ðÝ˜E 4Ñ(Ô(Ð(Ð(øÝ%ð ð ð Ø�Dðøøøðøøøs”   ¦D? °AÁ
AÁAÁD? Á(-B>ÂD? ÂB-Â-
B:Â9B:Â>
C7Ã%C2Ã-D? Ã2C7Ã7D? ÄD-Ä-
D:Ä9D:Ä?E'ÅEÅE'Å
E#	Å E'Å"E#	Å#E'c                 ó´   — |sd S t          | dd ¦  «        }|sd S |                     |¦  «        }|�'	 |                     |¦  «         n# t          $ r Y nw xY w|S )Nr¡  )rV   rv   r  r2   )r  r+   r	  r(  s       r>   r:
  z(GatewayRunner._get_cached_session_sourcekA  sˆ   € Øð 	Ø�4Ý  Ð'9¸4Ñ@Ô@ˆØð 	Ø�4Ø×#Ò# KÑ0Ô0ˆØÐðØ×*Ò*¨;Ñ7Ô7Ð7Ð7øÝð ð ð Ø�ðøøøàˆs   ²A Á
AÁAr;  r¼  c              ƒ   ó~b  ‡è‡é‡ê‡ë‡ìK  — t          j         ¦   «         }t          |j        d¦  «        r|j        j        nt	          |j        ¦  «        }|j        pddd…                              dd¦  «        }t          |dd¦  «        }t          |dd¦  «        pddd…                              dd¦  «        }	t           	                    d	||j
        p|j        pd
|j        pd
|||	¦  «         t          j        | j        |¦  «        ƒ d{V —†}
|
�\t           	                    d|j        |j        |j        |
¦  «         t#          j        ||
¬¦  «        }	 ||_        n# t&          $ r Y nw xY w| j                             |¦  «        ƒ d{V —†}|j        }t	          t          |dd¦  «        pi                      d¦  «        pd¦  «                             ¦   «         }|r"|                      ||¦  «        ƒ d{V —†}|€dS |}|                      ||¦  «         t          j        | j        |¦  «        ƒ d{V —†�rÙ	 | j        rF| j                             t	          |j        ¦  «        t	          |j        ¦  «        ¬¦  «        ƒ d{V —†nd}n.# t&          $ r! t                               dd¬¦  «         d}Y nw xY w|�rt	          |                     d¦  «        pd¦  «        }|rb| j        �[	 | j                             |¦  «        ƒ d{V —†}n/# t&          $ r" t                               d|d¬¦  «         |}Y nw xY w|r||k    r|}|r0||j         k    r%| j         !                    ||¦  «        ƒ d{V —†}|�|}|rK|t	          |                     d¦  «        pd¦  «        k    r#t          j        | j"        ||d¬¦  «        ƒ d{V —† nO	 t          j        | j#        ||¦  «        ƒ d{V —† n,# t&          $ r t                               dd¬¦  «         Y nw xY wt          |dd¦  «        }|r3|  $                    |d¬¦  «         |  %                    |¦  «         d|_&        |j'        |j(        k    p|pt          |dd¦  «        }t          |dd¦  «        rd|_)        |rC| j*         +                    d|j        r|j        j        nd|j        |j         |dœ¦  «        ƒ d{V —† tY          || j-        |¦  «        }|  .                    |¦  «        }d}d}d}	 t_          ¦   «         }ta          |                     d¦  «        pi                      dd¦  «        ¦  «        }n# t&          $ r Y nw xY w|  1                    |||¦  «        }g }|�rt          |d d¦  «        pd!}|d"k    rd#}n|d$k    rd%}n|d&k    rd'}nd(}	 te          ||¦  «        }n# t&          $ r d}Y nw xY w|r|d)z   |z   }| 3                    |¦  «         	 | j4        j-         5                    |j        t          |d*d+¦  «        ¬,¦  «        } |j        r|j        j        nd}!t          |d-d¦  «        }"|d.v p| j6        o
|"o|!| j7        v}#|#rá|  8                    |¦  «        }$|$rÊ|d"k    rd/}%nJ|d&k    rd0}%nA|d$k    rd1| j9        › d2�}%n/| j:        d3z  }&| j:        d3z  }'|'s|&› d4�n|&r|&› d5|'› d6�n|'› d6�}(d7|(› �}%d8|%› d9�})	 t          j        | j;        |¦  «        ƒ d{V —†}*|*r|)› d)|*› �})n# t&          $ r Y nw xY w|$ <                    |j        |)|  =                    |¦  «        ¬:¦  «        ƒ d{V —† n2# t&          $ r%}+t                               d;|+¦  «         Y d}+~+nd}+~+ww xY wd|_>        t          |d<d¦  «        },|�r2|,�r/t          |,t          ¦  «        r|,gnt�          |,¦  «        }-	 d=d>lAmB}.mC}/ g }0g }1|-D ]r}2 |.|2|¬?¦  «        }3|3rF|3\  }4}5}6d@|6› dA�}7 |/|4|5|7¦  «        }8|8r*|0 3                    |8¦  «         |1 3                    |2¦  «         ŒWt           D                    dB|2¦  «         Œs|0rP|0 3                    |j        ¦  «         d) E                    |0¦  «        |_        t           	                    dC|1|¦  «         n3# t&          $ r&}+t           D                    dD|-|+¦  «         Y d}+~+nd}+~+ww xY wt          | dEd¦  «        }9|9�‡	 |9 F                    |j         ||t�          dFt�          ¦  «        ¬G¦  «        ƒ d{V —†}:n$# t’          $ r |  J                    |¦  «         ‚ w xY w|:�(|  K                    |¦  «        jL        };|:|;_M        ||;_N        |  O                    ||j        ¦  «        ƒ d{V —† | j         P                    |j         ¦  «        ƒ d{V —†}<|<�r@t£          |<¦  «        dHk    �r,d=dIlRmS}=mT}> dJ}?dK}@d}AdL}BdM}CdN}DdO}Ed}Fd}Gd}Hd}Id}Jd}Kd}Li }M	 t_          ¦   «         }M|M�rk|M                     dPi ¦  «        }Nt          |Nt          ¦  «        r|N}?n®t          |Ntª          ¦  «        r™|N                     dQ¦  «        p|N                     dP¦  «        p|?}?|N                     dR¦  «        }O|O�(	 t­          |O¦  «        }Fn# t®          t°          f$ r Y nw xY w|N                     dS¦  «        pd}G|N                     dT¦  «        pd}H|M                     dUi ¦  «        }Pt          |Ptª          ¦  «        �rct	          |P                     dVd¦  «        ¦  «         Y                    ¦   «         dWv }A|P                     dX¦  «        }Q|Q�0	 t­          |Q¦  «        }R|Rd=k    r|R}Bn# t®          t°          f$ r Y nw xY w|P                     dY¦  «        }S|S�0	 tµ          |S¦  «        }R|Rd=k    r|R}Cn# t®          t°          f$ r Y nw xY w|P                     dZ¦  «        }T|T�0	 tµ          |T¦  «        }R|Rd=k    r|R}Dn# t®          t°          f$ r Y nw xY wt·          |D|C¦  «        }D|P                     d[¦  «        }U|U�0	 tµ          |U¦  «        }R|Rd=k    r|R}En# t®          t°          f$ r Y nw xY w|?}J|G}K|H}L	 |  \                    ||t          |Mtª          ¦  «        r|Mnd¬\¦  «        \  }?}V|V                     dS¦  «        p|G}G|V                     dT¦  «        p|H}H|V                     d]¦  «        p|I}In# t&          $ r Y nw xY w|F�2	 d=d^l]m^}W  |W|J|?|L|H|K|G¦  «        ƒ d{V —†rd}Fn# t&          $ r d}FY nw xY w|F€‹|Hr‰	 	 d=d_l_m`}Xma}Y  |X|M¦  «        }Zn<# t&          $ r/ |M                     d`¦  «        }Zt          |Zt€          ¦  «        sg }ZY nw xY w |Y|?|H|Z¬a¦  «        }[|[rt­          |[¦  «        }Fn# t®          t°          f$ r Y nw xY wn# t&          $ r Y nw xY w|A�
r% |>|?|Hpd|Ipd|F|Gpd¬b¦  «        ƒ d{V —†}\t­          |\|@z  ¦  «        }]t­          |\dcz  ¦  «        }^t£          |<¦  «        }_|jb        }`|`d=k    r|`Šèdd}an |=|<¦  «        Šède}a|B}b‰è|]k    p|_|bk    }c|cr t          | dfd¦  «        }d|d��t          |ddg|d¦  «        }dt          |ddhd¦  «        }e|e�i	  |e|j         ¦  «        }fn# t&          $ r d}fY nw xY w|frC|f                     did=¦  «        d=k    r)t           	                    dj|j         |fdi         ¦  «         d}c|c�	rt           	                    dk|_‰èdl›|at­          |@dmz  ¦  «        |\dl›|]dl›¦  «         |  =                    ||  c                    |¦  «        ¦  «        }g	 d=dnldme}h d=dolfmg}i |  \                    ||t          |Mtª          ¦  «        r|Mnd¬\¦  «        \  }?}V|V                     d]¦  «        �rdp„ |<D ¦   «         Šìt£          ‰ì¦  «        dHk    �rý	 | j         h                    |j         ¦  «        ƒ d{V —†}jn<# t&          $ r/}kd}jt           D                    dq|j         |kd¬¦  «         Y d}k~knd}k~kww xY wt          | j        dg| j        ¦  «        }l |i�d.i |V¤|?dHdddrg|j         |ldsœ¤ŽŠêtÓ          ‰ê|j¦  «         tÔ          ‰ê_        d}m	 d‰ê_k        t          t          ‰êdtd¦  «        dud¦  «        }ntÙ          |n¦  «        r |n|l|j         ¦  «         d‰ê_m        dv„ ‰ê_n        t          jo        ¦   «         }o |h¦   «         Šë|o p                    dˆèˆêˆëˆìfdw„¦  «        }p	 t          jq        ¦   «         }q	 t·          |C‰ë r                    ¦   «         z
  dx¦  «        }r	 t          js        t          jt        |p¦  «        |r¬y¦  «        ƒ d{V —†\  }s}tno# t          ju        $ r] t          jq        ¦   «         |qz
  }u‰ë r                    ¦   «         }v|v|Ck     r+|u|Dk     r%t           	                    dz|j         |u|v|D¦  «         Y ŒÃ‚ w xY w�nÝ# t          ju        $ �r� d}w|w€<‰ëjv        rd}wn2‰ë w                    ¦   «         }w|w€t          jx        d{¦  «        ƒ d{V —† |w®<|ws|pƒ d{V —†\  }s}t�n=‰ë y                    ¦   «          |  z                    |p‰êd|¬}¦  «         d}m|Ed=k    r&t÷          | |j         tù          | ||E¦  «        d~¦  «         d=dl}m~}x tÿ          ‰êd€|xj€        d�¦  «         t           D                    d‚|j         ‰ë r                    ¦   «         t          jq        ¦   «         |qz
  |D¦  «         dƒ|Cd„›d…�}y	 |  8                    |¦  «        }z|zr*|j        r#|z <                    |j        |y|g¬:¦  «        ƒ d{V —† n2# t&          $ r%}{t           D                    d†|{¦  «         Y d}{~{nd}{~{ww xY w‚ Y n?�t          $ r2 ‰ë ‚                    ¦   «          |ms|  z                    |p‰êd‡¬}¦  «         d}m‚ w xY w‰êj         }||||j         k    }}ta          t          ‰êdˆd¦  «        ¦  «        }~|}r§| j         ƒ                    |||s¦  «        ƒ d{V —†s&t           „                    d‰|j         ||¦  «         d}}d}~n`|||_         |  …                    ||||¦  «         | j         †                    ¦   «         ƒ d{V —† t          j        | j"        ||dŠ¬¦  «        ƒ d{V —† |}r$d=|_b        |s}<t£          |s¦  «        } |=|s¦  «        }€nJ|~r$d=|_b        |s}<t£          |s¦  «        } |=|s¦  «        }€n$|_}‰è}€t           D                    d‹|j         ¦  «         t           	                    dŒ|_|‰èdl›|€dl›¦  «         |€|^k    rt           D                    d�|€dl›¦  «         t          ‰êdtd¦  «        }�|�duot          |�dŽd¦  «        }‚|‚s(�t          |‚|}|~|_|‰è|€¬�¦  «        r�t          | |¦  «         |‚rù|Ed=k    r5t÷          | |j         tù          | ||E¦  «        t          |�d�d¦  «        ¦  «         d=dl}m~}x tÿ          ‰êd‘|xj‰        d’¦  «         t          |�d�d¦  «        pd“}ƒd=d”lŠm‹}„  |„|ƒd¬•¦  «        }ƒd–|ƒ› d—�}…	 |  8                    |¦  «        }z|zr*|j        r#|z <                    |j        |…|g¬:¦  «        ƒ d{V —† nç# t&          $ r%}{t           D                    d˜|{¦  «         Y d}{~{n½d}{~{ww xY w|��³t          |�d™d¦  «        r¢t          |�d™d¦  «        }†t          |�dšd¦  «        pd“}‡d›|†› dœ|‡› d��}ˆ	 |  8                    |¦  «        }z|zr*|j        r#|z <                    |j        |ˆ|g¬:¦  «        ƒ d{V —† n2# t&          $ r%}{t           D                    dž|{¦  «         Y d}{~{nd}{~{ww xY w|  %                    |¦  «         |ms|  Œ                    ‰êdŸ¬}¦  «        ƒ d{V —† n:# |  %                    |¦  «         |ms|  Œ                    ‰êdŸ¬}¦  «        ƒ d{V —† w w xY wn2# t&          $ r%}+t           D                    d |+¦  «         Y d}+~+nd}+~+ww xY w|<sû| j         �                    ¦   «         ƒ d{V —†sÜd¡}‰	 d=d¢lŽm�}Šm�}‹m‘}Œm’}�m“}Ž t_          ¦   «         }� |Ž|�¦  «        d£k    rQ |‹|�|Š¦  «        sE| 3                     |�¦   «                              ¦   «         ¦  «          |Œ�t(          d¤z  |Š¦  «         n| 3                    |‰¦  «         nG# t&          $ r:}�t                               d¥|�¦  «         | 3                    |‰¦  «         Y d}�~�nd}�~�ww xY w|<�sµ|j        �r­|j        �t*          j–        k    �r–|j        �t*          j—        k    �r|j        j        }!�t1          |!¦  «        }‘d}’	 d=d¦l™mš}“ |‘r |“|‘¦  «        pd                     ¦   «         nd}’n# t&          $ r d}’Y nw xY w|’s-|‘r)�t7          jœ        |‘¦  «        pd                     ¦   «         nd}’	 |’s!| j-         �                    |j        ¦  «        rd§}’n# t&          $ r Y nw xY w|’sk	 d=d¨lžmŸ}” t          |d©d¦  «        pd                     ¦   «         }•|•r,|•dQk    r& |”¦   «         }| �                    |j        ¦  «        rd§}’n# t&          $ r Y nw xY w|’sQ|j        �t*          j         k    rdªnd«}–d¬|! ¡                    ¦   «         › d­|–› d®�})|  ¢                    ||)¦  «        ƒ d{V —† |  £                    |||¦  «        }—|—r| 3                    |—¦  «         |  ¤                    |||<|¬¯¦  «        ƒ d{V —†}˜|˜€dS 	 d=d°l¥m¦}™ d=d±l§m¨}šm©}›mª}œ  |™¦   «         }�t          |d²d¦  «        }ž|˜rgt          |˜t          ¦  «        rR |œ|˜|�¬³¦  «        \  }Ÿ} |Ÿ} |š|ž|�¬³¦  «        }¡|¡�|¡n| }�tW          t_          ¦   «         ¦  «        r |›|Ÿ||�¬³¦  «        }˜n|Ÿ}˜n2# t&          $ r%}¢t                               d´|¢¦  «         Y d}¢~¢nd}¢~¢ww xY w|r|r|  ¬                    ||¦  «         |  ­                    |  8                    |¦  «        ||¦  «         	 |j        r|j        j        nd|j        |j        pdt          |dµd¦  «        rt	          t          |dµd¦  «        ¦  «        ndt          |d*d¦  «        pd|j         |˜dd¶…         d·œ}£| j*         +                    d¸|£¦  «        ƒ d{V —† |j         }¤t          jq        ¦   «         }¥|  ®                    |˜||<||¤|||  c                    |¦  «        |j¯        t          |d¹d¦  «        |||j°        ¬º¦  «        ƒ d{V —†}¦t          jq        ¦   «         |¥z
  }§	 |  8                    |¦  «        }¨t          �tc          |¨¦  «        d»d¦  «        }©t          �tc          |¨¦  «        d¼d¦  «        }ª|¨rXtÙ          |©¦  «        rI|¨ ²                    |j        |  =                    ||  c                    |¦  «        ¦  «        ¦  «        ƒ d{V —† n1|¨r/tÙ          |ª¦  «        r |¨ ³                    |j        ¦  «        ƒ d{V —† n# t&          $ r Y nw xY w|  ´                    ||¦  «        s¯t           	                    d½|pd¾|¦  «         |  8                    |¦  «        }«t          �tc          |«¦  «        d¿d¦  «        �|« µ                    ||¬À¦  «         n-|«r+t          |«dÁ¦  «        r|«j¶         ·                    |d¦  «         	 |  J                    |¦  «         dS |¦                     dÂ¦  «        pd}¬�tq          |¦¦  «        rd}¬	 d=dÃl¹mº}­  |­|¦|¬¦  «        }®n# t&          $ r d}®Y nw xY w|¬dÄk    r|®sdÅ}¬|¦                     dÆg ¦  «        }¯t          j         ¦   «         |z
  }°|¦                     dÇd=¦  «        }±t£          |¬¦  «        }²t           	                    dÈ||j        pd
|°|±|²¦  «         |rz�tw          |¦¦  «        rj|  ¼                    |¦  «         	 | j         ½                    |¦  «        ƒ d{V —† n3# t&          $ r&}³t                               dÉ||³¦  «         Y d}³~³nd}³~³ww xY w|®s6�t}          |¦|¬t£          |<¦  «        ¬Ê¦  «        }¬�t          |j        |¬¦  «        }¬|¦                     d¦  «        rÓ|¦d         |j         k    rÂ|j         |¤k    r“|¦d         |_         |  …                    |||j         ¦  «         | j         †                    ¦   «         ƒ d{V —† | j         À                    |j         ||¦  «        ƒ d{V —† t          j        | j"        ||dË¬¦  «        ƒ d{V —† n$t           	                    dÌ|pd¾|¤|j         ¦  «         	 �tƒ          t_          ¦   «         �t…          |j        ¦  «        dÍta          t          | dÎd¦  «        ¦  «        |j        �t*          jÃ        h¬Ï¦  «        }´n9# t&          $ r, |j        �t*          jÃ        k    rdnt          | dÎd¦  «        }´Y nw xY w|´�r‚|¬�r|®�s||¦                     dÐ¦  «        }µ|µ�rdd=dÑlÄmÅ}¶ |µ                     ¦   «          Æ                    ¦   «         }·t£          |·¦  «        dÒk    r7d E                    |·ddÒ…         ¦  «        }¸|¸dÓt£          |·¦  «        dÒz
  › dÔ�z  }¸n|µ                     ¦   «         }¸	 d=dÕlÇmÈ}¹  |¹t_          ¦   «         �t…          |j        ¦  «        dÖd×¦  «        }ºn# t&          $ r d×}ºY nw xY w|ºdØk    r:d E                    dÙ„ |¸ Æ                    ¦   «         D ¦   «         ¦  «        }»dÚ|»› d)|¬› �}¬nS|ºdÛk    r:d E                    dÜ„ |¸ Æ                    ¦   «         D ¦   «         ¦  «        }»dÝ|»› d)|¬› �}¬n |¶|¸¦  «        }¸dÞ|¸› dß|¬› �}¬d}¼	 d=dàlÉmÊ}½  |½t_          ¦   «         �t…          |j        ¦  «        |¦                     dP¦  «        |¦                     dád=¦  «        pd=|¦                     dR¦  «        pd�t6          jË                             dâd¦  «        |§¬ã¦  «        }¼n4# t&          $ r'}¾t                               dä|¾¦  «         d}¼Y d}¾~¾nd}¾~¾ww xY w|¼r |¬r|¦                     då¦  «        s	|®s|¬› d)|¼› �}¬| j*         +                    dæi |£¥|¬pddd¶…         |¦                     dPd¦  «        |¦                     dSd¦  «        dçœ¥¦  «        ƒ d{V —† 	 d=dèlÌmÍ}¿ |¿jÎ        }Àg |¿_Î        �tŸ          |À¦  «        D ]O\  }Á}Ât          jÐ        |  Ñ                    |Â¦  «        ¦  «         |Ádmz  dék    rt          jx        d=¦  «        ƒ d{V —† ŒPn2# t&          $ r%}+t           „                    dê|+¦  «         Y d}+~+nd}+~+ww xY w	 d=dèlÌmÍ}Ã �t¥          |ÃjÓ        ¦  «        }Ä|ÄD ]d}Å�t©          |Å¦  «        }Æ|ÆrP	 |  Õ                    |Æ|Å¦  «        ƒ d{V —† Œ2# t&          $ r%}Çt           „                    dë|Ç¦  «         Y d}Ç~ÇŒ\d}Ç~Çww xY wŒen2# t&          $ r%}+t                               dì|+¦  «         Y d}+~+nd}+~+ww xY wta          |¦                     dí¦  «        ¦  «        }È�tq          |¦¦  «        }Ét	          |¦                     dîd¦  «        ¦  «         Y                    ¦   «         Šé|ÈoTta          |¦                     dï¦  «        ¦  «        p2�t­          ˆéfdð„dñD ¦   «         ¦  «        pdò‰év ot£          |<¦  «        dók    }Ê|Êr!t           	                    dô|j         ¦  «         nZ|Èr!t           	                    dõ|j         ¦  «         n7|Ér5t           D                    dö|j         |¦                     dîd÷¦  «        ¦  «         |¦                     dø¦  «        r%t           	                    dù|r|j         nd¾¦  «         n³|¦                     dï¦  «        rž|rœ|ršt           	                    dú|j         ¦  «         | j         ×                    |¦  «        ƒ d{V —†}Ë|  %                    |¦  «         |  $                    |dû¬¦  «         |Ë�%|Ë}t          j        | j"        ||dü¬¦  «        ƒ d{V —† |¬pddýz   }¬t          j         ¦   «         }Ì|Êrng|<se|¦                     dþg ¦  «        }Í| j         Ø                    |j         dÿ|Ípg �t³          ¦   «         |j        r|j        j        nd|Ì�d œ¦  «        ƒ d{V —† |¦                     �d| j        du¦  «        }Î|Êr�n.|Ès|ÉrÄ�d|�|n|˜|�|n|Ì�dœ}Ï|jÚ        rt	          |jÚ        ¦  «        |Ï�d<   |jÚ        o7| j         Û                    |j         t	          |jÚ        ¦  «        ¦  «        ƒ d{V —†}Ð|Ðr)t           	                    �d|jÚ        |j         ¦  «         �n‘| j         Ø                    |j         |Ï|Î�¬¦  «        ƒ d{V —† �nf|¦                     �dt£          |<¦  «        ¦  «        }Ñt£          |¯¦  «        |Ñk    r
|¯|Ñd…         ng }Ò|ÒsŠ�d|�|n|˜|�|n|Ì�dœ}Ï|jÚ        rt	          |jÚ        ¦  «        |Ï�d<   | j         Ø                    |j         |Ï|Î�¬¦  «        ƒ d{V —† |¬r/| j         Ø                    |j         �d|¬|Ì�dœ|Î�¬¦  «        ƒ d{V —† n—d}Ó|ÒD ]’}Ô|Ô                     �d	¦  «        �d
k    rŒi |Ô¥d²|Ìi¥}Õ|ÓsA|Ô                     �d	¦  «        �dk    r&|jÚ        r�d|Õvrt	          |jÚ        ¦  «        |Õ�d<   d}Ó| j         Ø                    |j         |Õ|Î�¬¦  «        ƒ d{V —† Œ“| j         Ü                    |j        |¦                     dád=¦  «        �¬¦  «        ƒ d{V —† |  Ý                    ||j         ¦  «        ƒ d{V —† |®r#t           	                    �d|j         ¦  «         d}¬ta          |¦                     då¦  «        ¦  «        }Ö|  8                    |¦  «        }×|×duo*ta           t          |×�d�d„ ¦  «        ||¦  «        ¦  «        }Ø|Øs6|  Þ                    ||¬|¯|Ö�¬¦  «        r|  ß                    ||¬¦  «        ƒ d{V —† |¦                     då¦  «        rû|¦                     dí¦  «        sæ|¬r4|  8                    |¦  «        }Ù|Ùr|  à                    |¬||Ù¦  «        ƒ d{V —† |¼r–	 |  8                    |¦  «        }Ú|ÚrJ|Ú <                    |j        |¼|  =                    ||  c                    |¦  «        ¦  «        ¬:¦  «        ƒ d{V —† n3# t&          $ r&}³t                               �d|³¦  «         Y d}³~³nd}³~³ww xY w	 |  J                    |¦  «         dS |¬|  J                    |¦  «         S # t&          $ �rã}+	 |  8                    |¦  «        }Ût          �tc          |Û¦  «        d»d¦  «        }©t          �tc          |Û¦  «        d¼d¦  «        }ª|ÛrXtÙ          |©¦  «        rI|Û ²                    |j        |  =                    ||  c                    |¦  «        ¦  «        ¦  «        ƒ d{V —† n1|Ûr/tÙ          |ª¦  «        r |Û ³                    |j        ¦  «        ƒ d{V —† n# t&          $ r Y nw xY wt           á                    �d|¦  «         	 �d�tÅ          ¦   «         v �r|˜��
|��d}Ü	 | j         P                    |j         ¦  «        ƒ d{V —†}Ýn# t&          $ r g }ÝY nw xY w�tÇ          |Ý�dd…         ¦  «        D ]?}Þ|Þ                     �d	¦  «        �dk    r"|�|n|˜}ß|Þ                     �d¦  «        |ßk    }Ü nŒ@|Üsq�d|�|n|˜|�|nt          j         ¦   «         �dœ}Ït          |�dd¦  «        rt	          |jÚ        ¦  «        |Ï�d<   | j         Ø                    |j         |Ï¦  «        ƒ d{V —† n-# t&          $ r  t                               �dd¬¦  «         Y nw xY wd}àt          |+�dd¦  «        }á�d�tÅ          ¦   «         v rt£          |<¦  «        nd=}â|á�dk    r�d}à�n|á�dk    r�d}à�n|á�dk    rÎt          |+�dd¦  «        }ãi }ä	 |ã�?|ã ä                    ¦   «                              dîi ¦  «        }ät          |ätª          ¦  «        si }än# t&          $ r Y nw xY w|ä                     �d¦  «        �dk    rH|ä                     �d ¦  «        }å|år,|åd=k    r&d=dlå}æ|æ æ                    |å�d!z  ¦  «        }ç�d"|ç› �d#�}ànE�d$}ànA�d%}àn=|á�d&k    r�d'}àn2|á�d(v r-|âdók    r	 Y d}+~+|  J                    |¦  «         �d)S |á�d*k    r�d+}à�d,|à› �d-�cY d}+~+|  J                    |¦  «         S d}+~+ww xY w# |  J                    |¦  «         w xY w(/  zAInner handler that runs under the _running_agents sentinel guard.r­   r®   NéP   r  r™  r5
  r|  zSinbound message: platform=%s user=%s chat=%s msg=%r reply_to_id=%s reply_to_text=%rr¼  z1telegram topic recovery: chat=%s user=%s %r -> %srh  r¯   Úgateway_session_id©r2  r›  z%Failed to read Telegram topic bindingTrß   rN   z$compression-tip lookup failed for %szcompression-tip-walkr  z'Failed to record Telegram topic bindingÚwas_auto_resetFÚ
auto_resetÚis_fresh_resetzsession:start)r�   r¹  rN   r+   ÚprivacyÚ
redact_piiÚauto_reset_reasonÚidlery
  zy[System note: The user's previous session was stopped and suspended. This is a fresh conversation with no prior context.]Údailyz„[System note: The user's session was automatically reset by the daily schedule. This is a fresh conversation with no prior context.]Úresume_pending_expiredu·   [System note: The previous gateway session could not be recovered after a restart (API recovery timed out). This is a fresh conversation â€” use /resume to restore history if needed.]zy[System note: The user's previous session expired due to inactivity. This is a fresh conversation with no prior context.]r  r´  rµ  )r�   Úsession_typeÚreset_had_activity>   ry
  r%  z+previous session was stopped or interruptedz"gateway restart recovery timed outzdaily schedule at z:00rø  Úhzh rñ   zinactive for u!   â—� Session automatically reset (zŽ). Conversation history cleared.
Use /resume to browse and restore a previous session.
Adjust reset timing in config.yaml under session_reset.r.  z.Auto-reset notification failed (non-fatal): %sr€  r   )Ú_load_skill_payloadÚ_build_skill_messagerá  z[IMPORTANT: The "zB" skill is auto-loaded. Follow its instructions for this session.]z#[Gateway] Auto-skill '%s' not foundz0[Gateway] Auto-loaded skill(s) %s for session %sz-[Gateway] Failed to auto-load skill(s) %s: %srž  rË  )Ú	owner_keyr?  rÓ  r  )Úestimate_messages_tokens_roughrµ  zanthropic/claude-sonnet-4.6g333333ë?iˆ  r%   g     À‚@ç     Àr@r  rJ  r|  r  r  rm   rÓ  >   ro   rq   rr   Úhygiene_hard_message_limitÚhygiene_timeout_secondsÚhygiene_total_ceiling_secondsÚ hygiene_failure_cooldown_secondsrê  rÅ  rº  )r¸  r½  r¹  r¾  )r  rÅ  rÀ  r  çffffffî?ÚactualÚ	estimatedrR   rS   Ú get_compression_failure_cooldownÚremaining_secondszXSession hygiene: skipping compression for %s; previous failure cooldown active for %.1fsuf   Session hygiene: %s messages, ~%s tokens (%s) â€” auto-compressing (threshold: %s%% of %s = %s tokens)r¼  rv  )ÚCompressionCommitFence©r¨  c                 ó@   — g | ]}|                      d ¦  «        dv ¯|‘ŒS )r¦  >   rå  r¬  r­  rr  r_  s     r>   r  z<GatewayRunner._handle_message_with_agent.<locals>.<listcomp>ÞC  s8   € ð )ð )ð )Ø&'Ø#$§5¢5¨¡=¤=Ð4QÐ#QÐ#Qð !"Ø#QÐ#QÐ#QrM   zžSession hygiene could not restore the system prompt for session %s: %s. Preserving an empty prompt so the live turn rebuilds it with its configured providers.r¶  )r  r  r  Úskip_memoryr  rN   rX   rx  Úbind_session_statec                  ó   — d S r^   rN  )r  Úkws     r>   rò   z:GatewayRunner._handle_message_with_agent.<locals>.<lambda>D  s   € ÈD€ rM   c                  ó6   •— ‰                      ‰d‰ ‰¬¦  «        S )Nr®   )rH   Úcommit_fence)Ú_compress_context)Ú_approx_tokensÚ
_hyg_agentÚ_hyg_commit_fenceÚ	_hyg_msgss   €€€€r>   rò   z:GatewayRunner._handle_message_with_agent.<locals>.<lambda>%D  s(   ø€ °
×0LÒ0LØ,5°rØ:HØ9Jð 1Mñ 1*ô 1*€ rM   g{®Gázt?r  uƒ   Session hygiene compression for session %s still streaming after %.0fs (last progress %.1fs ago) â€” extending wait (ceiling %.0fs)gš™™™™™™?zsession hygiene timeoutrP
  zKsession hygiene compression timed out with no output from the summary model©r‡  z%session hygiene compression timed outz1hygiene compression timeout activity stamp failedz‡Session hygiene compression for session %s made no progress for %.1fs (total wait %.1fs, ceiling %.1fs); continuing without compressionu+   âš ï¸� Context compression timed out after ú.1fuÒ   s with no output from the summary model. No messages were dropped â€” continuing without compression. Run /compress to retry, /reset for a clean session, or check your auxiliary.compression model configuration.z9Failed to deliver compression-timeout warning to user: %szsession hygiene unwindr}  u©   Session hygiene: failed to persist compressed transcript for rotated session %s â†’ %s; keeping the live entry on the original session so the conversation is not droppedzhygiene-compressionuÎ   Gateway hygiene compression for session %s did not rotate or compact in place (no session_db on the hygiene agent) â€” preserving the original transcript instead of overwriting it with the summary (#21301).u>   Session hygiene: compressed %s â†’ %s msgs, ~%s â†’ ~%s tokensz3Session hygiene: still ~%s tokens after compressionÚ_last_compress_abortedrK   Ú_last_summary_errorz#session hygiene compression abortedz/hygiene compression abort activity stamp failedrÛ  rê   rì   u$   âš ï¸� Context compression aborted (u§   ). No messages were dropped â€” conversation is unchanged. Run /compress to retry, /reset for a clean session, or check your auxiliary.compression model configuration.z9Failed to deliver compression-failure warning to user: %sÚ_last_aux_model_failure_modelÚ_last_aux_model_failure_erroru%   â„¹ï¸� Configured compression model `z
` failed (u„   ). Recovered using your main model â€” context is intact â€” but you may want to check `auxiliary.compression.model` in config.yaml.z7Failed to deliver aux-model-fallback notice to user: %szsession hygienez(Session hygiene auto-compress failed: %szÁ[System note: This is the user's very first message ever. Briefly introduce yourself and mention that /help shows available commands. Keep the introduction concise -- one or two sentences max.])ÚPROFILE_BUILD_FLAGr  r  Úprofile_build_directiveÚprofile_build_modeÚaskr‹  z@Profile-build onboarding directive failed, using plain intro: %s)Ú
get_secretr•   r²  r  z/hermes sethomez/sethomeu    ðŸ“¬ No home channel is set for z^. A home channel is where Hermes delivers cron job results and cross-platform messages.

Type z8 to make this chat your home channel, or ignore to skip.rþ  rÛ  )Úcoerce_message_timestamprÝ  Ú strip_leading_message_timestampsrg  rà  z2Message timestamp injection failed (non-fatal): %sr›  r¡  )r�   r¹  r2  r›  r´  rN   r$  zagent:startÚ_moa_config)r$  r‹  rÙ  r(  rN   r+   r¼  r:  r´  ru  rt  rv  rÚ  Ú_stop_typing_with_metadataÚstop_typinguK   Discarding stale agent result for %s â€” generation %d is no longer currentr¿  Úpop_post_delivery_callbackr>  r@  rò  ©Ú#is_intentional_silence_agent_resultú(empty)uŽ   âš ï¸� The model returned no response after processing tool results. This can happen with some models â€” try again or rephrase your question.r(  rç  zMresponse ready: platform=%s chat=%s time=%.1fs api_calls=%d response=%d charsz&clear_resume_pending failed for %s: %srÖ  zagent-result-compressionz{Skipping agent-result session split sync for %s because the session binding moved from %s to %s before compression finishedrz	  r‡  rI  r†  )Úescape_code_fences_for_displayrJ  z
_... (z more lines)_rR  Úreasoning_styler/  Úsubtextc              3   ó(   K  — | ]}|rd |› �ndV — ŒdS )z-# z-#NrN  ©rb   Úlns     r>   rd   z;GatewayRunner._handle_message_with_agent.<locals>.<genexpr>KG  sB   è è € ð ,ð ,Ø;=¨"Ð6˜J "˜J˜J˜J°$ð,ð ,ð ,ð ,ð ,ð ,rM   u   -# ðŸ’­ Reasoning
Ú
blockquotec              3   ó(   K  — | ]}|rd |› �ndV — ŒdS )z> rž  NrN  r]  s     r>   rd   z;GatewayRunner._handle_message_with_agent.<locals>.<genexpr>PG  sB   è è € ð ,ð ,Ø9;¨Ð4˜I ˜I˜I˜I°ð,ð ,ð ,ð ,ð ,ð ,rM   u   > ðŸ’­ **Reasoning:**
u   ðŸ’­ **Reasoning:**
```
z
```

)Úbuild_footer_linery  rÒ  )rA  r?  r  Úcontext_tokensr|  rÑ  Úturn_secondszruntime_footer build failed: %sÚalready_sentz	agent:end)rJ  r  r  r*  rw  zProcess watcher setup error: %sú&Watch notification injection error: %szWatch queue drain error: %srÚ  rP   r�  c              3   ó    •K  — | ]}|‰v V — Œ	d S r^   rN  )rb   r;  Ú_err_str_for_classifys     €r>   rd   z;GatewayRunner._handle_message_with_agent.<locals>.<genexpr>¾G  s9   øè è € ð ð °a�qÐ1Ð1ð ð ð ð ð ð rM   )zcontext lengthzcontext sizezcontext windowzmaximum contextztoken limitztoo many tokenszreduce the lengthzexceeds the limitzrequest entity too largezprompt is too longzpayload too largezinput is too longrâ  rã  zjSkipping transcript persistence for context-overflow failure in session %s to prevent session growth loop.up   Transient agent failure in session %s â€” persisting user message so conversation context is preserved on retry.zLSuppressing hidden-reasoning-only incomplete gateway turn for session %s: %srê  r‚  uŸ   Compression deferred for session %s â€” the compression lock is held by a concurrent compressor. Keeping the session intact; the next message retries normally.z7Auto-resetting session %s after compression exhaustion.Úcompression_exhausted_resetzcompression-exhausted-resetu£   

ðŸ”„ Session auto-reset â€” the conversation exceeded the maximum context size and could not be compressed further. Your next message will start a fresh session.r»  rÞ  )r¦  r»  r  r�   rg  r‰  r¬  )r¦  r4  rg  rj  z:Skipping duplicate user turn (message_id=%s) in session %s)Úskip_dbr)  r­  r¦  rß  )ry  z5Suppressing intentional silence marker for session %sÚ_streaming_tts_turn_completedc                  ó   — dS ©NFrN  )Ú_ar"  s     r>   rò   z:GatewayRunner._handle_message_with_agent.<locals>.<lambda>ÌH  s   € Ðch€ rM   )rd  ztrailing footer send failed: %szAgent error in session %srÐ  iöÿÿÿr4  z<Failed to persist inbound user message after agent exceptionÚstatus_coderÙ  i‘  zH Check your API key or run `claude /login` to refresh OAuth credentials.i’  zG Your API balance or quota is exhausted. Check your provider dashboard.i­  rJ  rÎ   Úusage_limit_reachedÚresets_in_secondsrd  z9 Your plan's usage limit has been reached. It resets in ~zh.zG Your plan's usage limit has been reached. Please wait until it resets.z@ You are being rate-limited. Please wait a moment and try again.i  z= The API is temporarily overloaded. Please try again shortly.>   r  r¡  rä  r  z% The request was rejected by the API.z)Sorry, I encountered an unexpected error.ræ  rN  )çrU   rá   r�   r­   rw   rè   rl  rV   r3   rz  r)  r¹  r2  r  r  rf  r›  ri  r(  r2   r8
  rù  r+   rv   rx   r)  r  rÕ  rR   Úget_telegram_topic_bindingr4   r  rN   rú  rÏ  r]  r  rû  r  Ú
created_atró
  r  r¸  r½  r]  rz   Ú_set_session_envrs   rº   Ú_pinned_session_context_promptr_  r”   r›  Úget_reset_policyÚnotifyÚnotify_exclude_platformsr@  Úat_hourÚidle_minutesÚ_reset_notice_session_infor0  rî	  r"  rt   r½  r  r)  r*  rã   rf   Úacquirer„  rf  rh  Ú_clear_session_envr/   rJ  Úlease_tokenÚlease_generationr  Úload_transcriptr7   rË  r,  rµ  ru   rh  rw  rj  ry   ri  rC  r�  rÌ  r»  r˜  r¸  r½  ry  ru  Úagent.conversation_compressionr7  r	  r¨  r�  r½   Ú_GATEWAY_HYGIENE_PLATFORMÚcompression_in_placer/  rb
  Ú	_print_fnr!
  Úrun_in_executorr—  Úseconds_since_progressr  r–  r,  Úcommit_in_flightÚtry_cancel_before_commitr–  Ú"release_cancelled_compression_lockr_
  rZ   r?   Úagent.session_activityr‡  r‹  ÚAGENT_COMPRESSION_TIMEOUTrÓ  Úrevoke_commit_admissionÚrewrite_transcriptrP   Ú_rebind_turn_leaserË  rL   rB   ÚAGENT_COMPRESSION_COOLDOWNró   rë   rS
  Úhas_any_sessionsr<  rK  r  r  rL  rM  rl  rÄ  rt  rÓ  rf  r…  rO  r’   rÆ  r=
  rÆ  r¾  rÅ  rÏ  r/  Ú_voice_channel_sidecar_noter   rï  rÜ  rð  rP  rÝ  rQ  rÖ  Ú_set_pending_turn_sidecar_notesÚ_bind_adapter_run_generationÚ
_run_agentr´  rÚ  rÎ   rS  rT  Ú_is_session_run_currentrU  r@  rU  rì  Úgateway.response_filtersrW  rö  r}
  ré
  rð  r"  rÌ  rW  ru  Ú
MATTERMOSTr–  rY  rY  rT  rS  Úgateway.runtime_footerra  r“   r-  r+  rÎ  rí  r”  rt  rÓ  rÐ  rÊ  Ú_inject_watch_notificationr
  Úreset_sessionÚappend_to_transcriptr™  rj  Úhas_platform_message_idÚupdate_sessionÚ"_refresh_agent_cache_message_countÚ_should_send_voice_replyÚ_send_voice_replyÚ_deliver_media_from_responserÛ   r  r  r3  ÚmathÚceil)ír  rÖ  r(  r;  r¼  Ú_msg_start_timeÚ_platform_nameÚ_msg_previewÚ	_reply_idÚ
_reply_txtre  r\  r+   r  Úresolved_entryÚbindingÚbound_session_idÚcanonical_session_idr  Ú_was_auto_resetÚ_is_new_sessionrÙ   Ú_session_env_tokensÚ_redact_piirt  rv  Ú_pcfgr‹  Úturn_sidecar_notesÚreset_reasonrì  Úcontinuity_noterZ  r_  Úhad_activityÚshould_notifyr1  Úreason_textrý  rJ  r  r*  Úsession_infor¨  Ú_autoÚ_skill_namesr)  r*  Ú_combined_partsÚ_loaded_namesÚ_snamerƒ  Ú_loaded_skillÚ
_skill_dirÚ_display_nameræ  Ú_partÚ_lease_registryÚ_lease_tokenÚ_lease_staterÙ  r,  rµ  Ú
_hyg_modelÚ_hyg_threshold_pctÚ_hyg_compression_enabledÚ_hyg_hard_msg_limitÚ_hyg_timeout_secondsÚ_hyg_total_ceiling_secondsÚ_hyg_failure_cooldown_secondsÚ_hyg_config_context_lengthÚ_hyg_providerÚ_hyg_base_urlÚ_hyg_api_keyÚ_hyg_configured_modelÚ_hyg_configured_providerÚ_hyg_configured_base_urlÚ	_hyg_dataÚ
_model_cfgÚ_raw_ctxÚ	_comp_cfgÚ_raw_hard_limitrC
  Ú_raw_timeoutÚ_raw_ceilingÚ_raw_cooldownÚ_hyg_runtimer»  Ú_gw_gcpÚ_gw_gcclÚ_hyg_custom_providersÚ_hyg_custom_ctxÚ_hyg_context_lengthÚ_compress_token_thresholdÚ_warn_token_thresholdÚ
_msg_countÚ_stored_tokensÚ_token_sourceÚ_HARD_MSG_LIMITÚ_needs_compressrR   Ú_getterÚ_cooldown_stateÚ	_hyg_metar7  r¨  Ú_hyg_session_rowr<   Ú_hyg_session_dbÚ_hyg_cleanup_deferredÚ_bind_hyg_staterØ   Ú_hyg_futureÚ_hyg_wait_startedÚ_sliceÚ_compressedrK  Ú_hyg_waitedÚ_idleÚ
_cancelledr‡  Ú_timeout_msgr³  Ú_werrÚ_hyg_new_sidÚ_hyg_rotatedÚ_hyg_in_placeÚ
_new_countÚ_new_tokensÚ_compÚ_hyg_abortedr¥  rë   Ú	_warn_msgÚ
_aux_modelÚ_aux_errÚ_aux_msgÚ_intro_noterK  r  r  rL  rM  Ú_onb_cfgÚ_pb_errÚenv_keyÚhome_envrO  Ú_lgcÚprofÚsethome_cmdÚ_vc_noterÐ  Ú_get_evt_tzÚ_coerce_msg_tsr÷  Ú_strip_msg_tsÚ_evt_tzÚ_evt_tsÚ_clean_message_textÚ_embedded_tsÚ_event_epochÚ_ts_errrg  Ú_run_start_session_idÚ_turn_started_monotonicrØ  Ú_turn_secondsÚ_typing_adapterÚ_stop_with_metadataÚ_stop_typingÚ_stale_adapterrJ  rW  Ú_intentional_silenceÚagent_messagesÚ_response_timeÚ
_api_callsÚ	_resp_lenrÄ  Ú_show_reasoning_effectiver†  rY  rq  Údisplay_reasoningrS  Ú_reasoning_styleÚ_quotedÚ_footer_lineÚ_bflÚ_footer_errr+  rÜ  rî  r�
  Ú_prÚ_watch_eventsr¹  Ú
synth_textÚe2Úagent_failed_earlyÚhidden_reasoning_incompleteÚis_context_overflow_failureÚ	new_entryr²  Ú	tool_defsr‰  Ú_user_entryÚ_skip_persistr×  r9  Ú_user_msg_id_attachedr§  r®  Ú_already_sentÚ_stts_adapterÚ_streaming_tts_doneÚ_media_adapterÚ_foot_adapterÚ_err_adapterÚ_already_persistedÚ_recent_transcriptÚ_msgÚ_expected_user_contentÚstatus_hintrn  Ú	_hist_lenÚ	_err_bodyÚ	_err_jsonÚ
_resets_inr¡  Ú_hoursrA  rg  rB  rC  rD  sí                                                                                                                                                                                                                                           @@@@@r>   r"  z(GatewayRunner._handle_message_with_agentyA  sµG  øøøøøè è € åœ)™+œ+ˆÝ29¸&¼/È7Ñ2SÔ2SÐm˜œÔ.Ð.ÕY\Ð]cÔ]lÑYmÔYmˆØœ
Ð( b¨#¨2¨#Ô.×6Ò6°t¸SÑAÔAˆÝ˜EÐ#8¸$Ñ?Ô?ˆ	Ý˜e _°dÑ;Ô;ÐA¸rÀ3ÀBÀ3ÔG×OÒOÐPTÐVYÑZÔZˆ
Ý�ŠØaØ˜FÔ,ÐK°´ÐKÀ)ØŒNÐ'˜i¨°yÀ*ñ	
ô 	
ð 	
õ "Ô+¨DÔ,RÐTZÑ[Ô[Ð[Ð[Ð[Ð[Ð[Ð[ˆ	ØÐ Ý�KŠKØCØ” ¤°Ô0@À)ñô ð õ !Ô(¨¸9ÐEÑEÔEˆFðØ%�”�øÝð ð ð Ø�ðøøøð #Ô6×LÒLÈVÑTÔTÐTÐTÐTÐTÐTÐTˆØ#Ô/ˆÝÝ�U˜J¨Ñ-Ô-Ð3°×8Ò8Ð9MÑNÔNÐTÐRTñ
ô 
ç
Š%‰'Œ'ð 	ð ð 	+Ø#'×#IÒ#IØØ!ñ$ô $ð ð ð ð ð ð ˆNð Ð%Ø�Ø*ˆMØ×"Ò" ;°Ñ7Ô7Ð7ÝÔ" 4Ô#?ÀÑHÔHÐHÐHÐHÐHÐHÐHñ 8	[ðð Ô&ð1 Ô!1×!LÒ!LÝ ¤Ñ/Ô/Ý! &Ô"2Ñ3Ô3ð "Mñ "ô "ð ð ð ð ð ð ð ð -1ð �øõ ð ð ð Ý—’ÐDÈt�ÑTÔTÐTØ���ðøøøð ñ /[Ý#& w§{¢{°<Ñ'@Ô'@Ð'FÀBÑ#GÔ#GÐ ð $ð @¨Ô(8Ð(Dð	@Ø59Ô5E×5YÒ5YØ,ñ6ô 6ð 0ð 0ð 0ð 0ð 0ð 0Ð,Ð,øõ %ð @ð @ð @ÝŸšØBØ,°tð %ñ ô ð ð 0@Ð,Ð,Ð,ð@øøøð -ð@à0Ð4DÒDÐDà+?Ð(Ø#ð 1Ð(8¸MÔ<TÒ(TÐ(Tð &*Ô%=×%LÒ%LÈ[ÐZjÑ%kÔ%kÐkÐkÐkÐkÐkÐk�HØÐ+Ø(0˜ð %ðà(­C°·²¸LÑ0IÔ0IÐ0OÈRÑ,PÔ,PÒPÐPå!Ô+ØÔ9Ø Ð6Lðñ ô ð ð ð ð ð ð ð øð
[Ý!Ô+¨DÔ,OÐQWÐYfÑgÔgÐgÐgÐgÐgÐgÐgÐgÐgøÝ ð [ð [ð [Ý—L’LÐ!JÐUY�LÑZÔZÐZÐZÐZð[øøøõ
 " -Ð1AÀ5ÑIÔIˆØð 	1ð ×*Ò*¨;¸|Ð*ÑLÔLÐLð ×$Ò$ [Ñ1Ô1Ð1Ø+0ˆMÔ(ð Ô$¨Ô(@Ò@ð ?Øð?å�}Ð&6¸Ñ>Ô>ð 	õ �=Ð"2°EÑ:Ô:ð 	1Ø+0ˆMÔ(Øð 	Ø”*—/’/ /Ø5;´_ÐL˜FœOÔ1Ð1È"Ø!œ>Ø+Ô6Ø*ð	4ð 4ñ ô ð ð ð ð ð ð ð õ (¨°´¸]ÑKÔKˆð #×3Ò3°GÑ<Ô<Ðð ˆØ#ÐØ!%Ðð	Ý(Ñ*Ô*ˆEÝ §	¢	¨)Ñ 4Ô 4Ð :¸×?Ò?ÀÈeÑTÔTÑUÔUˆKˆKøÝð 	ð 	ð 	ØˆDð	øøøð ×<Ò<Ø�[ +ñ
ô 
ˆð )+Ðð ñ P	3Ý" =Ð2EÀtÑLÔLÐVÐPVˆLØ˜{Ò*Ð*ð  [��Ø Ò(Ð(ð  f��ØÐ!9Ò9Ð9ð  Y��ð  [�ð'Ý"?ÀÈvÑ"VÔ"V��øÝð 'ð 'ð 'Ø"&���ð'øøøàð GØ+¨fÑ4°ÑF�Ø×%Ò% lÑ3Ô3Ð3ð1RØÔ+Ô2×CÒCØ#œ_Ý!(¨°¸dÑ!CÔ!Cð Dñ ô �ð :@¼Ð P ¤Ô 5Ð 5Èb�Ý& }Ð6JÈEÑRÔR�ð
 !-Ð0WÐ Wð !Ø”Mð MØ$ðMà%¨VÔ-LÐLð ð
 !ð Ø"×6Ò6°vÑ>Ô>�GØð Ø'¨;Ò6Ð6Ø*W˜K˜KØ)Ð-EÒEÐEØ*N˜K˜KØ)¨WÒ4Ð4Ø*R¸v¼~Ð*RÐ*RÐ*R˜K˜Kà$*Ô$7¸2Ñ$=˜EØ#)Ô#6¸Ñ#;˜DØ:>Ð'p¨% { { { {Ð[`ÐDpÀuÐDWÐDWÐPTÐDWÐDWÐDWÐDWÐimÐfpÐfpÐfp˜HØ*D¸(Ð*DÐ*D˜KðWÀð Wð Wð Wð ð!Ý18Ô1BØ $Ô ?Àñ2ô 2ð ,ð ,ð ,ð ,ð ,ð ,˜Lð  ,ð GØ,2Ð)FÐ)F¸Ð)FÐ)F øøÝ(ð !ð !ð !Ø ˜Dð!øøøà%ŸlšlØ"œN¨FØ%)×%EÒ%EÀfÑ%MÔ%Mð +ñ ô ð ð ð ð ð ð ð øøõ ð Rð Rð RÝ—’ÐMÈqÑQÔQÐQÐQÐQÐQÐQÐQøøøøðRøøøð
 /3ˆMÔ+õ ˜˜|¨TÑ2Ô2ˆØñ 	a˜uñ 	aÝ&0°½Ñ&<Ô&<ÐM˜E˜7˜7Å$ÀuÁ+Ä+ˆLðaØZÐZÐZÐZÐZÐZÐZÐZØ-/�Ø+-�Ø*ð Vð V�FØ1Ð1°&À*ÐMÑMÔM�GØð VØCJÑ@˜ z°=ðJ°ð Jð Jð Jð ð !5Ð 4°]ÀJÐPUÑ VÔ V˜Ø ð 9Ø+×2Ò2°5Ñ9Ô9Ð9Ø)×0Ò0°Ñ8Ô8Ð8øåŸšÐ'LÈfÑUÔUÐUÐUØ"ð à#×*Ò*¨5¬:Ñ6Ô6Ð6Ø!'§¢¨_Ñ!=Ô!=�E”JÝ—K’KØJØ% {ñô ð øøõ ð að að aÝ—’ÐNÐP\Ð^_Ñ`Ô`Ð`Ð`Ð`Ð`Ð`Ð`øøøøðaøøøõ$ " $¨¸Ñ=Ô=ˆØÐ&ðØ%4×%<Ò%<Ø!Ô,Ø(Ø-Ý&Ø3Õ5Gñô ð	 &=ñ &ô &ð  ð  ð  ð  ð  ð  ��øõ )ð ð ð ð ×'Ò'Ð(;Ñ<Ô<Ð<Øðøøøð Ð'Ø#×2Ò2°:Ñ>Ô>ÔC�Ø+7�Ô(Ø0>�Ô-ð ×,Ò,¨U°MÔ4MÑNÔNÐNÐNÐNÐNÐNÐNÐNð Ô0×@Ò@ÀÔAYÑZÔZÐZÐZÐZÐZÐZÐZˆð" ñ \	•s˜7‘|”| qÒ(Ñ(ðð ð ð ð ð ð ð ð 7ˆJØ!%ÐØ'+Ð$Ø"&ÐØ#'Ð Ø).Ð&Ø,1Ð)Ø)-Ð&Ø ˆMØ ˆMØˆLØ$(Ð!Ø'+Ð$Ø'+Ð$ØˆIð|Ý0Ñ2Ô2�	Øñ ?%à!*§¢¨w¸Ñ!;Ô!;�JÝ! *­cÑ2Ô2ð KØ%/˜
˜
Ý# JµÑ5Ô5ð KØ%/§^¢^°IÑ%>Ô%>Ð%gÀ*Ç.Â.ÐQXÑBYÔBYÐ%gÐ]g˜
ð $.§>¢>Ð2BÑ#CÔ#C˜Ø#Ð/ð%Ý=@À¹]¼]Ð :Ð :øÝ$-­zÐ#:ð %ð %ð %Ø $ ð%øøøð )3¯ª°zÑ(BÔ(BÐ(JÀd˜Ø(2¯ª°zÑ(BÔ(BÐ(JÀd˜ð
 !*§¢¨m¸RÑ @Ô @�IÝ! )­TÑ2Ô2ñ (%Ý36Ø%ŸMšM¨)°TÑ:Ô:ñ4ô 4çš%™'œ'Ð%9ð4:Ð0ð +4¯-ª-Ð8TÑ*UÔ*U˜Ø*Ð6ð%Ý*-¨oÑ*>Ô*> Ø#*¨Q¢; ;Ø:AÐ$7øøÝ$-­zÐ#:ð %ð %ð %Ø $ ð%øøøà'0§}¢}Ð5NÑ'OÔ'O˜Ø'Ð3ð%Ý*/°Ñ*=Ô*= Ø#*¨Q¢; ;Ø;BÐ$8øøÝ$-­zÐ#:ð %ð %ð %Ø $ ð%øøøà'0§}¢}Ð5TÑ'UÔ'U˜Ø'Ð3ð%Ý*/°Ñ*=Ô*= Ø#*¨Q¢; ;ØAHÐ$>øøÝ$-­zÐ#:ð %ð %ð %Ø $ ð%øøøõ 69Ø6Ð8Lñ6ô 6Ð2ð )2¯ªÐ6XÑ(YÔ(Y˜Ø(Ð4ð%Ý*/°Ñ*>Ô*> Ø#*¨a¢< <ØDKÐ$AøøÝ$-­zÐ#:ð %ð %ð %Ø $ ð%øøøð )3Ð%Ø+8Ð(Ø+8Ð(ð
Ø/3×/RÒ/RØ%Ø$/Ý1;¸IÅtÑ1LÔ1LÐ$V I IÐRVð 0Sñ 0ô 0Ñ,�J ð
 %1×$4Ò$4°ZÑ$@Ô$@Ð$QÀM�MØ$0×$4Ò$4°ZÑ$@Ô$@Ð$QÀM�MØ#/×#3Ò#3°IÑ#>Ô#>Ð#NÀ,�L�LøÝ ð ð ð Ø�Dðøøøð .Ð9ð:Ø\Ð\Ð\Ð\Ð\Ð\à!?Ð!?Ø1Ø&Ø4Ø)Ø4Ø)ñ"ô "ð ð ð ð ð ð ð >ð :>Ð6øøÝ$ð :ð :ð :Ø59Ð2Ð2Ð2ð:øøøð .Ð5¸-Ð5ðð	;ðð ð ð ð ð ð ð ð 5<°G¸IÑ4FÔ4FÐ1Ð1øÝ(ð ;ð ;ð ;Ø4=·M²MÐBTÑ4UÔ4UÐ1Ý#-Ð.CÅTÑ#JÔ#Jð ;Ø8:Ð 5øøð;øøøð +3¨(Ø",Ø%2Ø-Bð+ñ +ô +˜ð
 +ð NÝ9<¸_Ñ9MÔ9MÐ6øøÝ%¥zÐ2ð ð ð Ø˜ðøøøøøåð ð ð Ø�ðøøøð (ñ A	Ø,JÐ,JØØ*Ð0¨bØ(Ð.¨BØ*DØ*Ð0¨bð-ñ -ô -ð 'ð 'ð 'ð 'ð 'ð 'Ð#õ -0Ø'Ð*<Ñ<ñ-ô -Ð)õ ),Ð,?À$Ñ,FÑ(GÔ(GÐ%å  ™\œ\�
ð "/Ô!A�Ø! AÒ%Ð%Ø%3�NØ$,�M�Mà%CÐ%CÀGÑ%LÔ%L�NØ$/�Mð* #6�à"Ð&?Ò?ð 5Ø! _Ò4ð  ð
 #ð 8õ #*¨$°¸tÑ"DÔ"D�KØ"Ð.Ý&-¨k¸5À+Ñ&NÔ&N˜Ý")¨+Ð7YÐ[_Ñ"`Ô"`˜Ø"Ð.ð7Ø29°'¸-Ô:RÑ2SÔ2S  øÝ#,ð 7ð 7ð 7Ø26   ð7øøøà.ð 8°?×3FÒ3FÐGZÐ\]Ñ3^Ô3^ÐabÒ3bÐ3bÝ &§¢ð%Qà$1Ô$<Ø$3Ð4GÔ$Hñ	!"ô !"ð !"ð 38 à"ñ wÝ—K’Kð>à" ~Ð$9Ð$9¸=ÝÐ.°Ñ4Ñ5Ô5Ø.Ð2Ð2Ø4Ð8Ð8ñô ð ð !%× @Ò @ÀÈ×IeÒIeÐfkÑIlÔIlÑ mÔ m�IðkØYÐYÐYÐYÐYÐYØ5Ð5Ð5Ð5Ð5Ð5à37×3VÒ3VØ#)Ø(3Ý5?À	Í4Ñ5PÔ5PÐ(Z¨	¨	ÐVZð 4Wñ 4ô 4Ñ0˜
 Lð
 (×+Ò+¨IÑ6Ô6ñ ]*ð)ð )Ø+2ð)ñ )ô )˜Iõ
  # 9™~œ~°Ò2Ñ2ð!&Ø=AÔ=M×=YÒ=YØ(5Ô(@ñ>&ô >&ð 8&ð 8&ð 8&ð 8&ð 8&ð 8&Ð$4Ð$4øõ (1ð 
!&ð 
!&ð 
!&Ø7;Ð$4Ý$*§N¢Nð)@ð )6Ô(@Ø(+Ø15ð %3ñ %&ô %&ð %&ð %&ð %&ð %&ð %&ð %&øøøøð
!&øøøõ 3:¸$Ô:JÈEÐSWÔScÑ2dÔ2d Ø-4¨Wñ 	."ð 	."Ø&2ð	."à*4Ø34Ø/3Ø04Ø6>°ZØ/<Ô/GØ/>ð	."ð 	."ð 	."ð 	." 
õ !<Ø$.Ø$4ñ!"ô !"ð !"õ 7P 
Ô 3Ø8=Ð 5ðj!*ð GK JÔ$CÝ6=Ý(/°
Ð<PÐRVÑ(WÔ(WØ(<Ø(,ñ7&ô 7& Oõ
 (0°Ñ'@Ô'@ð %*Ø(7¨Ø,;Ø,9Ô,Dñ)*ô )*ð )*ð HM JÔ$DØ;PÐ;P JÔ$8å+2Ô+CÑ+EÔ+E DØ8NÐ8NÑ8PÔ8PÐ$5Ø26×2FÒ2FØ(,ð)*ð )*ð )*ð )*ð )*ð )*ð )*ñ3&ô 3& Kða%.õ =A¼NÑ<LÔ<LÐ(9ð")6õ 69Ø0DØ2C×2ZÒ2ZÑ2\Ô2\ñ1]à05ñ6.ô 6.¨Fð
-6ÝGNÔGWÝ4;´NÀ;Ñ4OÔ4OØ<BðH2ñ H2ô H2ð B2ð B2ð B2ð B2ð B2ð B2±°¸Qð 16øÝ3:Ô3Gð -6ð -6ð -6Ý>B¼nÑ>NÔ>NÐQbÑ>b°Ø8I×8`Ò8`Ñ8bÔ8b°à49Ð<PÒ4PÐ4PØ8CÐF`Ò8`Ð8`å4:·K²Kð9Yð 9FÔ8PØ8CÀUØ8Rñ56ô 56ð 56ð 5=°HØ05ð#-6øøøñ 16øõ& ,3Ô+?ð _%2ñ _%2ð _%2Ø59¨
Ø.8Ð.@ð
 0AÔ/Qð -6Ø=B°
Ø05à0A×0ZÒ0ZÑ0\Ô0\ð -7ð 0:Ð/Aõ 7>´mÀEÑ6JÔ6JÐ0JÐ0JÐ0JÐ0JÐ0JÐ0JÐ0Jð# /9Ð.@ð$ 0:ð K)2ð DOÐ=NÐ=NÐ=NÐ=NÐ=NÐ=N©N¨K¸¹ð ->×,`Ò,`Ñ,bÔ,bÐ,bØ,0×,WÒ,WØ0;Ø0:Ø8Qð -Xñ -.ô -.ð -.ð
 EIÐ,AØ/LÐPQÒ/QÐ/QÝ0HØ48¸-Ô:RÝ4QØ8<¸kØ8Uñ56ô 56ð5Hñ	12ô 	12ð 	12ð-.ð -.ð -.ð -.ð -.ð -.õ -RØ0:Ø0WØ0BÔ0\ð1Hñ	-.ô -.ð -.õ -3¯NªNð1Qð 1>Ô0HØ0A×0XÒ0XÑ0ZÔ0ZÝ04´Ñ0@Ô0@ÐCTÑ0TØ0Jñ	-.ô 	-.ð 	-.ð1]Ø9MÐ0Uð1]ð 1]ð 1]ð -9ð-2Ø;?×;SÒ;SÐTZÑ;[Ô;[°Ø3;ð 16ÀÄð 16Ø:B¿-º-Ø8>¼Ø8DØAJð ;Hñ ;6ô ;6ð 56ð 56ð 56ð 56ð 56ð 56ð 56øøõ
 4=ð -2ð -2ð -2Ý06·²ð5Jà49ñ12ô 12ð 12ð 12ð 12ð 12ð 12ð 12øøøøð-2øøøð -2ðK :;¸öL ,9ð %.ð %.ð %.ð ):×(QÒ(QÑ(SÔ(SÐ(SØ/Dð )IØ,0×,WÒ,WØ0;Ø0:Ø8Pð -Xñ -.ô -.ð -.ð
 EIÐ,AØ(-ð#%.øøøð. 4>Ô3H LØ3?À=ÔC[Ò3[ LÝ48Ý(/°
Ð<WÐY^Ñ(_Ô(_ñ5&ô 5& Mð> (4ð %.Ø59Ô5M×5`Ò5`Ø,8¸+ñ6*ô 6*ð 0*ð 0*ð 0*ð 0*ð 0*ð 0*ð ).õ -3¯LªLð1Nð
 1>Ô0HØ0<ñ-.ô -.ð -.ð <A¨LØ<A¨M¨MàGS¨MÔ,Dð
 -1×,CÒ,CØ0:¸NÈLñ-.ô -.ð -.ð 37Ô2J×2PÒ2PÑ2RÔ2RÐ,RÐ,RÐ,RÐ,RÐ,RÐ,RÐ,RÝ29Ô2CØ04Ô0QØ06¸Ø7Lð3.ñ 3.ô 3.ð -.ð -.ð -.ð -.ð -.ð -.ð -.ð (4ð %*àKL¨Ô(HØ2=¨Ý58¸Ñ5EÔ5E¨
Ø6TÐ6TØ,7ñ7*ô 7*¨¨ð *7ð %*ð LM¨Ô(HØ2=¨Ý58¸Ñ5EÔ5E¨
Ø6TÐ6TØ,7ñ7*ô 7*¨¨ð 6@¨
Ø6D¨Ý(.¯ªð-[ð
 -:Ô,Dñ)*ô )*ð )*õ %+§K¢Kð)=à(2°JØ+9Ð(=Ð(=À+Ð?QÐ?Qñ	%&ô %&ð %&ð (3Ð6KÒ'KÐ'KÝ(.¯ªð-:à/:Ð,>Ð,>ñ)*ô )*ð )*õ -4°JÐ@TÐVZÑ,[Ô,[ EØ38ÀÐ3Dð 4&ÍØ(-Ð/GÈñJ&ô J& Lð ,8ð %.ö ,HØ4@Ø4@Ø5BØ6@Ø6@Ø:HØ7Bð,*ñ ,*ô ,*ð ).ö -JØ04°kñ-.ô -.ð -.ð (4ð D%.Ø+HÈAÒ+MÐ+MÝ,DØ04°mÔ6NÝ0MØ48¸+Ø4Qñ12ô 12õ 18Ø49Ð;PÐRVñ12ô 12ñ	-.ô 	-.ð 	-.ð)*ð )*ð )*ð )*ð )*ð )*õ )NØ,6Ø,QØ,>Ô,Yð-Dñ	)*ô )*ð )*õ 07°uÐ>SÐUYÑ/ZÔ/ZÐ/mÐ^m¨ð )WÐ(VÐ(VÐ(VÐ(VÐ(VØ/DÐ/DÀTÐQUÐ/VÑ/VÔ/V¨ð-=Ø04ð-=ð -=ð -=ð )2ð).Ø7;×7OÒ7OÐPVÑ7WÔ7W¨HØ/7ð -s¸F¼Nð -sØ6>·m²mÀFÄNÐT]Ðhq°mÑ6rÔ6rÐ0rÐ0rÐ0rÐ0rÐ0rÐ0rÐ0røøÝ/8ð ).ð ).ð ).Ý,2¯NªNØ0kØ05ñ-.ô -.ð -.ð -.ð -.ð -.ð -.ð -.øøøøð).øøøð */Ð):½wÀuÐNmÐosÑ?tÔ?tÐ):Ý5<¸UÐDcÐegÑ5hÔ5h¨
Ý3:¸5ÐBaÐcgÑ3hÔ3hÐ3{Ðl{¨ð-bÐT^ð -bð -bØ7?ð-bð -bð -bð )1ð).Ø7;×7OÒ7OÐPVÑ7WÔ7W¨HØ/7ð -r¸F¼Nð -rØ6>·m²mÀFÄNÐT\Ðgp°mÑ6qÔ6qÐ0qÐ0qÐ0qÐ0qÐ0qÐ0qÐ0qøøÝ/8ð ).ð ).ð ).Ý,2¯NªNØ0iØ05ñ-.ô -.ð -.ð -.ð -.ð -.ð -.ð -.øøøøð).øøøð %)×$<Ò$<¸[Ñ$IÔ$IÐ$IØ+@ð %*Ø.2×.TÒ.TØ,6Ð@Qð /Uñ /*ô /*ð )*ð )*ð )*ð )*ð )*ð )*ð )*øøð %)×$<Ò$<¸[Ñ$IÔ$IÐ$IØ+@ð %*Ø.2×.TÒ.TØ,6Ð@Qð /Uñ /*ô /*ð )*ð )*ð )*ð )*ð )*ð )*ð )*ð )*ð%*øøøøøõ
 %ð ð ð ÝŸšØFÈñô ð ð ð ð ð ð øøøøðøøøð ð #	7 TÔ%=×%NÒ%NÑ%PÔ%PÐPÐPÐPÐPÐPÐPð #	7ðNð ð7ðð ð ð ð ð ð ð ð ð ð ð ð ð õ 0Ñ1Ô1�à&Ð& xÑ0Ô0°EÒ9Ð9Ø#˜G HÐ.@ÑAÔAð :ð '×-Ò-Ð.EÐ.EÑ.GÔ.G×.MÒ.MÑ.OÔ.OÑPÔPÐPØ�Ižl¨]Ñ:Ð<NÑOÔOÐOÐOà&×-Ò-¨kÑ:Ô:Ð:øøÝð 7ð 7ð 7Ý—’ØVØñô ð ð #×)Ò)¨+Ñ6Ô6Ð6Ð6Ð6Ð6Ð6Ð6øøøøð7øøøð ñ 2	D˜6œ?ñ 2	D¨v¬Æ(Ä.Ò/PÑ/PÐU[ÔUdÖhpÔhxÒUxÑUxØ"œOÔ1ˆMÞ*¨=Ñ9Ô9ˆGð ˆHðØ9Ð9Ð9Ð9Ð9Ð9àBIÐQ˜J˜J wÑ/Ô/Ð5°2×<Ò<Ñ>Ô>Ð>Èr��øÝð ð ð Ø���ðøøøàð QØAHÐPžBœI gÑ.Ô.Ð4°"×;Ò;Ñ=Ô=Ð=Èb�ðØð % D¤K×$@Ò$@ÀÄÑ$QÔ$Qð %Ø$�HøøÝð ð ð Ø�ðøøøð ð ð
ØJÐJÐJÐJÐJÐJÝ# F¨I°tÑ<Ô<ÐBÀ×IÒIÑKÔK�DØð - ¨	Ò 1Ð 1ð !% ¡¤˜Ø ×1Ò1°&´/ÑBÔBð -Ø',˜HøøÝ ð ð ð Ø�Dðøøøàð Dð ”®(¬.Ò8Ð8ð &Ð%à#ð ð*°}×7JÒ7JÑ7LÔ7Lð *ð *ð (ð*ð *ð *ð ð ×3Ò3°F¸FÑCÔCÐCÐCÐCÐCÐCÐCÐCð ×3Ò3°E¸6À;ÑOÔOˆØð 	0Ø×%Ò% hÑ/Ô/Ð/ð "×NÒNØØØØ#ð	 Oñ 
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ˆð ÐØˆFð	XØ?Ð?Ð?Ð?Ð?Ð?ðð ð ð ð ð ð ð ð ð ð
 "�k‘m”mˆGÝ˜e [°$Ñ7Ô7ˆGØð 7¥
¨<½Ñ =Ô =ð 7Ø4A°MØ  Wð5.ñ 5.ô 5.Ñ1Ð# \à':Ð$Ø-˜~¨g¸'ÐBÑBÔB�à$0Ð$<�L�LÀ,ð 'ö /Õ/CÑ/EÔ/EÑFÔFð 	7Ø#1 >Ø+Ø.Ø"ð$ñ $ô $�L�Lð $7�LøøÝð 	Xð 	Xð 	XÝ�LŠLÐMÈwÑWÔWÐWÐWÐWÐWÐWÐWøøøøð	Xøøøð ð 	R +ð 	RØ×0Ò0°Ð>PÑQÔQÐQð
 	×)Ò)Ø×$Ò$ VÑ,Ô,ØØñ	
ô 	
ð 	
ð~	9ð 6<´_ÐL˜FœOÔ1Ð1È"Ø!œ>Ø!œ>Ð/¨RÝHOÐPVÐXcÐeiÑHjÔHjÐr�S¥¨°¸dÑ!CÔ!CÑDÔDÐDÐprÝ$ V¨[¸"Ñ=Ô=ÐCÀØ+Ô6Ø'¨¨¨Ô-ðð ˆHð ”*—/’/ -°Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:ð %2Ô$<Ð!Ý&*¤nÑ&6Ô&6Ð#Ø!%§¢Ø$Ø-ØØØ0Ø'Ø-Ø!%×!=Ò!=¸eÑ!DÔ!DØ$Ô3Ý" 5¨-¸Ñ>Ô>Ø%9Ø'=Ø"Ô/ð "1ñ "ô "ð ð ð ð ð ð ˆLõ !œNÑ,Ô,Ð/FÑFˆMð
Ø"&×":Ò":¸6Ñ"BÔ"B�Ý&-Þ˜Ñ)Ô)Ð+GÈñ'ô 'Ð#õ  '¦t¨OÑ'<Ô'<¸mÈTÑRÔR�Ø"ð F¥xÐ0CÑ'DÔ'Dð FØ)×DÒDØœØ×8Ò8Ø" D×$@Ò$@ÀÑ$GÔ$Gñô ñô ð ð ð ð ð ð ð ð ð %ð F­°,Ñ)?Ô)?ð FØ)×5Ò5°f´nÑEÔEÐEÐEÐEÐEÐEÐEÐEøøÝð ð ð Ø�ðøøøð ×/Ò/°
¸NÑKÔKð Ý—’ØaØÐ% #Ø"ñô ð ð
 "&×!9Ò!9¸&Ñ!AÔ!A�Ýž4 Ñ/Ô/Ð1MÈtÑTÔTÐ`Ø"×=Ò=Ø"Ø#1ð >ñ ô ð ð ð $ð R­°Ð@ZÑ([Ô([ð RØ"Ô;×?Ò?À
ÈDÑQÔQÐQØðn ×#Ò#Ð$7Ñ8Ô8Ð8Ð8Ð8ðk $×'Ò'Ð(8Ñ9Ô9Ð?¸RˆHö <¸LÑIÔIð Ø�ð-ØXÐXÐXÐXÐXÐXØ'JÐ'JØ  (ñ(ô (Ð$Ð$øõ ð -ð -ð -Ø',Ð$Ð$Ð$ð-øøøð ˜9Ò$Ð$Ð-AÐ$ð.ð ð
 *×-Ò-¨j¸"Ñ=Ô=ˆNÝ!œY™[œ[¨?Ñ:ˆNØ%×)Ò)¨+°qÑ9Ô9ˆJÝ˜H™œˆIÝ�KŠKØ_Ø ¤Ð ;°)Ø 
¨Iñô ð ð* ð ÖFÀ|ÑTÔTð Ø×1Ò1°+Ñ>Ô>Ð>ðØÔ2×GÒGÈÑTÔTÐTÐTÐTÐTÐTÐTÐTÐTøÝ ð ð ð Ý—L’LØ@Ø# Rñô ð ð ð ð ð ð øøøøðøøøð (ð WÞ:Ø  (½¸G¹¼ðñ ô �ö <¸F¼OÈXÑVÔV�ð ×Ò Ñ-Ô-ð °,¸|Ô2LÐP]ÔPhÒ2hÐ2hØ Ô+Ð/DÒDÐDØ/;¸LÔ/I�MÔ,ð
 ×+Ò+Ø" N°MÔ4Lñô ð ð Ô2×8Ò8Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:ØÔ2×OÒOØ%Ô0Ø#Øñô ð ð ð ð ð ð ð õ
 "Ô+ØÔ9Ø Ð6Pðñ ô ð ð ð ð ð ð ð ð õ
 —K’Kð/ð $Ð* sØ-Ø%Ô0ñô ð ðÞ,IÝ(Ñ*Ô*Þ(¨¬Ñ9Ô9Ø$Ý ¥¨Ð/@À%Ñ!HÔ!HÑIÔIØ#œ_Þ3;Ô3FÐ2Gð-ñ -ô -Ð)Ð)øõ ð ð ð ð ”®(Ô*=Ò=Ð=ð �Eå  Ð'8¸%Ñ@Ô@ð *Ð)Ð)ðøøøð )ñ &g¨Xñ &gÐ>Rñ &gØ!-×!1Ò!1Ð2BÑ!CÔ!C�Ø!ñ $gØVÐVÐVÐVÐVÐVà*×0Ò0Ñ2Ô2×=Ò=Ñ?Ô?�EÝ˜5‘z”z B’�Ø,0¯IªI°e¸C¸R¸C´jÑ,AÔ,AÐ)Ø)Ð-V½¸E¹
¼
ÀR¹Ð-VÐ-VÐ-VÑVÐ)Ð)à,:×,@Ò,@Ñ,BÔ,BÐ)ð	2ØRÐRÐRÐRÐRÐRØ+BÐ+BÝ0Ñ2Ô2Þ0°´ÑAÔAØ-Ø"ñ	,ô ,Ð(Ð(øõ %ð 2ð 2ð 2Ø+1Ð(Ð(Ð(ð2øøøà'¨9Ò4Ð4Ø"&§)¢)ð ,ð ,ØAR×A]ÒA]ÑA_ÔA_ð,ñ ,ô ,ñ #ô #˜ð $Q¸Ð#PÐ#PÀhÐ#PÐ#P˜˜Ø)¨\Ò9Ð9Ø"&§)¢)ð ,ð ,Ø?P×?[Ò?[Ñ?]Ô?]ð,ñ ,ô ,ñ #ô #˜ð $U¸WÐ#TÐ#TÈ(Ð#TÐ#T˜˜ð -KÐ,JÐK\Ñ,]Ô,]Ð)Ø#fÐ@QÐ#fÐ#fÐ\dÐ#fÐ#f˜ð ˆLð"ØLÐLÐLÐLÐLÐLØ#˜tÝ 4Ñ 6Ô 6Þ!5°f´oÑ!FÔ!FØ&×*Ò*¨7Ñ3Ô3Ø#/×#3Ò#3Ð4HÈ!Ñ#LÔ#LÐ#QÐPQØ#/×#3Ò#3Ð4DÑ#EÔ#EÐ#MÈÞœ
Ÿš ~°rÑ:Ô:Ø!.ð ñ  ô  ��øõ ð "ð "ð "Ý—’Ð>ÀÑLÔLÐLØ!������øøøøð"øøøð ð ; ð ;°×1AÒ1AÀ.Ñ1QÔ1Qð ;ÐZnð ;Ø&Ð:Ð:¨LÐ:Ð:�ð ”*—/’/ +ð 0Øð0à%˜^¨¨T¨c¨TÔ2Ø%×)Ò)¨'°2Ñ6Ô6Ø(×,Ò,¨Z¸Ñ<Ô<ð	0ð 0ð 0ñ ô ð ð ð ð ð ð ð ðCØCÐCÐCÐCÐCÐCð ,Ô<�Ø46Ð Ô1Þ"+¨HÑ"5Ô"5ð /ð /‘J�A�wÝÔ'¨×(AÒ(AÀ'Ñ(JÔ(JÑKÔKÐKØ˜3‘w "’}�}Ý%œm¨AÑ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.øð/øõ ð Cð Cð CÝ—’Ð>ÀÑBÔBÐBÐBÐBÐBÐBÐBøøøøðCøøøð?ØJÐJÐJÐJÐJÐJÞ ;¸CÔ<PÑ QÔ Q�Ø(ð Wð W�CÞ!EÀcÑ!JÔ!J�JØ!ð WðWØ"&×"AÒ"AÀ*ÈcÑ"RÔ"RÐRÐRÐRÐRÐRÐRÐRÐRøÝ(ð Wð Wð WÝ"ŸLšLÐ)QÐSUÑVÔVÐVÐVÐVÐVÐVÐVøøøøðWøøøðWðWøõ ð ?ð ?ð ?Ý—’Ð:¸AÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>øøøøð?øøøõ2 "& l×&6Ò&6°xÑ&@Ô&@Ñ!AÔ!AÐÞ*VØñ+ô +Ð'õ %(¨×(8Ò(8¸À"Ñ(EÔ(EÑ$FÔ$F×$LÒ$LÑ$NÔ$NÐ!ð
 +=ð 
+Ý�\×%Ò%Ð&=Ñ>Ô>Ñ?Ô?ð JÞð ð ð ð ð <ð ñ ô ñ ô ðJð Ð2Ð2ÐHµs¸7±|´|ÀbÒ7Hð (ð +ð Ý—’ðLà!Ô,ñô ð ð ð
 $ð Ý—’ðMà!Ô,ñô ð ð ð
 -ð Ý—’ð)à!Ô,Ø ×$Ò$ WÐ.EÑFÔFñ	ô ð ð" ×ÒÐ 6Ñ7Ô7ð *Ý—’ðIð 1>ÐF�MÔ,Ð,À3ñ	ô ð ð ð ×!Ò!Ð"9Ñ:Ô:ð #¸}ð #ÐQ\ð #Ý—’ØMØ!Ô,ñô ð ð #'Ô":×"HÒ"HÈÑ"UÔ"UÐUÐUÐUÐUÐUÐU�	Ø×(Ò(¨Ñ5Ô5Ð5ð ×.Ò.ØÐ(Eð /ñ ô ð ð Ð(ð %.�MÝ!Ô+ØÔ9Ø Ð6Sðñ ô ð ð ð ð ð ð ð ð %˜N¨ðDñ�õ ”‘”ˆBð
 +ð ØØð Ø(×,Ò,¨W°bÑ9Ô9�	ØÔ.×CÒCØ!Ô,à .Ø!* ¨bÞ!7Ñ!9Ô!9Ø=C¼_Ð$T F¤OÔ$9Ð$9ÐRTØ%'ñð ñ	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð* +×.Ò.Ñ/@À$ÔBRÐZ^ÐB^Ñ_Ô_ˆOð +ð eÙØ#ð cÐ'Bð cñ #ð 0Ð;ð -Ð,à)ð 2Ð=ð /Ð.àñð �ð Ô#ð FÝ03°EÔ4DÑ0EÔ0E�K¡Ñ-ð
 Ô$ð Ø"Ô6×NÒNØ%Ô0µ#°eÔ6FÑ2GÔ2Gñô ð ð ð ð ð ð ð ð !ð Ý—K’Kñ8àÔ(¨-Ô*Bñô ð ñ ð Ô2×GÒGØ%Ô0Ø#Ø /ñ Hñ ô ð ð ð ð ð ð ð ñ ð +×.Ò.Ñ/?ÅÀWÁÄÑNÔN�Ý?BÀ>Ñ?RÔ?RÐU`Ò?`Ð?`˜~¨k¨l¨lÔ;Ð;Ðfh�ð $ð 2á &ð  4Ð?ð 1Ð0à!-ð  6ÐAð 3Ð2à!#ñ#ð #�Kð Ô'ð JÝ47¸Ô8HÑ4IÔ4I˜¡LÑ1ØÔ2×GÒGØ%Ô0Ø#Ø /ñ Hñ ô ð ð ð ð ð ð ð ð
  ð Ø"Ô6×KÒKØ)Ô4Ù%0¸XÐTVÑWÐWØ$3ñ Lñ ô ð ð ð ð ð ð ð øð -2Ð)Ø+ð ð ˜àŸ7š7¡6™?œ?©hÒ6Ð6Ø$à 8 3Ð 8¨°RÐ 8Ð 8˜à 5ð9à #§¢©¡¤±6Ò 9Ð 9Ø %Ô 0ð !:á ,°EÐ 9Ð 9å25°eÔ6FÑ2GÔ2G˜E¡,Ñ/Ø48Ð1Ø"Ô6×KÒKØ)Ô4°eØ$3ñ Lñ ô ð ð ð ð ð ð ð ð ð Ô*×9Ò9ØÔ)Ø#/×#3Ò#3Ð4HÈ!Ñ#LÔ#Lñ :ñ ô ð ð ð ð ð ð ð ð. ×9Ò9Ø˜]Ô5ñô ð ð ð ð ð ð ð ð $ð Ý—’ÙKØ!Ô,ñô ð ð �õ ! ×!1Ò!1°.Ñ!AÔ!AÑBÔBˆMà ×4Ò4°VÑ<Ô<ˆMà TÐ)ð HÝÐi� Ñ0OÑQhÐQhÑiÔiÐjuð  xFñ  Gô  Gñ  Hô  Hð  ð
 (ð>à×1Ò1°%¸À>Ð`mÑ1ÑnÔnð>ð ×,Ò,¨U°HÑ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=ð ×Ò Ñ/Ô/ð ¸×8HÒ8HÈÑ8RÔ8Rð Øð Ø%)×%=Ò%=¸fÑ%EÔ%E�NØ%ð Ø"×?Ò?Ø$ e¨^ñô ð ð ð ð ð ð ð ð  ð 
Lð	LØ(,×(@Ò(@ÀÑ(HÔ(H˜Ø(ð Ø"/×"4Ò"4Ø &¤Ø ,Ø)-×)IÒ)IÈ&ÐRV×RnÒRnÐotÑRuÔRuÑ)vÔ)vð #5ñ #ô #ð ð ð ð ð ð ð øøõ
 %ð Lð Lð LÝŸšÑ%FÈÑKÔKÐKÐKÐKÐKÐKÐKøøøøðLøøøàðn ×#Ò#Ð$7Ñ8Ô8Ð8Ð8Ð8ðk ðj ×#Ò#Ð$7Ñ8Ô8Ð8Ð8øõg ð p	ñ p	ð p	ðØ#×7Ò7¸Ñ?Ô?�Ý&-Þ˜Ñ&Ô&Ð(DÀdñ'ô 'Ð#õ  '¦t¨LÑ'9Ô'9¸=È$ÑOÔO�Øð C¥HÐ-@Ñ$AÔ$Að CØ&×AÒAØœØ×8Ò8Ø" D×$@Ò$@ÀÑ$GÔ$Gñô ñô ð ð ð ð ð ð ð ð ð "ð C¥h¨|Ñ&<Ô&<ð CØ&×2Ò2°6´>ÑBÔBÐBÐBÐBÐBÐBÐBÐBøøÝð ð ð Ø�ðøøøå×ÒÑ8¸+ÑFÔFÐFð%lÙ!¦V¡X¤XÐ-Ñ-°,Ñ2JÈ}ÑOhØ).Ð&ð0Ø37Ô3K×3[Ò3[Ð\iÔ\tÑ3uÔ3uÐ-uÐ-uÐ-uÐ-uÐ-uÐ-uÐ*Ð*øÝ$ð 0ð 0ð 0Ø-/Ð*Ð*Ð*ð0øøøæ (Ð);¹C¸D¸DÔ)AÑ BÔ Bð "ð "˜ØŸ8š8¡FÑ+Ô+©vÒ5Ð5ð $8Ð#Cð !5Ð 4à%1ð 3ð
 37·(²(¹9Ñ2EÔ2EÐI_Ò2_Ð.Ø!˜Eð 6ð .ð á$*ð $8Ð#Cð !5Ð 4à%1ð $:Ð#Eð !7Ð 6å%)¤Y¡[¤[ñ'ð '˜õ # 5©,¸Ñ=Ô=ð NÝ8;¸EÔ<LÑ8MÔ8M˜K©Ñ5Ø"Ô6×KÒKØ)Ô4Ø'ñô ð ð ð ð ð ð ð øøõ ð lð lð lÝ—’Ñ[Ðfj�ÑkÔkÐkÐkÐkðløøøð ˆKÝ! !¡]°DÑ9Ô9ˆKÙ(1¶V±X´XÐ(=Ð(=�˜G™œ˜À1ˆIØ™cÒ!Ð!Ùh�‘Ø¡Ò#Ð#Ùg�‘Ø¡Ò#Ð#å# A¡z°4Ñ8Ô8�	Ø�	ðØ Ð,Ø$-§N¢NÑ$4Ô$4×$8Ò$8¸À"Ñ$EÔ$E˜	Ý)¨)µTÑ:Ô:ð +Ø(*˜IøøÝ ð ð ð Ø�Dðøøøà—=’=¡Ñ(Ô(Ñ,AÒAÐAØ!*§¢Ñ/BÑ!CÔ!C�JØ!ð p j°1¢n nØ#˜˜˜Ø!%§¢¨:¹Ñ+<Ñ!=Ô!=˜Ù&lÐbhÐ&lÑ&lÐ&l˜˜á&o˜˜á"d�K�KØ¡Ò#Ð#Ù]��Ø¡
Ð*Ð*ð ˜r’>�>ð1ðð ð ð ð ×#Ò#Ð$7Ñ8Ô8Ð8Ñ8Ð8ð !¡CÒ'Ð'Ù"I�KñD¸Kð Dñ Dð Dðð ð ð ð ð ×#Ò#Ð$7Ñ8Ô8Ð8Ð8øøøøðgp	øøøøðf ×#Ò#Ð$7Ñ8Ô8Ð8Ð8øøøs~  ÅE Å
E%Å$E%È2AJ Ê(J-Ê,J-Ë! L Ì)L.Ì-L.Î<!O Ï&PÐPÔAU	 Õ	
UÕUÖ&V7 Ö7W×W×)C#\> Û)[7 Û6\> Û7
\Ü\> Ü\Ü9\> Ü>
]-Ý](Ý(]-Þ6Cb
 â

b:âb5â5b:ã7d	 ä	!d*çBv( é3j êv( êjêv( êjêB+v( ím ív( ím/í,v( í.m/í/v( î
n" î!v( î"n6î3v( î5n6î6v( ïo) ï(v( ï)o=ï:v( ï<o=ï=*v( ð(q  ð?v( ñ qñv( ñqñ	v( ñA7s óv( ó
s#ó v( ó"s#ó#v( ó)t ôv( ôtôv( ôtôv( ô t4 ô3v ô46u-õ*v õ,u-õ-"v öv( öv$ö!v( ö#v$ö$v( ö(
v5ö4v5ù1z úzúzü<A4A^. þ1% ÿA^. ÿ
A@ÿ!%A@Á@A^. Á@A@Á@AA^. ÁA&BA]3 ÁC69AG ÁD01AE" ÁE!AG ÁE"A(AGÁG
AG ÁGAGÁGAG ÁGA]3 ÁGD&AN-ÁK:AAL<ÁL;AN-ÁL<
AM+ÁMAM&ÁM!AN-ÁM&AM+ÁM+AN-ÁM/A]3 ÁM1<AN-ÁN-I'A]3 ÁXAAY ÁYA]3 ÁY
AZÁY!AZÁY<A]3 ÁZAZÁZAA]3 Á[
AA\ Á\A]3 Á\
A\;Á\A\6Á\1A]3 Á\6A\;Á\;A]3 Á\>5A^. Á]37A^*Á^*A^. Á^.
A_Á^8A_Á_A_Á`BAb Áb
AcÁb 0AcÁcAcÁd5)Ae ÁeAe.Áe-Ae.Áf!#Ag Ág
AgÁgAgÁgAAh2 Áh2
Ah?Áh>Ah?Ák'BAm< Ám<
An+ÁnAn&Án&An+Áo3DBt4 ÁtCAw. Áw-Bt4 Áw.
Aw;Áw8Bt4 Áw:Aw;Áw;B0Bt4 Á{)Bt4 Á{-A|  Á{?Bt4 Á| A|Á|Bt4 Á|A|Á|B+Bt4 Á~; A ÁBt4 Á
B@Á&B@Â@Bt4 Â@B@Â@D#Bt4 ÂD0A"BF ÂFBt4 ÂF3BG	ÂGBt4 ÂGBG	ÂG	B.Bt4 ÂI83BJ, ÂJ+Bt4 ÂJ,BJ;ÂJ8Bt4 ÂJ:BJ;ÂJ;BBt4 ÂMBBO) ÂO(Bt4 ÂO)
BPÂO3BPÂPBt4 ÂPBPÂPB Bt4 ÂRA4BT ÂTBt4 ÂT
BT?ÂTBT:ÂT5Bt4 ÂT:BT?ÂT?Bt4 ÂU1BW ÂU5BVÂVBW ÂV
BWÂVBV<ÂV7BW ÂV<BWÂWBW ÂWBt4 ÂW
BW5ÂWBW0ÂW+Bt4 ÂW0BW5ÂW5Y:Bt4 Âq0A!Bs ÂsBt4 Âs
BtÂsBs=Âs8Bt4 Âs=BtÂtBt4 ÂtBt4 Ât4CD"Âu CBxÂxCDÂx
Bx,Âx)CDÂx+Bx,Âx,CDÂyB}-Ây(%BzÂzB}-ÂzBzÂzB}-ÂzBzÂzCB}-Â},CDÂ}-'B~Â~CDÂ~B~Â~A-CDÃ@ACAÃACDÃA
CAÃACDÃACAÃABCDÃCCD% ÃC1CDÃDCD"ÃDCD% ÃDCD"ÃD"CD% ÃD%CD<c                 ó  — t          t          | dd¦  «        dd¦  «        rNt          |                      |¦  «        ¦  «        5  |                      ¦   «         cddd¦  «         S # 1 swxY w Y   |                      ¦   «         S )uÓ  Session-info block for the auto-reset notice, profile-scoped.

        When multiplexing, resolve model/provider/context inside the profile
        serving ``source`` â€” otherwise the banner advertises the base config's
        model while the session actually runs on the profile's (#59003).
        Mirrors ``_run_agent``'s gating so single-profile gateways never
        enter the scope.

        Call via ``asyncio.to_thread`` from async handlers: under the scope,
        resolution can do blocking work (credential refresh, context-length
        HTTP probes) that must not run on the event loop. The scope is entered
        inside this method, so contextvars behave correctly in the worker
        thread.
        rz   Nr½  F)rV   rº  rÿ  Ú_format_session_inforX  s     r>   rz  z(GatewayRunner._reset_notice_session_infonI  s¼   € õ •7˜4 ¨4Ñ0Ô0Ð2FÈÑNÔNð 	3Ý'¨×(MÒ(MÈfÑ(UÔ(UÑVÔVð 3ð 3Ø×0Ò0Ñ2Ô2ð3ð 3ð 3ð 3ñ 3ô 3ð 3ð 3ð 3ð 3ð 3ð 3øøøð 3ð 3ð 3ð 3à×(Ò(Ñ*Ô*Ð*s   ÁA$Á$A(Á+A(c                 ó^  — ddl m}m} t          ¦   «         }d}d}d}d}d}d}	d}
d}d}	 t	          ¦   «         }	|	rþ|	                     di ¦  «        }t          |t          ¦  «        r›|                     d¦  «        p|                     d¦  «        }
|                     d¦  «        }|�(	 t          |¦  «        }n# t          t          f$ r Y nw xY w|                     d¦  «        pd}|                     d¦  «        pd}|}|}	 dd	lm}  ||	¦  «        }n%# t          $ r |	                     d
¦  «        }Y nw xY wn# t          $ r Y nw xY w	 t          ¦   «         }|                     d¦  «        p|}|                     d¦  «        p|}|                     d¦  «        }n# t          $ r Y nw xY w|�,	 ddlm}  ||
|||||¦  «        rd}n# t          $ r d}Y nw xY w|€.|r,|r*	 ddlm}  ||||¬¦  «        }|r|}n# t          $ r Y nw xY w |||pd|pd||pd|¬¦  «        }|�d}n||k    rd}nd}|dk    r
|dz  d›d�}n|dk    r	|dz  › d�}nt%          |¦  «        }d|› d�d|pd› �d|› d|› d�g}|r$d |v sd!|v sd"|v r|                     d#|› �¦  «         d$                     |¦  «        S )%a  Resolve current model config and return a formatted info block.

        Surfaces model, provider, context length, and endpoint so gateway
        users can immediately see if context detection went wrong (e.g.
        local models falling to the 128K default).
        r   )Úget_model_context_lengthÚDEFAULT_FALLBACK_CONTEXTNr  rJ  r|  r  r  r·  r¹  rÅ  )Úshould_clear_context_pinr¼  r¾  r®   r¿  rz   u:   default â€” set model.context_length in config to overrideÚdetectedi@B rF  ÚMiè  ÚKu   â—† Model: `r  u   â—† Provider: Ú
openrouteru   â—† Context: z	 tokens (rŠ  Ú	localhostz	127.0.0.1z0.0.0.0u   â—† Endpoint: r  )rË  rF  rG  r™  rs   rv   rt   ru   rh  rw  rj  r˜  r¸  r2   rÅ  rÌ  rH  r½  rw   r”   rf   )r  rF  rG  r  rÀ  r  r  rÅ  Úcustom_provsrî  Úconfigured_modelÚconfigured_providerÚconfigured_base_urlrÂ  Úraw_ctxr¸  r¿  rH  r½  Ú
custom_ctxr|  Ú
ctx_sourceÚctx_displayrq  s                           r>   rD  z"GatewayRunner._format_session_info‚I  sf  € ð 	\Ð[Ð[Ð[Ð[Ð[Ð[Ð[å&Ñ(Ô(ˆØ $ÐØˆØˆØˆØˆØˆØÐØ"ÐØ"Ðð	Ý'Ñ)Ô)ˆDØð @Ø ŸHšH W¨bÑ1Ô1�	Ý˜i­Ñ.Ô.ð 3Ø'0§}¢}°YÑ'?Ô'?Ð'YÀ9Ç=Â=ÐQXÑCYÔCYÐ$Ø'ŸmšmÐ,<Ñ=Ô=�GØÐ*ð!Ý47¸±L´LÐ1Ð1øÝ )­:Ð6ð !ð !ð !Ø ˜Dð!øøøà(Ÿ}š}¨ZÑ8Ô8Ð@¸D�HØ(Ÿ}š}¨ZÑ8Ô8Ð@¸D�HØ*2Ð'Ø*2Ð'ð@ØQÐQÐQÐQÐQÐQØ#BÐ#BÀ4Ñ#HÔ#H�L�LøÝ ð @ð @ð @Ø#'§8¢8Ð,>Ñ#?Ô#?�L�L�Lð@øøøøøåð 	ð 	ð 	ØˆDð	øøøð	Ý3Ñ5Ô5ˆGØ—{’{ :Ñ.Ô.Ð:°(ˆHØ—{’{ :Ñ.Ô.Ð:°(ˆHØ—k’k )Ñ,Ô,ˆGˆGøÝð 	ð 	ð 	ØˆDð	øøøð !Ð,ð-ØNÐNÐNÐNÐNÐNà+Ð+Ø$ØØ'ØØ'Øñô ð 1ð -1Ð)øøÝð -ð -ð -Ø(,Ð%Ð%Ð%ð-øøøð !Ð(¨\Ð(¸hÐ(ðØPÐPÐPÐPÐPÐPà?Ð?ØØ%Ø%1ðñ ô �
ð
 ð 7Ø,6Ð)øøÝð ð ð Ø�ðøøøð 2Ð1ØØ�^ Ø�M˜rØ"7Ø�^ Ø)ð
ñ 
ô 
ˆð !Ð,Ø!ˆJˆJØÐ7Ò7Ð7ØUˆJˆJà#ˆJð ˜YÒ&Ð&Ø+¨iÑ7Ð>Ð>Ð>Ð>ˆKˆKØ˜uÒ$Ð$Ø+¨uÑ4Ð7Ð7Ð7ˆKˆKå˜nÑ-Ô-ˆKð $˜5Ð#Ð#Ð#Ø7˜XÐ5¨Ð7Ð7Ø?˜KÐ?Ð?°*Ð?Ð?Ð?ð
ˆð ð 	6˜¨Ð0Ð0°KÀ8Ð4KÐ4KÈyÐ\dÐOdÐOdØ�LŠLÐ4¨(Ð4Ð4Ñ5Ô5Ð5à�yŠy˜ÑÔÐs‘   ªA<D9 Â'B7 Â6D9 Â7CÃD9 Ã
CÃ5D9 ÄD ÄD9 ÄD5Ä2D9 Ä4D5Ä5D9 Ä9
EÅEÅ
AF Æ
F)Æ(F)Æ/G ÇGÇGÇ!G: Ç:
HÈHÚcanonical_cmdc                 ó¶  — ddl m} |sdS  || j        |¦  «        }|j        r|                     |j        |¦  «        rdS t                               d||j        r|j        j	        nd|j        ¦  «         t          |j        ¦  «        }|rFdd                     d„ |dd	…         D ¦   «         ¦  «        z   t          |¦  «        d	k    rd
ndz   dz   }nd}d|› d|› �S )uü  Return a denial message if ``source`` cannot run ``canonical_cmd``,
        else None. Used by both the cold and running-agent dispatch paths
        in ``_handle_message`` so admin/user gating can't be bypassed by
        an in-flight agent.

        Backward-compat semantics live in
        :func:`gateway.slash_access.policy_for_source` â€” when the operator
        hasn't set ``allow_admin_from`` for the scope, the policy returns
        ``enabled=False`` and this method always returns None.
        r   )Úpolicy_for_sourceNzLSlash command /%s denied for %s:%s (not admin, not in user_allowed_commands)r¿  zYou can run: r  c              3   ó    K  — | ]	}d |› �V — Œ
dS )r]  NrN  )rb   r  s     r>   rd   z4GatewayRunner._check_slash_access.<locals>.<genexpr>J  s(   è è € ÐBÐB¨˜G ˜G˜GÐBÐBÐBÐBÐBÐBrM   rÌ   rž  r®   z . Use /whoami for the full list.z‹No slash commands are enabled for non-admins on this platform. Ask an admin to add you to allow_admin_from or to set user_allowed_commands.u   â›” /z is admin-only here. )Úgateway.slash_accessrX  rz   rÓ  Úcan_runr¹  r3   rz  r�   r­   r  Úuser_allowed_commandsrf   r7   )r  r(  rV  Ú_policy_for_sourcerZ  Úallowed_previewr  s          r>   ró  z!GatewayRunner._check_slash_accessýI  s/  € ð 	QÐPÐPÐPÐPÐPàð 	Ø�4Ø#Ð# D¤K°Ñ8Ô8ˆØŒ~ð 	 §¢°´ÀÑ!NÔ!Nð 	Ø�4Ý�ŠØZØØ%+¤_Ð=ˆFŒOÔ!Ð!¸#ØŒNñ		
ô 	
ð 	
õ ! Ô!=Ñ>Ô>ˆØð 	àØ—)’)ÐBÐB¨_¸S¸b¸SÔ-AÐBÑBÔBÑBÔBñCå Ñ0Ô0°2Ò5Ð5�5�5¸2ñ?ð 5ñ5ð ˆFð3ð ð
 D�}ÐCÐC¸6ÐCÐCÐCrM   Úown_keyc           	      óÀ  — t          |dd¦  «        }t          |dd¦  «        }|r|sg S |j        j        }t          |dd¦  «        pd}d                     d||t	          |¦  «        t	          |¦  «        g¦  «        }g }|                      ¦   «         D ]K\  }	}
|	|k    rŒ|
t          u s|
sŒ|	|k    s|	                     |dz   ¦  «        r|                     |	¦  «         ŒL|S )u  Find running-agent keys for OTHER participants in the same thread.

        Only applies when the message originates in a thread.  In per-user
        thread mode (``thread_sessions_per_user=True``) each participant gets
        an isolated session key of the form
        ``agent:main:{platform}:{chat_type}:{chat_id}:{thread_id}:{user_id}``,
        so a run started by another user is invisible to the caller's own
        ``/stop``.  This returns the keys of any *actually running* agents
        (not the pending sentinel, not the caller's own key) whose key shares
        the caller's ``{chat_id}:{thread_id}`` prefix.

        Returns an empty list when the source is not in a thread, or when no
        sibling runs exist â€” callers must still gate on authorization.
        r›  Nr2  r´  r®   rÉ  z
agent:main)	rV   r�   r­   rf   rw   rO  rž  r!  r”   )r  r(  r_  r›  r2  r�   r´  r  Úmatchesr  rµ   s              r>   Ú_sibling_thread_run_keysz&GatewayRunner._sibling_thread_run_keys-J  s  € õ ˜F K°Ñ6Ô6ˆ	Ý˜& )¨TÑ2Ô2ˆØð 	 ð 	ØˆIØ”?Ô(ˆÝ˜F K°Ñ6Ô6Ð<¸"ˆ	ð —’Ø˜8 Yµ°G±´½cÀ)¹n¼nÐMñ
ô 
ˆð ˆØ×3Ò3Ñ5Ô5ð 	$ð 	$‰JˆC�Ø�gŠ~ˆ~ØØÕ/Ð/Ð/°uÐ/ØØ�fŠ}ˆ} §¢¨v¸©|Ñ <Ô <ˆ}Ø—’˜sÑ#Ô#Ð#øØˆrM   c                 óT  — |�|j         €dS |j        €dS |j         j        €dS 	 |j         j        j        }n# t          $ r Y dS w xY w|dk    rdS 	 t
          dz  }|                     ¦   «         sEt          | dd¦  «        r2t          j        ¦   «         t          | dd¦  «        z
  dk     r	d| _	        d	S dS t          j        |                     d
¬¦  «        ¦  «        }n# t          $ r Y dS w xY w|                     d¦  «        |k    rdS |                     d¦  «        }t          |t          ¦  «        sdS |j        |k    rdS t          | dd¦  «        r	d| _	        d	S |                     d¦  «        }t          |t          t           f¦  «        rt          j        ¦   «         |z
  dk    rdS d	S )aj  Return True if this /restart is a Telegram re-delivery we already handled.

        The previous gateway wrote ``.restart_last_processed.json`` with the
        triggering platform + update_id when it processed the /restart.  If
        we now see a /restart on the same platform with an update_id <= that
        recorded value, it is a redelivery when this process booted from that
        restart. Otherwise the marker must still be recent (< 5 minutes).

        Only applies to Telegram today (the only platform that exposes a
        numeric cross-session update ordering); other platforms return False.
        NFrY  z.restart_last_processed.jsonrš  r™  r@  rø  TrQ  r‚  r�   Ú	update_idr‰  rå  )r(  Úplatform_update_idr�   r­   r2   rl  r˜   rV   rU   rš  r3  r4  rX  rv   rt   rh  ri  )r  rÖ  r>  r  rî  Úrecorded_uidr‰  s          r>   Ú_is_stale_restart_redeliveryz*GatewayRunner._is_stale_restart_redeliveryWJ  sò  € ð ˆ=˜EœLÐ0Ø�5ØÔ#Ð+Ø�5ØŒ<Ô Ð(Ø�5ð	Ø"œ\Ô2Ô8ˆNˆNøÝð 	ð 	ð 	Ø�5�5ð	øøøà˜ZÒ'Ð'Ø�5ð	Ý&Ð)GÑGˆKØ×%Ò%Ñ'Ô'ð õ ˜DÐ"8¸%Ñ@Ô@ð åœ	™œ¥g¨d°OÀSÑ&IÔ&IÑIÈBÒNÐNà05�DÔ-Ø˜4Ø�uÝ”:˜k×3Ò3¸WÐ3ÑEÔEÑFÔFˆDˆDøÝð 	ð 	ð 	Ø�5�5ð	øøøð �8Š8�JÑÔ >Ò1Ð1Ø�5Ø—x’x Ñ,Ô,ˆÝ˜,­Ñ,Ô,ð 	Ø�5ØÔ# lÒ2Ð2Ø�5õ �4Ð/°Ñ7Ô7ð 	Ø(-ˆDÔ%Ø�4ð
 —x’x Ñ/Ô/ˆÝ�l¥S­% LÑ1Ô1ð 	ÝŒy‰{Œ{˜\Ñ)¨CÒ/Ð/Ø�uØˆts(   ¤6 ¶
AÁAÁAC Â3(C Ã
C*Ã)C*c              ƒ   ó"  K  — |                      ¦   «         pd                     ¦   «         }|j        }d}	 t          |j        dd¦  «        pt          t          |dd¦  «        pd¦  «        }t          |dd¦  «        }|r4|r2|t          |¦  «        t          |dd¦  «        t          |dd¦  «        dœ}n# t          $ r d}Y nw xY w	 d	d
lm}  |||d¬¦  «        S # t          $ r*}t           
                    d|¦  «         d|› �cY d}~S d}~ww xY w)zòHandle /suggestions in the gateway.

        Delegates to the shared handler so CLI and gateway never drift. The
        origin is built from the event source so an accepted suggestion's job
        delivers back to this chat/thread.
        r®   Nr­   r�   r2  r*  r›  ©r�   r2  r*  r›  r   )Úhandle_suggestions_commandr9   ©r3
  r¨	  zsuggestions command failed: %szSuggestions command failed: )rd  rx   r(  rV   r�   rw   r2   Úhermes_cli.suggestions_cmdrj  r3   r4   )	r  rÖ  r¸  r(  r3
  r�   r2  rj  r¨  s	            r>   r  z)GatewayRunner._handle_suggestions_command°J  sl  è è € ð ×&Ò&Ñ(Ô(Ð.¨B×5Ò5Ñ7Ô7ˆØ”ˆØˆð	Ý˜vœ°¸Ñ>Ô>ÐlÅ#ÅgÈfÐV`ÐbdÑFeÔFeÐFkÐikÑBlÔBlˆHÝ˜f i°Ñ6Ô6ˆGØð ˜Gð à (Ý" 7™|œ|Ý!(¨°¸dÑ!CÔ!CÝ!(¨°¸dÑ!CÔ!Cð	ð �øøõ ð 	ð 	ð 	ØˆFˆFˆFð	øøøð	6ØMÐMÐMÐMÐMÐMà-Ð-¨d¸6È9ÐUÑUÔUÐUøÝð 	6ð 	6ð 	6Ý�LŠLÐ9¸1Ñ=Ô=Ð=Ø5°!Ð5Ð5Ð5Ð5Ð5Ð5Ð5Ð5øøøøð	6øøøs0   µA=B3 Â3CÃCÃC Ã
DÃ$D	ÄDÄ	Dc              ƒ   ó@  K  — |                      ¦   «         pd                     ¦   «         }|j        }d}	 t          |j        dd¦  «        pt          t          |dd¦  «        pd¦  «        }t          |dd¦  «        }|r4|r2|t          |¦  «        t          |dd¦  «        t          |dd¦  «        dœ}n# t          $ r d}Y nw xY w	 d	d
lm}  |||d¬¦  «        S # t          $ r9}t           
                    d|¦  «         d	dlm}	  |	d|› �¦  «        cY d}~S d}~ww xY w)a
  Handle /blueprint in the gateway.

        Delegates to the shared handler so CLI, TUI, and gateway never drift.
        Returns a BlueprintCommandResult: ``text`` is shown to the user, and if
        ``agent_seed`` is set the dispatch site rewrites ``event.text`` to the
        seed and falls through to the agent (the ``/steer`` pattern) so the
        agent gathers the slot values conversationally. Origin is built from the
        event source so a directly created blueprint job delivers back to this chat.
        r®   Nr­   r�   r2  r*  r›  ri  r   )Úhandle_blueprint_commandr9   rk  zblueprint command failed: %s)ÚBlueprintCommandResultzCron blueprint command failed: )rd  rx   r(  rV   r�   rw   r2   Úhermes_cli.blueprint_cmdrn  r3   r4   ro  )
r  rÖ  r¸  r(  r3
  r�   r2  rn  r¨  ro  s
             r>   r  z'GatewayRunner._handle_blueprint_commandÎJ  s�  è è € ð ×&Ò&Ñ(Ô(Ð.¨B×5Ò5Ñ7Ô7ˆØ”ˆØˆð	Ý˜vœ°¸Ñ>Ô>ÐlÅ#ÅgÈfÐV`ÐbdÑFeÔFeÐFkÐikÑBlÔBlˆHÝ˜f i°Ñ6Ô6ˆGØð ˜Gð à (Ý" 7™|œ|Ý!(¨°¸dÑ!CÔ!CÝ!(¨°¸dÑ!CÔ!Cð	ð �øøõ ð 	ð 	ð 	ØˆFˆFˆFð	øøøð	QØIÐIÐIÐIÐIÐIà+Ð+¨D¸ÈÐSÑSÔSÐSøÝð 	Qð 	Qð 	QÝ�LŠLÐ7¸Ñ;Ô;Ð;ØGÐGÐGÐGÐGÐGà)Ð)Ð*OÈAÐ*OÐ*OÑPÔPÐPÐPÐPÐPÐPÐPøøøøð		Qøøøs0   µA=B3 Â3CÃCÃC Ã
DÃ$.DÄDÄDc                 ó`  — 	 t          | j        t          ¦  «        r| j        pi                      di ¦  «        nt	          | j        di ¦  «        pi }|s'ddlm}  |¦   «         pi                      d¦  «        pi }t          |                     dd¦  «        pd¦  «        S # t          $ r Y dS w xY w)a%  Resolve the configured /goal turn budget for gateway sessions.

        GatewayRunner.config is a GatewayConfig dataclass, not the full
        user config mapping. Top-level config blocks such as ``goals`` are
        therefore only available through hermes_cli.config.load_config().
        Úgoalsr   rc  r‘  r�  )	rt   rz   ru   rv   rV   r˜  rd  rh  r2   )r  Ú	goals_cfgrd  s      r>   Ú_goal_max_turns_from_configz)GatewayRunner._goal_max_turns_from_configôJ  s×   € ð	õ ˜dœk­4Ñ0Ô0ð=�”Ð" ×'Ò'¨°Ñ4Ô4Ð4å˜Tœ[¨'°2Ñ6Ô6Ð<¸"ð ð
 ð EØ9Ð9Ð9Ð9Ð9Ð9à(˜[™]œ]Ð0¨b×5Ò5°gÑ>Ô>ÐDÀ"�	Ý�y—}’} [°"Ñ5Ô5Ð;¸Ñ<Ô<Ð<øÝð 	ð 	ð 	Ø�2�2ð	øøøs   ‚BB Â
B-Â,B-c              ƒ   ó¤  K  — 	 ddl m} n3# t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w	 | j                             |j        ¦  «        ƒ d{V —†}n3# t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY wt          |dd¦  «        pd}|sdS |  	                    ¦   «         } |||¬	¦  «        |fS )
z¹Return a GoalManager bound to the session for this gateway event.

        Returns ``(manager, session_entry)`` or ``(None, None)`` if the
        goals module can't be loaded.
        r   r0	  zgoal manager unavailable: %sNrT  z'goal manager: session lookup failed: %srN   r®   ©rN   Údefault_max_turns)
r2	  r1	  r2   r3   r4   r8
  rù  r(  rV   rt  )r  rÖ  r1	  r<   r\  Úsidr‘  s          r>   Ú_get_goal_manager_for_eventz)GatewayRunner._get_goal_manager_for_event	K  s%  è è € ð	Ø4Ð4Ð4Ð4Ð4Ð4Ð4øÝð 	ð 	ð 	Ý�LŠLÐ7¸Ñ=Ô=Ð=Ø�:�:�:�:�:øøøøð	øøøð	Ø"&Ô":×"PÒ"PÐQVÔQ]Ñ"^Ô"^Ð^Ð^Ð^Ð^Ð^Ð^ˆMˆMøÝð 	ð 	ð 	Ý�LŠLÐBÀCÑHÔHÐHØ�:�:�:�:�:øøøøð	øøøõ �m \°4Ñ8Ô8Ð>¸BˆØð 	Ø�:Ø×4Ò4Ñ6Ô6ˆ	Øˆ{ c¸YÐGÑGÔGÈÐVÐVó'   „ ‹
;•6¶;¿%A% Á%
BÁ/BÂBc              ƒ   óz  K  — 	 ddl m} n3# t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w	 | j                             |j        ¦  «        ƒ d{V —†}n3# t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY wt          |dd¦  «        pd}|sdS  ||¬	¦  «        |fS )
zŠReturn a HeartbeatManager bound to the session for this event.

        Returns ``(manager, session_entry)`` or ``(None, None)``.
        r   ©ÚHeartbeatManagerz!heartbeat manager unavailable: %sNrT  z,heartbeat manager: session lookup failed: %srN   r®   r~  )	Úhermes_cli.heartbeatr}  r2   r3   r4   r8
  rù  r(  rV   )r  rÖ  r}  r<   r\  rx  s         r>   Ú _get_heartbeat_manager_for_eventz.GatewayRunner._get_heartbeat_manager_for_eventK  s  è è € ð
	Ø=Ð=Ð=Ð=Ð=Ð=Ð=øÝð 	ð 	ð 	Ý�LŠLÐ<¸cÑBÔBÐBØ�:�:�:�:�:øøøøð	øøøð	Ø"&Ô":×"PÒ"PÐQVÔQ]Ñ"^Ô"^Ð^Ð^Ð^Ð^Ð^Ð^ˆMˆMøÝð 	ð 	ð 	Ý�LŠLÐGÈÑMÔMÐMØ�:�:�:�:�:øøøøð	øøøõ �m \°4Ñ8Ô8Ð>¸BˆØð 	Ø�:ØÐ¨3Ð/Ñ/Ô/°Ð>Ð>rz  c                 ót   — t          | dd¦  «        }|€	i }|| _        ||f||<   |                      ¦   «          dS )uÂ  Track a session with an active heartbeat and start the poller.

        The registry maps ``quick_key`` â†’ ``(source, session_id)`` so the
        poller can rebuild a MessageEvent and enqueue via the adapter FIFO.
        In-memory by design: heartbeat STATE survives restarts in SessionDB,
        but firing resumes when the user touches /heartbeat again in the new
        gateway process (documented; durable schedules belong to cron).
        Ú_heartbeat_watchN)rV   r�  Ú_start_heartbeat_poller)r  r-  r(  rN   Úwatchs        r>   Ú_register_heartbeat_watchz'GatewayRunner._register_heartbeat_watch3K  sO   € õ ˜Ð0°$Ñ7Ô7ˆØˆ=ØˆEØ$)ˆDÔ!Ø" JÐ/ˆˆiÑØ×$Ò$Ñ&Ô&Ð&Ð&Ð&rM   c                 ó\   — t          | dd ¦  «        }|r|                     |d ¦  «         d S d S )Nr�  )rV   rU  )r  r-  rƒ  s      r>   Ú_unregister_heartbeat_watchz)GatewayRunner._unregister_heartbeat_watchCK  s@   € Ý˜Ð0°$Ñ7Ô7ˆØð 	'Ø�IŠI�i Ñ&Ô&Ð&Ð&Ð&ð	'ð 	'rM   c                 óž  ‡ ‡— t          ‰ dd¦  «        }|�|                     ¦   «         sdS ddlmŠ ˆˆ fd„}	 t	          j         |¦   «         ¦  «        }|‰ _        t          ‰ dd¦  «        }|�1|                     |¦  «         |                     |j	        ¦  «         dS dS # t          $ r  t                               dd¬	¦  «         Y dS w xY w)
z?Start the single gateway-wide heartbeat poll task (idempotent).Ú_heartbeat_poll_taskNr   )ÚPOLL_SECONDSc               “   ó|  •K  — 	 t          j        ‰
¦  «        ƒ d {V —† t          ‰dd ¦  «        } | sŒ/t          |                      ¦   «         ¦  «        D ]ç\  }\  }}	 |‰j        v rŒddlm}  ||¬¦  «        }|                     ¦   «         s|  	                    |d ¦  «         ŒP| 
                    ¦   «         }|sŒg‰                     |¦  «        }|€Œt          |t          j        |d d ¬¦  «        }‰                     |||¦  «         Œµ# t           $ r&}	t"                               d||	¦  «         Y d }	~	Œàd }	~	ww xY w�Œ9)NTr�  r   r|  r~  ©rè   rÚ  r(  rj  r´  z heartbeat poll for %s failed: %s)r  r–  rV   r½  rñ  r7  r~  r}  Úhas_heartbeatrU  Ú
due_promptr@  rr  rs  rÀ	  r	  r2   r3   r4   )rƒ  r-  r(  rN   r}  ÚmgrrY	  r1  Úhb_eventr<   r‰  r  s             €€r>   Ú
_poll_loopz9GatewayRunner._start_heartbeat_poller.<locals>._poll_loopPK  s¦  øè è € ðYÝ”m LÑ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ý Ð&8¸$Ñ?Ô?�Øð ØÝ7;¸E¿KºK¹M¼MÑ7JÔ7Jð Yð YÑ3�IÑ3 ¨
ðYà$¨Ô(<Ð<Ð<Ø$ØIÐIÐIÐIÐIÐIà.Ð.¸*ÐEÑEÔE˜Ø"×0Ò0Ñ2Ô2ð %Ø!ŸIšI i°Ñ6Ô6Ð6Ø$Ø!$§¢Ñ!1Ô!1˜Ø%ð %Ø$Ø"&×":Ò":¸6Ñ"BÔ"B˜Ø"˜?Ø$Ý#/Ø!'Ý)4Ô)9Ø#)Ø'+Ø+/ð$ñ $ô $˜ð ×*Ò*¨9°hÀÑHÔHÐHÐHøÝ$ð Yð Yð YÝŸšÐ%GÈÐTWÑXÔXÐXÐXÐXÐXÐXÐXøøøøðYøøøñ=Ys0   Á	D	Á'<D	Â$D	Â;D	Ã5D	Ä	
D9ÄD4Ä4D9r¼  z Failed to start heartbeat pollerTrß   )rV   r  r~  r‰  r  r”  rˆ  r—   rä  rü  r2   r3   r4   )r  r·  r�  rÝ   rÖ  r‰  s   `    @r>   r‚  z%GatewayRunner._start_heartbeat_pollerHK  s  øø€ å˜4Ð!7¸Ñ>Ô>ˆØÐ¨¯ª©¬ÐØˆFà5Ð5Ð5Ð5Ð5Ð5ð 	Yð  	Yð  	Yð  	Yð  	Yð  	YðD	LÝÔ& z z¡|¤|Ñ4Ô4ˆDØ(,ˆDÔ%Ý˜$Ð 3°TÑ:Ô:ˆCØˆØ—’˜‘”�Ø×&Ò& s¤{Ñ3Ô3Ð3Ð3Ð3ð ˆøõ ð 	Lð 	Lð 	LÝ�LŠLÐ;ÀdˆLÑKÔKÐKÐKÐKÐKð	Løøøs   ¹A%B" Â"&CÃCr$  c              ƒ   óª  K  — |                       |¦  «        }|s,t                               dt          |dd¦  «        ¦  «         dS 	 |                      |¦  «        }n# t
          $ r d}Y nw xY w|                     |j        ||¬¦  «        ƒ d{V —†}|�=t          |dd¦  «        s.t                               dt          |dd	¦  «        ¦  «         dS dS dS )
zCSend a /goal judge status line back to the originating chat/thread.ú$goal continuation: no adapter for %sr�   Nr.  r/  Tú)goal continuation: status send failed: %srP   rÛ  )	r@  r3   r4   rV   rî	  r2   r0  r2  rã   )r  r(  r$  r1  r¯   r·  s         r>   Ú_send_goal_status_noticez&GatewayRunner._send_goal_status_notice~K  s  è è € à×*Ò*¨6Ñ2Ô2ˆØð 	Ý�LŠLÐ?ÅÈÐQ[Ð]aÑAbÔAbÑcÔcÐcØˆFð	Ø×7Ò7¸Ñ?Ô?ˆHˆHøÝð 	ð 	ð 	ØˆHˆHˆHð	øøøð —|’| F¤N°GÀh�|ÑOÔOÐOÐOÐOÐOÐOÐOˆØÐ¥g¨f°iÀÑ&FÔ&FÐÝ�NŠNØ;Ý˜ ¨Ñ9Ô9ñô ð ð ð ð ÐÐÐs   ÁA ÁA,Á+A,c              ƒ   óH  ‡ ‡‡K  — ‰                       ‰¦  «        }|s,t                               dt          ‰dd¦  «        ¦  «         dS dˆˆ ˆfd„}	 ‰                      ‰¦  «        }n# t
          $ r d}Y nw xY w|r–t          |d¦  «        r†	 d}t          |di ¦  «                             |¦  «        }|�t          |dd¦  «        }|                     |||¬	¦  «         dS # t
          $ r%}t                               d
|¦  «         Y d}~nd}~ww xY w |¦   «         ƒ d{V —† dS )a  Send a /goal status line after the main response is delivered.

        The gateway message handler returns the agent response to the platform
        adapter, which sends it after this method's caller has returned.  For a
        natural Discord/Telegram reading order, goal status belongs after that
        send.  Platform adapters provide a one-shot post-delivery callback for
        exactly this boundary; when unavailable, fall back to direct awaited
        delivery rather than silently dropping the notice.
        r’  r�   Nr-   c               “   ó°   •K  — 	 ‰                      ‰‰¦  «        ƒ d {V —† d S # t          $ r(} t                               d| d¬¦  «         Y d } ~ d S d } ~ ww xY w)Nr“  Trß   )r”  r2   r3   rã   )r<   r$  r  r(  s    €€€r>   Ú_deliverzHGatewayRunner._defer_goal_status_notice_after_delivery.<locals>._deliver K  sŠ   øè è € ð`Ø×3Ò3°F¸GÑDÔDÐDÐDÐDÐDÐDÐDÐDÐDÐDøÝð `ð `ð `Ý—’ÐJÈCÐZ^�Ñ_Ô_Ð_Ð_Ð_Ð_Ð_Ð_Ð_øøøøð`øøøs   …# £
A­AÁAr=  Ú_active_sessionsÚ_hermes_run_generationr>  zAgoal continuation: post-delivery callback registration failed: %srŽ  )	r@  r3   r4   rV   rA  r2   rá   rv   r=  )	r  r(  r$  r1  r—  r+   r?  rö  r<   s	   ```      r>   Ú(_defer_goal_status_notice_after_deliveryz6GatewayRunner._defer_goal_status_notice_after_delivery‘K  s¸  øøøè è € ð ×*Ò*¨6Ñ2Ô2ˆØð 	Ý�LŠLÐ?ÅÈÐQ[Ð]aÑAbÔAbÑcÔcÐcØˆFð	`ð 	`ð 	`ð 	`ð 	`ð 	`ð 	`ð 	`ð	Ø×6Ò6°vÑ>Ô>ˆKˆKøÝð 	ð 	ð 	ØˆKˆKˆKð	øøøð ð 	g�7 7Ð,MÑNÔNð 	gðgØ!�
Ý  Ð*<¸bÑAÔA×EÒEÀkÑRÔR�ØÐ%Ý!(¨Ð1IÈ4Ñ!PÔ!P�JØ×7Ò7ØØØ)ð 8ñ ô ð ð
 �øÝð gð gð gÝ—’Ð`ÐbeÑfÔfÐfÐfÐfÐfÐfÐføøøøðgøøøð ˆh‰jŒjÐÐÐÐÐÐÐÐÐs+   ÁA( Á(A7Á6A7ÂAC  Ã 
DÃ*D
Ä
Drò  c             ƒ   ó¤  K  — 	 ddl m} n3# t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY wt          |dd¦  «        pd}|sdS |                      ¦   «         } |||¬¦  «        }|                     ¦   «         sdS 	 ddl m}	  |	¦   «         }
n# t          $ r d}
Y nw xY w| 	                    |pdd	|
¬
¦  «        }| 
                    d¦  «        pd}|r|�|                      ||¦  «        ƒ d{V —† | 
                    d¦  «        sdS | 
                    d¦  «        pd}|r|€dS 	 |                      |¦  «        }|                      |¦  «        }|r9|r9t          |t          j        |dd¬¦  «        }|                      |||¦  «         dS dS dS # t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w)aÐ  Run the goal judge after a gateway turn and, if still active,
        enqueue a continuation prompt for the same session.

        Called from ``_handle_message_with_agent`` at turn boundary, AFTER
        the response has been delivered. Safe when no goal is set.

        We use the adapter's pending-message / FIFO machinery so any real
        user message that arrives simultaneously is handled by the same
        queue and takes priority naturally.
        r   r0	  z/goal continuation: goals module unavailable: %sNrN   r®   rv  )Úgather_background_processesT)Úuser_initiatedÚbackground_processesr$  Úshould_continueÚcontinuation_promptr‹  z%goal continuation: enqueue failed: %s)r2	  r1	  r2   r3   r4   rV   rt  r3	  rœ  Úevaluate_after_turnrv   rš  r@  rA  rr  rs  rÀ	  r	  )r  r\  r(  rò  r1	  r<   rx  r‘  rŽ  Ú
_gather_bgÚ	_bg_procsr­  r§  rY	  r1  r;  Ú
cont_events                    r>   r'  z*GatewayRunner._post_turn_goal_continuation¼K  s«  è è € ð"	Ø4Ð4Ð4Ð4Ð4Ð4Ð4øÝð 	ð 	ð 	Ý�LŠLÐJÈCÑPÔPÐPØˆFˆFˆFˆFˆFøøøøð	øøøõ �m \°4Ñ8Ô8Ð>¸BˆØð 	ØˆFà×4Ò4Ñ6Ô6ˆ	àˆk S¸IÐFÑFÔFˆØ�}Š}‰Œð 	ØˆFð	ØRÐRÐRÐRÐRÐRØ"˜
™œˆIˆIøÝð 	ð 	ð 	ØˆIˆIˆIð	øøøð ×*Ò*ØÐ ˜bØØ!*ð +ñ 
ô 
ˆð
 �lŠl˜9Ñ%Ô%Ð+¨ˆð ð 	M�6Ð%Ø×?Ò?ÀÈÑLÔLÐLÐLÐLÐLÐLÐLÐLà�|Š|Ð-Ñ.Ô.ð 	ØˆFà—’Ð3Ñ4Ô4Ð:¸ˆØð 	˜˜ØˆFð	GØ×.Ò.¨vÑ6Ô6ˆGØ×5Ò5°fÑ=Ô=ˆJØð D˜:ð DÝ)ØÝ!,Ô!1Ø!Ø#Ø#'ðñ ô �
ð ×"Ò" :¨z¸7ÑCÔCÐCÐCÐCðDð Dð Dð Døõ ð 	Gð 	Gð 	GÝ�LŠLÐ@À#ÑFÔFÐFÐFÐFÐFÐFÐFÐFøøøøð	Gøøøs;   „ ‹
;•6¶;ÂB ÂB-Â,B-Ä6A#F Æ
GÆ)G
Ç
Gc                 óÌ   — t          | dd¦  «        }|€dS t          |d¦  «        r|j        rt          |j        ¦  «        S t          |d¦  «        r|j        r|j        j        S dS )z5Extract Discord guild_id from the raw message object.r{  NÚguild_idÚguild)rV   rá   r¦  rh  r§  rÍ   )rÖ  rx  s     r>   Ú_get_guild_idzGatewayRunner._get_guild_idL  st   € õ �e˜]¨DÑ1Ô1ˆØˆ;Ø�4å�3˜
Ñ#Ô#ð 	%¨¬ð 	%Ý�s”|Ñ$Ô$Ð$å�3˜Ñ Ô ð 	  S¤Yð 	 Ø”9”<ÐØˆtrM   c              ƒ   ód  ‡ K  — ‰                       |j        ¦  «        }t          |d¦  «        sdS ‰                      |¦  «        }|sdS |                     ||j        j        ¦  «        ƒ d{V —†}|sdS t          |d¦  «        r‰ j        |_        t          |d¦  «        r‰ j        |_	        t          |d¦  «        r
ˆ fd	„|_
        	 |                     |¦  «        ƒ d{V —†}n€# t          $ rs}t                               d
|¦  «         d|_        t          |¦  «                             ¦   «         }d|v sd|v sd|v rdt"          j        › d�cY d}~S d|› �cY d}~S d}~ww xY w|rÅt'          |j        j        ¦  «        |j        |<   t          |d¦  «        r!|j                             ¦   «         |j        |<   d‰ j        ‰                      |j        j        |j        j        ¦  «        <   ‰                      ¦   «          ‰                      ||j        j        d¬¦  «         d|j        › d�S d|_        dS )z.Join the user's current Discord voice channel.Újoin_voice_channelz2Voice channels are not supported on this platform.z,This command only works in a Discord server.Nz(You need to be in a voice channel first.rb  Ú_on_voice_disconnectÚ_voice_mode_getterc                 ó�   •— ‰j                              ‰                     t          j        t          | ¦  «        ¦  «        d¦  «        S )Nr  )rº  rv   rè  rÄ  r±  rw   )r2  r  s    €r>   rò   z:GatewayRunner._handle_voice_channel_join.<locals>.<lambda>5L  s6   ø€ ¸Ô9I×9MÒ9MØ—’¥Ô 0µ#°g±,´,Ñ?Ô?Àñ:ô :€ rM   z Failed to join voice channel: %sÚpynaclÚnaclÚdaveyz@Voice dependencies are missing (PyNaCl / davey). Install with: `z -m pip install PyNaCl`zFailed to join voice channel: Ú_voice_sourcesr�  T)rÓ  zJoined voice channel **zL**.
I'll speak my replies and listen to you. Use /voice leave to disconnect.zFFailed to join voice channel. Check bot permissions (Connect + Speak).)r@  r(  rá   r¨  Úget_user_voice_channelr¹  r¢  rb  Ú_handle_voice_timeout_cleanupr«  r¬  rª  r2   r3   rã   rw   ry   rŽ   r­  rh  r2  Ú_voice_text_channelsÚto_dictr±  rº  rè  r�   r÷  r  rÖ   )r  rÖ  r1  r¦  Úvoice_channelr/  r¨  Ú	err_lowers   `       r>   Ú_handle_voice_channel_joinz(GatewayRunner._handle_voice_channel_joinL  sä  øè è € à×*Ò*¨5¬<Ñ8Ô8ˆÝ�wÐ 4Ñ5Ô5ð 	HØGÐGà×%Ò% eÑ,Ô,ˆØð 	BØAÐAà%×<Ò<Ø�e”lÔ*ñ
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ˆð ð 	>Ø=Ð=õ �7Ð3Ñ4Ô4ð 	MØ,0Ô,LˆGÔ)Ý�7Ð2Ñ3Ô3ð 	NØ+/Ô+MˆGÔ(õ �7Ð0Ñ1Ô1ð 	ð*ð *ð *ð *ˆGÔ&ð	8Ø#×6Ò6°}ÑEÔEÐEÐEÐEÐEÐEÐEˆGˆGøÝð 		8ð 		8ð 		8Ý�NŠNÐ=¸qÑAÔAÐAØ,0ˆGÔ)Ý˜A™œŸš™œˆIØ˜9Ð$Ð$¨°)Ð(;Ð(;¸wÈ)Ð?SÐ?SðNÝ&)¤nðNð Nð Nðð ð ð ð ð ð 8°AÐ7Ð7Ð7Ð7Ð7Ð7Ð7Ð7øøøøð		8øøøð ð 
	Ý58¸¼Ô9MÑ5NÔ5NˆGÔ(¨Ñ2Ý�wÐ 0Ñ1Ô1ð JØ38´<×3GÒ3GÑ3IÔ3I�Ô& xÑ0Ø]bˆDÔ˜TŸ_š_¨U¬\Ô-BÀEÄLÔDXÑYÔYÑZØ×"Ò"Ñ$Ô$Ð$Ø×.Ò.¨w¸¼Ô8LÐVZÐ.Ñ[Ô[Ð[ð\¨-Ô*<ð \ð \ð \ðð
 )-ˆÔ%ØWÐWs+   ÃC" Ã"
EÃ,AEÅ
EÅEÅEÅEc              ƒ   óz  K  — |                       |j        ¦  «        }|                      |¦  «        }|rt          |d¦  «        sdS t          |d¦  «        r|                     |¦  «        sdS 	 |                     |¦  «        ƒ d{V —† n2# t          $ r%}t                               d|¦  «         Y d}~nd}~ww xY wd| j	        |  
                    |j        j        |j        j        ¦  «        <   |                      ¦   «          |                      ||j        j        d¬¦  «         t          |d	¦  «        rd|_        d
S )z Leave the Discord voice channel.Úleave_voice_channelzNot in a voice channel.Úis_in_voice_channelNzError leaving voice channel: %sr  T©rj  rb  zLeft voice channel.)r@  r(  r¨  rá   r»  rº  r2   r3   rã   rº  rè  r�   r2  r÷  rÿ  rb  )r  rÖ  r1  r¦  r¨  s        r>   Ú_handle_voice_channel_leavez)GatewayRunner._handle_voice_channel_leaveUL  sp  è è € à×*Ò*¨5¬<Ñ8Ô8ˆØ×%Ò% eÑ,Ô,ˆàð 	-�w wÐ0EÑFÔFð 	-Ø,Ð,å�wÐ 5Ñ6Ô6ð 	-¸g×>YÒ>YÐZbÑ>cÔ>cð 	-Ø,Ð,ð	AØ×-Ò-¨hÑ7Ô7Ð7Ð7Ð7Ð7Ð7Ð7Ð7Ð7øÝð 	Að 	Að 	AÝ�NŠNÐ<¸aÑ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@øøøøð	Aøøøð Z_ˆÔ˜Ÿš¨¬Ô)>ÀÄÔ@TÑUÔUÑVØ×ÒÑ Ô Ð Ø×+Ò+¨G°U´\Ô5IÐTXÐ+ÑYÔYÐYÝ�7Ð3Ñ4Ô4ð 	1Ø,0ˆGÔ)Ø$Ð$s   Á.B
 Â

B9ÂB4Â4B9c                 óö   — d| j         |                      t          j        |¦  «        <   |                      ¦   «          | j                             t          j        ¦  «        }|                      ||d¬¦  «         dS )z�Called by the adapter when a voice channel times out.

        Cleans up runner-side voice_mode state that the adapter cannot reach.
        r  Tr¼  N)rº  rè  rÄ  r±  r÷  r°  rv   rÿ  )r  r2  r1  s      r>   r³  z+GatewayRunner._handle_voice_timeout_cleanuplL  so   € ð
 HMˆÔ˜Ÿš­Ô)9¸7ÑCÔCÑDØ×ÒÑ Ô Ð Ø”-×#Ò#¥HÔ$4Ñ5Ô5ˆØ×+Ò+¨G°WÀtÐ+ÑLÔLÐLÐLÐLrM   r¦  r¹  r  c                 óª  ‡‡— ddl m} t          j        dd|¦  «                             ¦   «                              ¦   «         }t          j        dd|¦  «        }|sdS t          j        ¦   «         ŠdŠ||f}t          | d	d
¦  «        }t          |t          ¦  «        s	i }|| _        ˆˆfd„|                     |g ¦  «        D ¦   «         }|D ]d\  }	}
|
|k    r|||<    dS t          |
¦  «        dk    r>t          |¦  «        dk    r+ |d
|
|¦  «                             ¦   «         dk    r|||<    dS Œe|                     ‰|f¦  «         |dd
…         ||<   dS )ar  Suppress repeated STT outputs for the same recent utterance.

        Voice capture can occasionally emit the same utterance twice a few
        seconds apart, which creates a second queued agent run and overlapping
        spoken replies. Dedup exact and near-exact repeats per guild/user over a
        short window while allowing genuinely new turns through.
        r   )ÚSequenceMatcherú\s+r™  z[^\w\s]r®   Fg      (@r»  Nc                 ó0   •— g | ]\  }}‰|z
  ‰k    ¯||f‘ŒS rN  rN  )rb   r²  ÚtxtrŒ  rÜ  s      €€r>   r  z@GatewayRunner._is_duplicate_voice_transcript.<locals>.<listcomp>ŒL  s:   ø€ ð 
ð 
ð 
á��CØ�R‰x˜>Ò)Ð)ð �ˆIà)Ð)Ð)rM   Trä  r2  éûÿÿÿ)ÚdifflibrÀ  r_   rõ   rx   ry   rU   r—  rV   rt   ru   r»  rv   r7   Úratior”   )r  r¦  r¹  r  rÀ  rH  r  Úrecent_storeÚrecentrK  ÚpriorrŒ  rÜ  s              @@r>   Ú_is_duplicate_voice_transcriptz,GatewayRunner._is_duplicate_voice_transcriptvL  s¤  øø€ ð 	,Ð+Ð+Ð+Ð+Ð+å”V˜F C¨Ñ4Ô4×:Ò:Ñ<Ô<×BÒBÑDÔDˆ
Ý”V˜J¨¨JÑ7Ô7ˆ
Øð 	Ø�5åŒnÑÔˆØˆØ˜Ð!ˆÝ˜tÐ%@À$ÑGÔGˆÝ˜,­Ñ-Ô-ð 	:ØˆLØ-9ˆDÔ*ð
ð 
ð 
ð 
ð 
à'×+Ò+¨C°Ñ4Ô4ð
ñ 
ô 
ˆð ð 	 ð 	 ‰HˆAˆuØ˜
Ò"Ð"Ø$*�˜SÑ!Ø�t�tÝ�5‰zŒz˜RÒÐ¥C¨
¡O¤O°rÒ$9Ð$9Ø"�? 4¨°
Ñ;Ô;×AÒAÑCÔCÀtÒKÐKØ(.�L Ñ%Ø˜4˜4øà�Š�s˜JÐ'Ñ(Ô(Ð(Ø" 2 3 3œKˆ�SÑØˆurM   c           	   ƒ   ó*  K  — | j                              t          j        ¦  «        }|sdS |j                             |¦  «        }|sdS t          |di ¦  «                             |¦  «        }|r=t          j        |¦  «        }t          |¦  «        |_	        t          |¦  «        |_
        nEt          t          j        t          |¦  «        t          |¦  «        t          |¦  «        d¬¦  «        }|                      |¦  «        st                               d|¦  «         dS |                      |||¦  «        r't                               d|||dd…         ¦  «         dS 	 |j                             |¦  «        }|rS|dd…                              d	d
¦  «                             dd¦  «        }	|                     d|› d|	› �¦  «        ƒ d{V —† n# t(          $ r Y nw xY wddlm}
 d}t          |dd¦  «        }t/          |¦  «        rE	  |t          |¦  «        ¦  «        }t1          |t          ¦  «        r|nd}n# t(          $ r d}Y nw xY wt3          ||t4          j         |
|d¬¦  «        |¬¦  «        }|                     |¦  «        ƒ d{V —† dS )zÕHandle transcribed voice from a user in a voice channel.

        Creates a synthetic MessageEvent and processes it through the
        adapter's full message pipeline (session, typing, agent, TTS reply).
        Nr±  Úchannel)r�   r2  r¹  r)  r´  z/Unauthorized voice input from user %d, ignoringz?Suppressing duplicate voice transcript for guild=%s user=%s: %srv  éÐ  z	@everyoneu   @â€‹everyonez@hereu   @â€‹herez**[Voice]** <@z>: r   )ÚSimpleNamespaceÚ_resolve_channel_prompt)r¦  r§  )r(  rè   rÚ  r{  r´  )r°  rv   rÄ  r±  r´  rV   r[  Ú	from_dictrw   r¹  r)  rí	  r3   r4   rÊ  rz  Ú_clientÚget_channelrl  r0  r2   ÚtypesrÎ  r/  rt   rr  rs  rá  rË
  )r  r¦  r¹  r  r1  Ú
text_ch_idÚsource_datar(  rÌ  Ú	safe_textrÎ  r´  Úresolverre  rÖ  s                  r>   r¢  z)GatewayRunner._handle_voice_channel_inputŸL  s   è è € ð ”-×#Ò#¥HÔ$4Ñ5Ô5ˆØð 	ØˆFàÔ1×5Ò5°hÑ?Ô?ˆ
Øð 	ØˆFõ ˜gÐ'7¸Ñ<Ô<×@Ò@ÀÑJÔJˆØð 	Ý"Ô,¨[Ñ9Ô9ˆFÝ  ™\œ\ˆFŒNÝ" 7™|œ|ˆFÔÐå"Ý!Ô)Ý˜J™œÝ˜G™œÝ˜g™,œ,Ø#ðñ ô ˆFð ×'Ò'¨Ñ/Ô/ð 	Ý�LŠLÐJÈGÑTÔTÐTØˆFà×.Ò.¨x¸À*ÑMÔMð 	Ý�KŠKØQØØØ˜4˜C˜4Ô ñ	ô ð ð ˆFð	Ø”o×1Ò1°*Ñ=Ô=ˆGØð MØ& u¨ uÔ-×5Ò5°kÐCTÑUÔU×]Ò]Ð^eÐgtÑuÔu�	Ø—l’lÐ#K°GÐ#KÐ#KÀ	Ð#KÐ#KÑLÔLÐLÐLÐLÐLÐLÐLÐLøøÝð 	ð 	ð 	ØˆDð	øøøð 	*Ð)Ð)Ð)Ð)Ð)ð )-ˆÝ˜7Ð$=¸tÑDÔDˆÝ�HÑÔð 	&ð&Ø#˜8¥C¨
¡O¤OÑ4Ô4�Ý-7¸Å#Ñ-FÔ-FÐ!P  ÈD��øÝð &ð &ð &Ø!%���ð&øøøåØØÝ$Ô*Ø'˜°ÀÐFÑFÔFØ)ð
ñ 
ô 
ˆð ×$Ò$ UÑ+Ô+Ð+Ð+Ð+Ð+Ð+Ð+Ð+Ð+Ð+s%   Å"A/G Ç
GÇGÈ1H= È=IÉIrJ  r  rd  c                 ó^  — |r|                      d¦  «        rdS |j        j        }|                      |j        j        |¦  «        }| j                             |¦  «        }|j        t          j	        k    }| j
                             |j        j        ¦  «        }	d}
|	rFt          |	d¦  «        r6	 t          |	                     |¦  «        ¦  «        }
n# t          $ r d}
Y nw xY w|dk    p|dk    o|p|du o|
}|s/t                               d||
||j        j        j        ¦  «         dS d}t%          t'          |¦  «        ¦  «        D ]5\  }}|                     d¦  «        d	k    rt)          |¦  «        d
z
  |z
  } nŒ6|�
||d…         n|}t+          d„ |D ¦   «         ¦  «        }|rdS |r|sdS dS )aø  Decide whether the runner should send a TTS voice reply.

        Returns False when:
        - voice_mode is off for this chat
        - response is empty or an error
        - agent already called text_to_speech tool (dedup)
        - voice input and base adapter auto-TTS already handled it (skip_double)
          UNLESS streaming already consumed the response (already_sent=True),
          in which case the base adapter won't have text for auto-TTS so the
          runner must handle it.
        zError:FÚ_should_auto_tts_for_chatr�  rê  NzIAuto voice reply skipped: mode=%s adapter_auto_tts=%s chat=%s platform=%sr¦  r¬  r(   c              3   ó¤   K  — | ]K}|                      d ¦  «        dk    o-t          d„ |                      d¦  «        pg D ¦   «         ¦  «        V — ŒLdS )r¦  r­  c              3   ór   K  — | ]2}|                      d ¦  «        pi                       d¦  «        dk    V — Œ3dS )r-  rÖ   r  Nrr  )rb   Útcs     r>   rd   zCGatewayRunner._should_send_voice_reply.<locals>.<genexpr>.<genexpr>'M  s[   è è € ð ð àð —’˜
Ñ#Ô#Ð) r×.Ò.¨vÑ6Ô6Ð:JÒJðð ð ð ð ð rM   rã  N)rv   r
  )rb   r§  s     r>   rd   z9GatewayRunner._should_send_voice_reply.<locals>.<genexpr>%M  s†   è è € ð 
ð 
ð ð �GŠG�F‰OŒO˜{Ò*ð Ýð ð àŸ7š7 <Ñ0Ô0Ð6°Bðñ ô ñ ô ð
ð 
ð 
ð 
ð 
ð 
rM   T)r!  r(  r2  rè  r�   rº  rv   rÚ  rs  rá  r°  rá   rº   rÙ  r2   r3   r4   r­   rí  r  r7   r
  )r  rÖ  rJ  r  rd  r2  Ú	voice_keyÚ
voice_modeÚis_voice_inputr1  Úadapter_auto_ttsÚshouldÚlast_user_idxrî  r§  Úturn_messagesÚhas_agent_ttss                    r>   rž  z&GatewayRunner._should_send_voice_replyîL  s6  € ð$ ð 	˜8×.Ò.¨xÑ8Ô8ð 	Ø�5à”,Ô&ˆØ—O’O E¤LÔ$9¸7ÑCÔCˆ	ØÔ%×)Ò)¨)Ñ4Ô4ˆ
ØÔ,µÔ0AÒAˆà”-×#Ò# E¤LÔ$9Ñ:Ô:ˆØ ÐØð 	)•w˜wÐ(CÑDÔDð 	)ð)Ý#'¨×(IÒ(IÈ'Ñ(RÔ(RÑ#SÔ#SÐ Ð øÝð )ð )ð )Ø#(Ð Ð Ð ð)øøøð ˜5Ò ð 9Ø˜lÒ*Ð=¨~ð9ð
 ˜dÐ"Ð7Ð'7ð 	ð ð 	Ý�LŠLØ[ØÐ,¨g°u´|Ô7LÔ7Rñô ð ð �5ð ˆÝ¥¨Ñ 8Ô 8Ñ9Ô9ð 	Cð 	C‰FˆAˆsØ�wŠw�v‰Œ &Ò(Ð(Ý # NÑ 3Ô 3°aÑ 7¸!Ñ ;�¸U¸Uð )à:GÐ:S˜ } ~ ~Ô6Ð6ÐYgˆÝð 
ð 
ð %ð
ñ 
ô 
ñ 
ô 
ˆð ð 	Ø�5ð ð 	 ,ð 	Ø�5àˆts   Â."C ÃC ÃC c                 óH   — t          t          | j        dd¦  «        ¦  «        S )zFReturn whether inbound voice/STT transcripts should be echoed to chat.Ústt_echo_transcriptsT)rº   rV   rz   rN  s    r>   rÆ  z*GatewayRunner._should_echo_stt_transcripts:M  s   € å•G˜DœKÐ)?ÀÑFÔFÑGÔGÐGrM   rè   c              ƒ   óò  K  — d}g }	 ddl m}m}  ||¦  «        }|s4	 |h|£dhz
  D ]'}	 t          j        |¦  «         Œ# t
          $ r Y Œ$w xY wdS t          |j        j        ¦  «        }t          j
        |||¬¦  «        ƒ d{V —†}		 t          j        |	¦  «        }
nu# t          j        t          f$ r\ t                               d|	r
|	dd…         n|	¦  «         Y |h|£dhz
  D ]'}	 t          j        |¦  «         Œ# t
          $ r Y Œ$w xY wdS w xY w|
                     d¦  «        p|
                     d|¦  «        g}d	„ |D ¦   «         }|
                     d
¦  «        r|sbt                               d|
                     d¦  «        ¦  «         	 |h|£dhz
  D ]'}	 t          j        |¦  «         Œ# t
          $ r Y Œ$w xY wdS |                      |j        ¦  «        }|                      |¦  «        }t)          |dd¦  «        }t)          |dd¦  «        }t)          |dd¦  «        }t+          |o(t-          |¦  «        ot-          |¦  «        o
 ||¦  «        ¦  «        }|                      |¦  «        }|                      |j        |¦  «        }|s*t-          |¦  «        r|�t3          |¦  «        }d|d<   nddi}|D ]Ÿ}|r@t5          t6          dt8          t:                   f         |¦  «        } |||¦  «        ƒ d{V —† ŒDt-          |¦  «        rLt5          t6          dt8          t:                   f         |¦  «        }|j        j        |||dœ} |di |¤Žƒ d{V —† Œ n4# t>          $ r'}t                               d|d¬¦  «         Y d}~nd}~ww xY w|h|£dhz
  D ]'}	 t          j        |¦  «         Œ# t
          $ r Y Œ$w xY wdS # |h|£dhz
  D ]'}	 t          j        |¦  «         Œ# t
          $ r Y Œ$w xY ww xY w)zEGenerate TTS audio and send as a voice message before the text reply.Nr   )r  Ú_strip_markdown_for_tts)rè   Úoutput_pathz.Auto voice reply TTS returned invalid JSON: %sr  Ú
file_pathsrU	  c                 ón   — g | ]2}|¯t           j                             |¦  «        ¯#t          |¦  «        ‘Œ3S rN  )r’   r™   Úisfilerw   rn  s     r>   r  z3GatewayRunner._send_voice_reply.<locals>.<listcomp>_M  sJ   € ð ð ð Ø"ØðåœGŸNšN¨4Ñ0Ô0ðÝ�D‘	”	ðð ð rM   r/  zAuto voice reply TTS failed: %srP   Úplay_in_voice_channelr»  Ú
send_voiceTrv  .)r2  Ú
audio_pathr€  r¯   zAuto voice reply failed: %srß   rN  ) Útools.tts_toolr  rè  r’   ru  r–   rv  r(  r�   r  r  r3  r4  rí  rw  r3   rã   rv   r@  r¨  rV   rº   r/  ru  rî	  ru   r   r	   r   r   r2  r2   )r  rÖ  rè   rï  Úactual_pathsr  rè  Útts_textr;  Úresult_jsonr·  r1  r¦  rí  r»  rî  Úin_voice_channelrõ	  rö	  Úactual_pathÚ
play_voiceÚsend_voice_callÚsend_kwargsr¨  s                           r>   rŸ  zGatewayRunner._send_voice_reply>M  s¸  è è € àˆ
Ø"$ˆðU	ØSÐSÐSÐSÐSÐSÐSÐSà.Ð.¨tÑ4Ô4ˆHØð ØðX "Ð1 LÐ1°T°FÑ:ð ð �ðÝ”I˜a‘L”L�L�LøÝð ð ð Ø�Dðøøøðð õK 4°E´LÔ4IÑJÔJˆJå 'Ô 1Ø#¨(À
ð!ñ !ô !ð ð ð ð ð ð ˆKðÝœ KÑ0Ô0��øÝÔ(­)Ð4ð ð ð Ý—’ÐOÐfqð  RCÐQ\Ð]aÐ^aÐ]aÔQbÐQbð  xCñ  Dô  Dð  DØðx "Ð1 LÐ1°T°FÑ:ð ð �ðÝ”I˜a‘L”L�L�LøÝð ð ð Ø�Dðøøøðð ð}øøøð "Ÿ:š: lÑ3Ô3ð Ø—
’
˜;¨
Ñ3Ô3ð8ˆLðð Ø&2ðñ ô ˆLð —:’:˜iÑ(Ô(ð °ð Ý—’Ð@À&Ç*Â*ÈWÑBUÔBUÑVÔVÐVØð\ "Ð1 LÐ1°T°FÑ:ð ð �ðÝ”I˜a‘L”L�L�LøÝð ð ð Ø�Dðøøøðð ðY ×.Ò.¨u¬|Ñ<Ô<ˆGð ×)Ò)¨%Ñ0Ô0ˆHÝ$+¨GÐ5LÈdÑ$SÔ$SÐ!Ý")¨'Ð3HÈ$Ñ"OÔ"OÐÝ  ¨,¸Ñ=Ô=ˆJÝ#Øð 2ÝÐ2Ñ3Ô3ð2åÐ0Ñ1Ô1ð2ð (Ð'¨Ñ1Ô1ñ	 ô  Ðð  ×7Ò7¸Ñ>Ô>ˆLØ×:Ò:¸5¼<ÈÑVÔVˆKØ#ð 3­°Ñ(<Ô(<ð 3ð Ð*Ý"& {Ñ"3Ô"3�KØ,0�K Ñ)Ð)à#+¨TÐ"2�KØ+ð 9ð 9�Ø#ð 9Ý!%¥h¨sµI½c´NÐ/BÔ&CÐEZÑ![Ô![�JØ$˜* X¨{Ñ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ý˜jÑ)Ô)ð 9Ý&*­8°C½Å3¼Ð4GÔ+HÈ*Ñ&UÔ&U�Oà#(¤<Ô#7Ø&1Ø$0Ø$/ð	3ð 3�Kð *˜/Ð8Ð8¨KÐ8Ð8Ð8Ð8Ð8Ð8Ð8Ð8Ð8øð9øõ ð 	Lð 	Lð 	LÝ�NŠNÐ8¸!ÀdˆNÑKÔKÐKÐKÐKÐKÐKÐKøøøøð	Løøøð "Ð1 LÐ1°T°FÑ:ð ð �ðÝ”I˜a‘L”L�L�LøÝð ð ð Ø�Dðøøøðð ø�zÐ1 LÐ1°T°FÑ:ð ð �ðÝ”I˜a‘L”L�L�LøÝð ð ð Ø�DðøøøðøøøsÊ   ˆM ª?¿
AÁAÁ6M ÂB ÂM Â=DÃM Ã'C<Ã<
D	ÄD	ÄDÄB M ÆF1Æ1
F>Æ=F>ÇFM ÍO Í
NÍ&NÎO ÎNÎO ÎN1Î1
N>Î=N>ÏO6ÏO%Ï$O6Ï%
O2	Ï/O6Ï1O2	Ï2O6Úthread_metadatac              ƒ   óH  ‡K  — ddl m} ddlmŠ 	 d|v }ddlm}m} |                     |¦  «        \  }	}
 |j        |	¦  «        }	| 	                    |
¦  «         |�t          |¦  «        n-|                      |j        |                      |¦  «        ¦  «        }h d£}h d£}g }g }|	D ]\\  }} ||¦  «        j                             ¦   «         }||v r|s|s|                     |¦  «         ŒE|                     ||f¦  «         Œ]|rp	 ˆfd	„|D ¦   «         }|                     |j        j        ||¬
¦  «        ƒ d{V —† n8# t&          $ r+}t(                               d|j        |¦  «         Y d}~nd}~ww xY w|D ]ö\  }}	  ||¦  «        j                             ¦   «         } ||j        j        ||¬¦  «        r)|                     |j        j        ||¬¦  «        ƒ d{V —† nU||v r)|                     |j        j        ||¬¦  «        ƒ d{V —† n(|                     |j        j        ||¬¦  «        ƒ d{V —† Œ¿# t&          $ r+}t(                               d|j        |¦  «         Y d}~Œïd}~ww xY wdS # t&          $ r&}t(                               d|¦  «         Y d}~dS d}~ww xY w)uÍ  Extract explicit MEDIA: tags from a response and deliver them.

        Called after streaming has already sent the text to the user, so the
        text itself is already delivered â€” this only handles file attachments
        that the normal _process_message_background path would have caught.

        Unlike the non-streaming path in ``gateway/platforms/base.py`` (which
        also auto-detects bare local paths via ``extract_local_files``), this
        post-stream rescan is EXPLICIT-ONLY. The visible reply has already
        been streamed verbatim, so a bare path string here was either (a)
        already shown to the user as text, or (b) stale tool/inspected
        content that was never part of the intended visible reply. Promoting
        such paths into uploads after the fact sent files the model never
        asked to deliver (#20834). Only ``MEDIA:`` directives â€” the explicit
        attachment contract â€” trigger post-stream uploads.
        r   r   )rŒ
  rL  )rG  Úshould_send_media_as_audioN¾   ú.3gpú.aviú.mkvú.movú.mp4ú.webm¾   ú.gifú.jpgú.pngú.jpegú.webpc                 ó0   •— g | ]}d  ‰|¦  «        › �df‘ŒS )zfile://r®   rN  )rb   r;  Ú_quotes     €r>   r  z>GatewayRunner._deliver_media_from_response.<locals>.<listcomp>êM  s/   ø€ ÐOÐOÐO¸aÐ4¨¨°©¬Ð4Ð4°bÐ9ÐOÐOÐOrM   )r2  Úimagesr¯   z0[%s] Post-stream image batch delivery failed: %s)Úis_voice©r2  rï  r¯   ©r2  Ú
video_pathr¯   ©r2  rU	  r¯   z*[%s] Post-stream media delivery failed: %sz'Post-stream media extraction failed: %s)Úpathlibr   Úurllib.parserŒ
  r	  rG  rû  rH  Úfilter_media_delivery_pathsÚextract_imagesru   rî	  r(  ru  r  ry   r”   Úsend_multiple_imagesr2  r2   r3   rã   rÖ   r�   rî  Ú
send_videoÚsend_document)r  rJ  rÖ  r1  rù  r   Úforce_document_attachmentsrG  rû  rJ  rM  Ú_thread_metaÚ_VIDEO_EXTSÚ_IMAGE_EXTSr×  Únon_image_mediaÚ
media_pathr  r   r  r¨  r
  s                        @r>   r   z*GatewayRunner._deliver_media_from_response™M  sH  øè è € ð. 	!Ð Ð Ð Ð Ð Ø0Ð0Ð0Ð0Ð0Ð0ðY	Ið
 *;¸hÐ)FÐ&à^Ð^Ð^Ð^Ð^Ð^Ð^Ð^à#*×#8Ò#8¸Ñ#BÔ#BÑ ˆK˜ØIÐ-ÔIÈ+ÑVÔVˆKð ×"Ò" 7Ñ+Ô+Ð+ð #Ð.õ �_Ñ%Ô%Ð%à×5Ò5Ø”LØ×0Ò0°Ñ7Ô7ñô ð ð LÐKÐKˆKØDÐDÐDˆKð !#ˆKØ$&ˆOØ(3ð Cð CÑ$�
˜HØ�d˜:Ñ&Ô&Ô-×3Ò3Ñ5Ô5�Ø˜;Ð&Ð&Ø (ð 'à :ð 'ð  ×&Ò& zÑ2Ô2Ð2Ð2à#×*Ò*¨J¸Ð+AÑBÔBÐBÐBàð 	hðhØOÐOÐOÐOÀ;ÐOÑOÔO�FØ!×6Ò6Ø %¤Ô 4Ø%Ø!-ð 7ñ ô ð ð ð ð ð ð ð ð øõ
 !ð hð hð hÝ—N’NÐ#UÐW^ÔWcÐefÑgÔgÐgÐgÐgÐgÐgÐgøøøøðhøøøð )8ð bð bÑ$�
˜HðbØ˜$˜zÑ*Ô*Ô1×7Ò7Ñ9Ô9�CØ1Ð1°%´,Ô2GÈÐW_Ð`Ñ`Ô`ð Ø%×0Ò0Ø$)¤LÔ$8Ø'1Ø%1ð 1ñ ô ð ð ð ð ð ð ð ð ð
  Ð+Ð+Ø%×0Ò0Ø$)¤LÔ$8Ø'1Ø%1ð 1ñ ô ð ð ð ð ð ð ð ð ð &×3Ò3Ø$)¤LÔ$8Ø&0Ø%1ð 4ñ ô ð ð ð ð ð ð ð øøõ
 !ð bð bð bÝ—N’NÐ#OÐQXÔQ]Ð_`ÑaÔaÐaÐaÐaÐaÐaÐaøøøøðbøøøð+bð bøõ0 ð 	Ið 	Ið 	IÝ�NŠNÐDÀaÑHÔHÐHÐHÐHÐHÐHÐHÐHøøøøð	Iøøøsm   ‘C5I1 Ä6D> Ä=I1 Ä>
E3Å!E.Å)I1 Å.E3Å3
I1 Å>B8H7È6I1 È7
I,É!I'É"I1 É'I,É,I1 É1
J!É;JÊJ!r¯   r:  Útext_already_deliveredÚdeliver_mediac              ƒ   óâ   K  — |s5t          ||¦  «        }|r#|                     |j        ||¬¦  «        ƒ d{V —† |sdS t          d||¬¦  «        }	|                      ||	||¬¦  «        ƒ d{V —† dS )zADeliver a queued response using the normal text+attachment split.r.  Nr®   )rè   r(  rj  )rù  )rN  r0  r2  rr  r   )
r  rJ  r(  r1  r¯   r:  r  r  Útext_contentr
  s
             r>   Ú_deliver_queued_first_responsez,GatewayRunner._deliver_queued_first_responseN  së   è è € ð &ð 	ÝFÀxÐQXÑYÔYˆLØð Ø—l’lØ”NØ Ø%ð #ñ ô ð ð ð ð ð ð ð ð ð 	ØˆFå&ØØØ'ð
ñ 
ô 
ˆð
 ×/Ò/ØØØØ$ð	 0ñ 
ô 
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
rM   rY	  r[  r'  rì  rÕ  c           	   ƒ   óB  K  — t          t          | dd¦  «        dd¦  «        s |                      ||||||¦  «        ƒ d{V —†S |                      |¦  «        }t          |¦  «        5  |                      ||||||¦  «        ƒ d{V —†cddd¦  «         S # 1 swxY w Y   dS )a>  Profile-scoping wrapper around the background agent task.

        When multiplexing is active, resolve the inbound source's profile and
        run the whole task inside ``_profile_runtime_scope`` so credentials
        resolve from that profile's secret scope. Mirrors the pattern in
        ``_run_agent``.
        rz   Nr½  F)rV   Ú_run_background_task_innerrÿ  rº  )r  rY	  r(  r'  r:  rì  rÕ  r®  s           r>   Ú_run_background_taskz"GatewayRunner._run_background_task5N  s3  è è € õ  •w˜t X¨tÑ4Ô4Ð6JÈEÑRÔRð 	Ø×8Ò8Ø˜ Ð)9¸:À{ñô ð ð ð ð ð ð ð ð ×<Ò<¸VÑDÔDˆÝ# LÑ1Ô1ð 	ð 	Ø×8Ò8Ø˜ Ð)9¸:À{ñô ð ð ð ð ð ð ð	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s   Á' BÂBÂBc              ƒ   ó  ‡ ‡‡‡#‡$‡%‡&‡'‡(‡)‡*‡+‡,K  — ddl mŠ# |pg }|pg }‰                      ‰¦  «        }|s#t                               d‰j        ‰¦  «         dS ‰                      ‰|¦  «        }	 t          ¦   «         Š,‰                      ‰‰,¬¦  «        \  }	}
|
 	                    d¦  «        s)| 
                    ‰j        d‰› d�|¬	¦  «        ƒ d{V —† dS t          ‰j        ¦  «        Š(dd
lm} t           |‰,‰(¦  «        ¦  «        Š%‰, 	                    d¦  «        pi }| 	                    d¦  «        pdŠ$‰ j        Š)t#          ¦   «         Š'‰                      ‰|	¬¦  «        Š*‰*‰ _        ‰                      ‰¬¦  «        ‰ _        ‰                      ||	|
¦  «        Š+|Š&|r°g }t/          |¦  «        D ]L\  }}|t1          |¦  «        k     r||         nd}|                     d¦  «        r|                     |¦  «         ŒM|rP	 ‰                      ||¦  «        ƒ d{V —†Š&n2# t8          $ r%}t                               d|¦  «         Y d}~nd}~ww xY wˆ#ˆ$ˆ%ˆ&ˆ'ˆ(ˆ)ˆ*ˆ ˆˆˆ+ˆ,fd„}‰                      |¦  «        ƒ d{V —†}|r| 	                    dd¦  «        nd}|s"|r | 	                    d¦  «        rd|d         › �}|�r|                     |¦  «        \  }}ddlm }  |j!        |¦  «        }| "                    |¦  «        \  }}|dd…         t1          |¦  «        dk    rdndz   }d|› d�}|r'| 
                    ‰j        ||z   |¬¦  «        ƒ d{V —† n*|s(|s&| 
                    ‰j        |dz   |¬¦  «        ƒ d{V —† |pg D ]:\  }}	 | #                    ‰j        |||¬¦  «        ƒ d{V —† Œ+# t8          $ r Y Œ7w xY wddlm$} h d£}h d £}|pg D ]ö\  } }!tJ          j&         '                    | ¦  «        d!          (                    ¦   «         }"	  |‰j        |"|!¦  «        r$| )                    ‰j        | |¬"¦  «        ƒ d{V —† ns|"|v r$| *                    ‰j        | |¬#¦  «        ƒ d{V —† nK|"|v r$| +                    ‰j        | |¬$¦  «        ƒ d{V —† n#| ,                    ‰j        | |¬%¦  «        ƒ d{V —† Œç# t8          $ r Y Œów xY wdS |dd…         t1          |¦  «        dk    rdndz   }| 
                    ‰j        d|› d&�|¬¦  «        ƒ d{V —† dS # t8          $ rg}t           -                    d'‰¦  «         	 | 
                    ‰j        d‰› d(|› �|¬¦  «        ƒ d{V —† n# t8          $ r Y n
w xY wY d}~dS Y d}~dS d}~ww xY w))zCExecute a background agent task and deliver the result to the chat.r   r8  z0No adapter for platform %s in background task %sN)r(  rA  rÅ  u   â�Œ Background task z, failed: no provider credentials configured.r.  ©Ú_get_platform_toolsrµ   r  )r(  r  r,  r®   rÙ  z,Background task vision enrichment failed: %sc                  ó(  •—  ‰d&d‰d         i‰d         ¤t          ‰¦  «        ¤i d‰“dd“dd“d‰“d	‰“d
‰“d‰	j        “d‰                     d¦  «        “d‰                     d¦  «        “d‰                     d¦  «        “d‰                     d¦  «        “d‰                     d¦  «        “d‰                     dd¦  «        “d‰                     d¦  «        “d‰“d‰“d‰
j        “d‰
j        “d‰
j        “d‰
j        “d‰
j        “d ‰
j        “d!‰
j	        “d"t          ‰	j        d#‰	j        ¦  «        “d$‰	                     ¦   «         “¤Ž} 	 |                      ‰‰¬%¦  «        ‰	                     | ¦  «         S # ‰	                     | ¦  «         w xY w)'Nr  r¿  r  r  Tr  Fr  r  r  r  r  r  r  r  r   r!  r"  r#  r$  r%  r&  r'  r(  rN   r�   r¹  r	  r)  r2  r*  r´  r›  rX   rS   r,  )r€  r'  rN  )r”  r’  rv   r¹  r	  r)  r2  r*  r´  r›  rV   rR   r£  rÇ  rd
  )rµ   r¨  r  r  Úenriched_promptr  r?  rÕ  r  r  r(  r'  rß  rA  s    €€€€€€€€€€€€€r>   r!  z:GatewayRunner._run_background_task_inner.<locals>.run_sync•N  sg  ø€ Ø˜ð ð Ø$ WÔ-ðà  Ô+ðõ /¨{Ñ;Ô;ðð ð ð $2 >ð	ð
  $˜tðð %* Eðð &6Ð%5ðð '8Ð&7ðð &6Ð%5ðð "&Ô!3Ð!3ðð '1§n¢nÐ5HÑ&IÔ&IÐ&Iðð ')§f¢f¨V¡n¤n nðð ')§f¢f¨XÑ&6Ô&6Ð&6ðð %'§F¢F¨7¡O¤O Oðð #%§&¢&¨¡.¤. .ðð  13·²Ð7KÈUÑ0SÔ0SÐ0Sð!ð" .0¯VªVÐ4EÑ-FÔ-FÐ-Fð#ð$  '˜wð%ð& *˜\ð'ð( #œN˜Nð)ð* !'Ô 2Ð 2ð+ð, %Ô.Ð.ð-ð. #œN˜Nð/ð0 %Ô.Ð.ð1ð2 %Ô.Ð.ð3ð4 %Ô.Ð.ð5õ6  ' tÔ'7¸ÀÔ@PÑQÔQÐQð7ð: $(×#?Ò#?Ñ#AÔ#AÐ#Að;ð �ð>9Ø ×1Ò1Ø%4Ø 'ð 2ñ ô ð
 ×1Ò1°%Ñ8Ô8Ð8Ð8ø�D×1Ò1°%Ñ8Ô8Ð8Ð8øøøs   ÅE: Å:Frò  rP   zError: rÏ  rø  r  u&   âœ… Background task complete
Prompt: "z"

rç
  z(No response generated))r2  rq  Úcaptionr¯   )rû  r  rü  r(   r  r  )r2  Ú
image_pathr¯   r  z"

(No response generated)zBackground task %s failedz	 failed: ).r	  r¨  r@  r3   rã   r�   rî	  rs   r�  rv   r0  r2  ru  Úhermes_cli.tools_configr(  r  rŽ  r¢  r�  r�  r‘  r’  r˜  rí  r7   r!  r”   rÄ  r2   rc
  rH  r	  rG  r  r  Ú
send_imagerû  r’   r™   r  ry   rî  r  Úsend_image_filer  rÛ   )-r  rY	  r(  r'  r:  rì  rÕ  r1  Ú_thread_metadatar  rÔ  r(  r�  r×  rî  r™   rÝ  r¨  r!  r·  rJ  rJ  rG  r  r!  r  Úheaderrq  Úalt_textÚ_should_send_media_as_audior  r  r  rF  rê  r¨  r  r  r*  r  r?  rÕ  r  rß  rA  s-   ` ``                               @@@@@@@@@@r>   r$  z(GatewayRunner._run_background_task_innerPN  s%	  øøøøøøøøøøøøøè è € ð 	&Ð%Ð%Ð%Ð%Ð%àÐ% 2ˆ
Ø!Ð' Rˆà×*Ò*¨6Ñ2Ô2ˆØð 	Ý�NŠNÐMÈvÌÐ`gÑhÔhÐhØˆFà×;Ò;¸FÐDTÑUÔUÐðv	Ý.Ñ0Ô0ˆKØ$(×$GÒ$GØØ'ð %Hñ %ô %Ñ!ˆE�>ð "×%Ò% iÑ0Ô0ð Ø—l’lØ”NØ`¨7Ð`Ð`Ð`Ø-ð #ñ ô ð ð ð ð ð ð ð ð
 �å/°´Ñ@Ô@ˆLàCÐCÐCÐCÐCÐCÝ%Ð&9Ð&9¸+À|Ñ&TÔ&TÑUÔUÐØ#Ÿš¨Ñ0Ô0Ð6°BˆIØ )§¢Ð.AÑ BÔ BÐ JÀdÐàÔ'ˆBÝ4Ñ6Ô6ˆNØ#×EÒEØ Uð  Fñ  ô  Ðð &6ˆDÔ"Ø!%×!CÒ!CÈ6Ð!CÑ!RÔ!RˆDÔØ×8Ò8¸ÀÈÑWÔWˆJð %ˆOØð ZØ �Ý(¨Ñ4Ô4ð 1ð 1‘G�A�tØ./µ#°kÑ2BÔ2BÒ.BÐ.B˜K¨œN˜NÈ�EØ×'Ò'¨Ñ1Ô1ð 1Ø#×*Ò*¨4Ñ0Ô0Ð0øØð ZðZØ04×0PÒ0PØ" Kñ1ô 1ð +ð +ð +ð +ð +ð +˜˜øõ %ð Zð Zð ZÝŸšÐ'UÐWXÑYÔYÐYÐYÐYÐYÐYÐYøøøøðZøøøð&9ð &9ð &9ð &9ð &9ð &9ð &9ð &9ð &9ð &9ð &9ð &9ð &9ð &9ð &9ð &9ð &9ðP  ×=Ò=¸hÑGÔGÐGÐGÐGÐGÐGÐGˆFà;AÐI�v—z’zÐ"2°BÑ7Ô7Ð7ÀrˆHØð 7 ð 7¨6¯:ª:°gÑ+>Ô+>ð 7Ø6 V¨G¤_Ð6Ð6�ð ñ MØ(/×(=Ò(=¸hÑ(GÔ(GÑ%�˜XØFÐFÐFÐFÐFÐFØMÐ1ÔMÈkÑZÔZ�Ø'.×'=Ò'=¸hÑ'GÔ'GÑ$�˜à   " œ+µ#°f±+´+ÀÒ2BÐ2B¨¨ÈÑK�ØQÀ7ÐQÐQÐQ�àð Ø!Ÿ,š,Ø &¤Ø &¨Ñ 5Ø!1ð 'ñ ô ð ð ð ð ð ð ð ð ð
  ð ¨ð Ø!Ÿ,š,Ø &¤Ø &Ð)BÑ BØ!1ð 'ñ ô ð ð ð ð ð ð ð ð -3¨L°bð 	ð 	Ñ'�I˜xðØ%×0Ò0Ø$*¤NØ&/Ø$,Ø%5ð	 1ñ ô ð ð ð ð ð ð ð ð øõ %ð ð ð Ø˜ðøøøðð ð ð ð ð ð IÐHÐH�ØOÐOÐO�Ø.9Ð.?¸Rð ð Ñ)�J 	Ýœ7×+Ò+¨JÑ7Ô7¸Ô:×@Ò@ÑBÔB�DðØ6Ð6°v´ÈÈiÑXÔXð Ø")×"4Ò"4Ø(.¬Ø+5Ø)9ð #5ñ #ô #ð ð ð ð ð ð ð ð ð
 " [Ð0Ð0Ø")×"4Ò"4Ø(.¬Ø+5Ø)9ð #5ñ #ô #ð ð ð ð ð ð ð ð ð
 " [Ð0Ð0Ø")×"9Ò"9Ø(.¬Ø+5Ø)9ð #:ñ #ô #ð ð ð ð ð ð ð ð ð #*×"7Ò"7Ø(.¬Ø*4Ø)9ð #8ñ #ô #ð ð ð ð ð ð ð øøõ
 %ð ð ð Ø˜ðøøøð7ð ð< !  " œ+µ#°f±+´+ÀÒ2BÐ2B¨¨ÈÑK�Ø—l’lØ"œNØkÀgÐkÐkÐkØ-ð #ñ ô ð ð ð ð ð ð ð ð ð øõ ð 		ð 		ð 		Ý×ÒÐ8¸'ÑBÔBÐBðØ—l’lØ"œNØH°7ÐHÐHÀQÐHÐHØ-ð #ñ ô ð ð ð ð ð ð ð ð øõ
 ð ð ð Ø�ðøøøðð ð ð ð ð ð �����øøøøð		øøøsÀ   Á/A$T ÃD*T È H ÈT È
IÈ'IÉT ÉIÉD:T Î$N,Î+T Î,
N9Î6T Î8N9Î9AT ÐB)R5Ò4T Ò5
SÒ?T ÓSÓT ÓA	T Ô
VÔU>Ô8)U"Õ!U>Õ"
U/Õ,U>Õ.U/Õ/U>Õ>Vc              ƒ   ób  ‡K  — |                       |¦  «        }t          |dd¦  «        }|�t          |d¦  «        sddiS 	 |                     ¦   «         ƒ d{V —†Šn0# t          $ r# t
                               dd¬¦  «         ddicY S w xY wd	t          fˆfd
„}d |d¦  «         |d¦  «        dœS )z?Read Telegram private-topic capability flags via Bot API getMe.Ú_botNÚget_meÚcheckedFz1Failed to fetch Telegram getMe topic capabilitiesTrß   rÖ   c                 ó  •— t          ‰| ¦  «        rt          ‰| ¦  «        S t          ‰dd ¦  «        }t          |t          ¦  «        r| |v r|                     | ¦  «        S t          ‰t          ¦  «        r‰                     | ¦  «        S d S )NÚ
api_kwargs)rá   rV   rt   ru   rv   )rÖ   r9  Úmes     €r>   Ú_fieldz>GatewayRunner._get_telegram_topic_capabilities.<locals>._field0O  s‹   ø€ Ý�r˜4Ñ Ô ð )Ý˜r 4Ñ(Ô(Ð(Ý   \°4Ñ8Ô8ˆJÝ˜*¥dÑ+Ô+ð ,°¸
Ð0BÐ0BØ!—~’~ dÑ+Ô+Ð+Ý˜"�dÑ#Ô#ð $Ø—v’v˜d‘|”|Ð#Ø�4rM   Úhas_topics_enabledÚallows_users_to_create_topics)r7  r<  r=  )r@  rV   rá   r6  r2   r3   r4   rw   )r  r(  r1  Úbotr;  r:  s        @r>   Ú _get_telegram_topic_capabilitiesz.GatewayRunner._get_telegram_topic_capabilities$O  s  øè è € à×*Ò*¨6Ñ2Ô2ˆÝ�g˜v tÑ,Ô,ˆØˆ;�g c¨8Ñ4Ô4ˆ;Ø˜uÐ%Ð%ð	&Ø—z’z‘|”|Ð#Ð#Ð#Ð#Ð#Ð#ˆBˆBøÝð 	&ð 	&ð 	&Ý�LŠLÐLÐW[ˆLÑ\Ô\Ð\Ø˜uÐ%Ð%Ð%Ð%ð	&øøøð	�ð 	ð 	ð 	ð 	ð 	ð 	ð Ø"( &Ð)=Ñ">Ô">Ø-3¨VÐ4SÑ-TÔ-Tð
ð 
ð 	
s   ÁA Á*B	ÂB	c              ƒ   óH  K  — |                       |¦  «        }|�|j        sdS d}t          |dd¦  «        }t          |¦  «        rR	  |t	          |j        ¦  «        d¦  «        ƒ d{V —†}n,# t
          $ r t                               dd¬¦  «         Y nw xY w|sdS d}	 |                     |j        ddt          |¦  «        i¬	¦  «        ƒ d{V —†}t          |d
d¦  «        }n,# t
          $ r t                               dd¬¦  «         Y nw xY w|sdS t          |dd¦  «        }|�t          |d¦  «        sdS 	 |                     t	          |j        ¦  «        t	          |¦  «        d¬¦  «        ƒ d{V —† dS # t
          $ r  t                               dd¬¦  «         Y dS w xY w)zJCreate/pin the managed System topic after /topic activation when possible.NÚ_create_dm_topicÚSystemz&Failed to create Telegram System topicTrß   z,System topic for Hermes commands and status.r›  r.  rj  z*Failed to send Telegram System topic intror5  Úpin_chat_message)r2  rj  Údisable_notificationz)Failed to pin Telegram System topic intro)r@  r2  rV   r/  rh  r2   r3   r4   r0  rw   rá   rC  )r  r(  r1  r›  Úcreate_topicrj  Úsend_resultr>  s           r>   Ú_ensure_telegram_system_topicz+GatewayRunner._ensure_telegram_system_topic@O  sU  è è € à×*Ò*¨6Ñ2Ô2ˆØˆ? &¤.ˆ?ØˆFàˆ	Ý˜wÐ(:¸DÑAÔAˆÝ�LÑ!Ô!ð 	VðVØ". ,­s°6´>Ñ/BÔ/BÀHÑ"MÔ"MÐMÐMÐMÐMÐMÐM�	�	øÝð Vð Vð VÝ—’ÐEÐPT�ÑUÔUÐUÐUÐUðVøøøàð 	ØˆFàˆ
ð	VØ '§¢Ø”Ø>Ø%¥s¨9¡~¤~Ð6ð !-ñ !ô !ð ð ð ð ð ð ˆKõ
 ! ¨l¸DÑAÔAˆJˆJøÝð 	Vð 	Vð 	VÝ�LŠLÐEÐPTˆLÑUÔUÐUÐUÐUð	Vøøøàð 	ØˆFå�g˜v tÑ,Ô,ˆØˆ;�g cÐ+=Ñ>Ô>ˆ;ØˆFð	UØ×&Ò&Ý˜FœNÑ+Ô+Ý˜z™?œ?Ø%)ð 'ñ ô ð ð ð ð ð ð ð ð ð øõ
 ð 	Uð 	Uð 	UÝ�LŠLÐDÈtˆLÑTÔTÐTÐTÐTÐTð	Uøøøs7   Á$A+ Á+&BÂBÂAC" Ã"&DÄ
DÄ8=E7 Å7&F!Æ F!c           	   ƒ   óð  K  — |                       |¦  «        }|�|j        rt          |d¦  «        sdS t          t          ¦  «                             ¦   «         j        dz  dz  }|                     ¦   «         sdS 	 |                     |j        t          |¦  «        d|j
        rdt          |j
        ¦  «        ind¬¦  «        ƒ d{V —† dS # t          $ r  t                               dd	¬
¦  «         Y dS w xY w)zFSend the bundled BotFather Threads Settings screenshot when available.Nr/  Úassetsz'telegram-botfather-threads-settings.jpgu/   BotFather â†’ Bot Settings â†’ Threads Settingsr›  )r2  r,  r+  r¯   z)Failed to send Telegram topic setup imageTrß   )r@  r2  rá   r   r�   r�   r‘   r˜   r/  rw   r›  r2   r3   r4   )r  r(  r1  r,  s       r>   Ú _send_telegram_topic_setup_imagez.GatewayRunner._send_telegram_topic_setup_imageiO  s4  è è € à×*Ò*¨6Ñ2Ô2ˆØˆ? &¤.ˆ?½ÀÐIZÑ8[Ô8[ˆ?ØˆFÝ�(‘^”^×+Ò+Ñ-Ô-Ô4°xÑ?ÐBkÑkˆ
Ø× Ò Ñ"Ô"ð 	ØˆFð	UØ×)Ò)ØœÝ˜z™?œ?ØIØAGÔAQÐ[˜+¥s¨6Ô+;Ñ'<Ô'<Ð=Ð=ÐW[ð	 *ñ ô ð ð ð ð ð ð ð ð ð øõ ð 	Uð 	Uð 	UÝ�LŠLÐDÈtˆLÑTÔTÐTÐTÐTÐTð	Uøøøs   Á;AC Ã&C5Ã4C5rÏ  c                 óà   — t          j        ddt          |pd¦  «        ¦  «                             ¦   «         }|sdS t	          |¦  «        dk    r|dd…                              ¦   «         dz   }|S )	zFReturn a Bot API-safe forum topic name from a generated session title.rÁ  r™  r®   úHermes Chatr  Néu   r  )r_   rõ   rw   rx   r7   r  ©r  rÏ  rM  s      r>   Ú_sanitize_telegram_topic_titlez,GatewayRunner._sanitize_telegram_topic_title{O  sp   € å”&˜ ¥c¨%¨+°2Ñ&6Ô&6Ñ7Ô7×=Ò=Ñ?Ô?ˆØð 	!Ø �=õ ˆw‰<Œ<˜#ÒÐØ˜d˜s˜d”m×*Ò*Ñ,Ô,¨uÑ4ˆGØˆrM   c                 óâ   — |j         t          j        k    oZ|j        dk    oOt	          t          |dd¦  «        ¦  «        o1t	          |j        ¦  «        ot	          t          |dd¦  «        ¦  «        S )z>Return True only for Discord threads Hermes just auto-created.r¶  Úauto_thread_createdFÚauto_thread_initial_nameN)r�   rÄ  r±  r´  rº   rV   r›  rX  s     r>   r×  z*GatewayRunner._is_discord_auto_thread_lane†O  s{   € ð ŒO�xÔ/Ò/ð HØÔ  HÒ,ðHå•W˜VÐ%:¸EÑBÔBÑCÔCðHõ �VÔ%Ñ&Ô&ðHõ •W˜VÐ%?ÀÑFÔFÑGÔGð	
rM   c                 óœ   — |j         t          j        k    o7t          |j        ¦  «        o#|j         o|j        dv ot          |dd¦  «        du S )aT  Shape-only check: a relay-delivered Discord CHANNEL event whose
        reply the connector MAY auto-thread (title-turn registration gate).

        Deliberately does NOT consult the send-result cache: at registration
        time (before delivery) the feedback can't exist yet. The rename lane
        polls the cache at fire time instead.)rð   rÌ  Údelivered_via_upstream_relayFT)r�   rÄ  r±  rº   r2  r›  r´  rV   rX  s     r>   rØ  z,GatewayRunner._is_relay_discord_channel_lane�O  si   € ð ŒO�xÔ/Ò/ð OÝ�V”^Ñ$Ô$ðOàÔ$Ð$ðOð Ô Ð$8Ð8ðOõ ˜Ð >ÀÑFÔFÈ$ÐNð	
rM   c                 ó’  — |j         t          j        k    s|j        sdS t	          |dd¦  «        sdS t	          |dd¦  «        }|rt          |¦  «        dfS |                      |¦  «        }t	          |dd¦  «        }t          |¦  «        sdS 	 t           |t          |j        ¦  «        ¦  «        ¦  «        S # t          $ r Y dS w xY w)uT  (thread_id, initial_name) when the RELAY connector auto-threaded our
        reply to this source's chat â€” the title-turn sibling of
        _is_discord_auto_thread_lane.

        The marker-based check above only lights up for events ARRIVING IN an
        auto-created thread (turn 2+). The auto-title fires on the FIRST
        exchange, whose source is the PARENT channel event â€” the thread did
        not exist at ingest, so no markers can be present and the native lane
        check never matches on the relay title turn (staging repro
        2026-07-29: initial titles fine, semantic renames never happened).

        Preferred path: the connector stamps ``prospective_thread_id`` on the
        inbound (the anchor message id, which IS the id of the thread it will
        auto-create). It's deterministic and per-message, so it identifies the
        EXACT thread even when several auto-threads spawn from one channel â€”
        unlike the send-result cache below, which held a single slot per parent
        chat and so only the FIRST thread in a channel ever renamed (staging
        repro 2026-08-02: thread A renamed, sibling thread B stuck at raw
        text). The connector's own created-name guard (prefer_connector_created)
        enforces no-clobber, so no initial name is needed here.

        Fallback: the connector reports where the reply actually landed on the
        send result (contract Â§SendResult thread_id/auto_thread_name); the
        relay adapter caches it per chat and this reads it back â€” kept for
        older connectors that don't stamp prospective_thread_id.
        NrT  FÚprospective_thread_idr®   Úauto_thread_info_for_chat)
r�   rÄ  r±  r2  rV   rw   r@  r/  r‚  r2   )r  r(  Úprospectiver1  Úinfo_fns        r>   Ú_relay_auto_thread_infoz%GatewayRunner._relay_auto_thread_infoŸO  sì   € ð: Œ?�hÔ.Ò.Ð.°f´nÐ.Ø�4Ý�vÐ=¸uÑEÔEð 	Ø�4Ý˜fÐ&=¸tÑDÔDˆØð 	*õ ˜Ñ$Ô$ bÐ)Ð)Ø×*Ò*¨6Ñ2Ô2ˆÝ˜'Ð#>ÀÑEÔEˆÝ˜Ñ Ô ð 	Ø�4ð	Ý" 7 7­3¨v¬~Ñ+>Ô+>Ñ#?Ô#?Ñ@Ô@Ð@øÝð 	ð 	ð 	Ø�4�4ð	øøøs   Â)B8 Â8
CÃCc              ƒ   ó^  K  — |                       |¦  «        }|�|S |                      |¦  «        }t          |dd¦  «        }t          |¦  «        r|j        sdS t          dd¦  «        pd}	 t           |t          |j        ¦  «        |¦  «        ƒ d{V —†¦  «        S # t          $ r Y dS w xY w)u³  ``_relay_auto_thread_info``, waited out until this turn delivers.

        The legacy send-result path can only answer once the reply is sent, and
        the caller asks at title time â€” one turn early. The adapter answers on
        the send either way, so the timeout is only a backstop for a turn that
        never sends at all; the turn's own inactivity limit is exactly how long
        that turn could still be alive.
        NÚwait_for_auto_thread_infor  r  )	rZ  r@  rV   r/  r2  r„  r‚  rw   r2   )r  r(  Úknownr1  Úwait_fnrÓ  s         r>   Ú_await_relay_auto_thread_infoz+GatewayRunner._await_relay_auto_thread_infoÎO  sÛ   è è € ð ×,Ò,¨VÑ4Ô4ˆØÐØˆLØ×*Ò*¨6Ñ2Ô2ˆÝ˜'Ð#>ÀÑEÔEˆÝ˜Ñ Ô ð 	¨¬ð 	Ø�4åÐ3°TÑ:Ô:ÐB¸dˆð	Ý"¨¨µ°V´^Ñ1DÔ1DÀgÑ)NÔ)NÐ#NÐ#NÐ#NÐ#NÐ#NÐ#NÑOÔOÐOøÝð 	ð 	ð 	Ø�4�4ð	øøøs   Á-0B Â
B,Â+B,c                 óì   — t          j        ddt          |pd¦  «        ¦  «                             ¦   «         }|sdS t	          |¦  «        dk    r%t          |d¦  «                             ¦   «         dz   }|S )a  Return a Discord-safe semantic thread title from a session title.

        Discord thread names are capped at 100 characters measured in UTF-16
        code units (emoji count double), so truncate with the UTF-16 helpers
        rather than Python code-point slices.
        rÁ  r™  r®   rL  r  éM   r  )r_   rõ   rw   rx   rx  rt  r  rN  s      r>   Ú_sanitize_discord_thread_titlez,GatewayRunner._sanitize_discord_thread_titleéO  st   € õ ”&˜ ¥c¨%¨+°2Ñ&6Ô&6Ñ7Ô7×=Ò=Ñ?Ô?ˆØð 	!Ø �=Ý�WÑÔ Ò"Ð"Ý0°¸"Ñ=Ô=×DÒDÑFÔFÈÑNˆGØˆrM   Ú
relay_infoc              ƒ   ó.  K  — |€Vt          j        | j        |¦  «        ƒ d{V —†s6|                      |¦  «        sdS |                      |¦  «        ƒ d{V —†}|€dS t          | dd¦  «        r|                      |¦  «        nd}|€dS t          |dd¦  «        }|€dS |r|d         nt          |j        ¦  «        }|du}|rdnt          |dd¦  «        }	|  	                    |¦  «        }
|r|j
        rt          |j
        ¦  «        nd}t                               d||rdnd|
¦  «         	  |||
||	|¬	¦  «        ƒ d{V —†}t                               d
|t          |¦  «        ¦  «         dS # t          $ r  t                               dd¬¦  «         Y dS w xY w)uÄ  Best-effort semantic rename of a newly auto-created Discord thread.

        ``relay_info`` is the (thread_id, initial_name) pair from the relay
        connector's send-result feedback â€” supplied on the title turn, where
        the source is the parent-channel event and carries no auto-thread
        markers (see _relay_auto_thread_info). When absent, the native
        marker-based lane supplies thread identity from the source itself.
        Nr°  Úrename_threadr   rR  z:discord auto-thread rename: thread=%s lane=%s new_title=%rÚrelayr   )Úprefer_connector_createdÚonly_if_current_nameré  z7discord auto-thread rename result: thread=%s applied=%sz@Failed to rename Discord auto-thread for generated session titleTrß   )r  r  r×  rØ  r_  rV   r@  rw   r›  rb  r2  r3   rz  rº   r2   r4   )r  r(  rN   rÏ  rc  r1  re  Útarget_thread_idÚuse_connector_guardÚ
guard_namerÿ  ré  Úrenameds                r>   Ú-_rename_discord_auto_thread_for_session_titlez;GatewayRunner._rename_discord_auto_thread_for_session_title÷O  sX  è è € ð Ð­GÔ,=ØÔ-¨vñ-
ô -
ð '
ð '
ð '
ð '
ð '
ð '
Ðð ×6Ò6°vÑ>Ô>ð Ø�Ø#×AÒAÀ&ÑIÔIÐIÐIÐIÐIÐIÐIˆJØÐ!ð �Ý6=¸dÀJÐPTÑ6UÔ6UÐ_�$×*Ò*¨6Ñ2Ô2Ð2Ð[_ˆØˆ?ØˆFÝ ¨¸$Ñ?Ô?ˆØÐ ØˆFØ,6ÐQ˜: aœ=˜=½CÀÔ@PÑ<QÔ<QÐð )°Ð4Ðð #ðCˆDˆDå˜Ð!;¸TÑBÔBð 	ð
 ×9Ò9¸%Ñ@Ô@ˆð $7ÐS¸6¼>ÐS�C�”ÑÔÐÈtð 	õ 	�ŠØHØØ*Ð8ˆGˆG°Øñ		
ô 	
ð 	
ð	lØ)˜MØ ØØ)<Ø%/Ø-ðñ ô ð ð ð ð ð ð ˆGõ �KŠKØIØ Ý�W‘”ñô ð ð ð øõ
 ð 	lð 	lð 	lÝ�LŠLÐ[ÐfjˆLÑkÔkÐkÐkÐkÐkð	løøøs   Ä)?E* Å*&FÆFc                 ó  — d}|sdS |                       |¦  «        s.|                      |¦  «        }|€|                      |¦  «        sdS 	 t          j        ¦   «         }n!# t
          $ r t          | dd¦  «        }Y nw xY w|�|                     ¦   «         rdS 	 t          j	        |¦  «        }n# t          $ r |}Y nw xY wt          |                      ||||¬¦  «        |t          d¬¦  «        }|€dS dd„}|                     |¦  «         dS )	zJSchedule Discord auto-thread rename from the auto-title background thread.Nr“  )rc  z1Discord semantic thread rename failed to scheduler¬  r-   c                 óŠ   — 	 |                       ¦   «          d S # t          $ r  t                               dd¬¦  «         Y d S w xY w)Nz%Discord semantic thread rename failedTrß   ©r·  r2   r3   r4   ©rÝ  s    r>   Ú_log_rename_failurezSGatewayRunner._schedule_discord_semantic_thread_rename.<locals>._log_rename_failurezP  sX   € ðUØ—
’
‘”���øÝð Uð Uð UÝ—’ÐDÈt�ÑTÔTÐTÐTÐTÐTðUøøøó   ‚ ˜&AÁArŽ  )r×  rZ  rØ  r  r!
  r¾  rV   Ú	is_closedri  rl  r2   r   rm  r3   rä  )	r  r(  rN   rÏ  rc  rØ   Úcopied_sourcerÜ   rr  s	            r>   rÒ  z6GatewayRunner._schedule_discord_semantic_thread_renameNP  s  € ð ˆ
Øð 	ØˆFØ×0Ò0°Ñ8Ô8ð 	ð ×5Ò5°fÑ=Ô=ˆJØÐ!¨$×*MÒ*MØñ+ô +Ð!ð �ð	8ÝÔ+Ñ-Ô-ˆDˆDøÝð 	8ð 	8ð 	8Ý˜4 °$Ñ7Ô7ˆDˆDˆDð	8øøøàˆ<˜4Ÿ>š>Ñ+Ô+ˆ<ØˆFð	#Ý'Ô/°Ñ7Ô7ˆMˆMøÝð 	#ð 	#ð 	#Ø"ˆMˆMˆMð	#øøøå)Ø×>Ò>Ø˜z¨5¸Zð ?ñ ô ð ÝØKð
ñ 
ô 
ˆð ˆ>ØˆFð	Uð 	Uð 	Uð 	Uð 	× Ò Ð!4Ñ5Ô5Ð5Ð5Ð5s$   ÁA ÁA=Á<A=ÂB. Â.B=Â<B=c              ƒ   óØ  K  — t          j        | j        |¦  «        ƒ d{V —†r|j        r|j        sdS |                      |¦  «        rdS |                      |¦  «        }|�‰t          t          |¦  «        dd¦  «        }t          |¦  «        r\	  ||t          |j        ¦  «        t          |j        ¦  «        ¦  «        }n# t          $ r d}Y nw xY wt          |t          ¦  «        rdS t          | dd¦  «        }|�©	 |                     t          |j        ¦  «        t          |j        ¦  «        ¬¦  «        ƒ d{V —†}|r7t          |                     d¦  «        pd¦  «        t          |¦  «        k    rdS n-# t          $ r  t                                dd¬	¦  «         Y dS w xY w|€dS |                      |¦  «        }		 t          |d
d¦  «        }
|
�: |
t          |j        ¦  «        t          |j        ¦  «        |	¬¦  «        ƒ d{V —† dS t          |dd¦  «        }|�t          |dd¦  «        nd}|€|�t          |dd¦  «        nd}|€dS 	  |t'          |j        ¦  «        t'          |j        ¦  «        |	¬¦  «        ƒ d{V —† dS # t(          t*          f$ r"  ||j        |j        |	¬¦  «        ƒ d{V —† Y dS w xY w# t          $ r  t                                dd¬	¦  «         Y dS w xY w)zLBest-effort rename of a Telegram DM topic when Hermes auto-titles a session.NÚ_get_dm_topic_inforR   r  rN   r®   z5Failed to verify Telegram topic binding before renameTrß   Úrename_dm_topic)r2  r›  rÖ   r5  Úedit_forum_topicÚeditForumTopic)r2  Úmessage_thread_idrÖ   z8Failed to rename Telegram topic for auto-generated title)r  r  rÕ  r2  r›  Ú$_telegram_topic_auto_rename_disabledr@  rV   rÎ   r/  rw   r2   rt   ru   rq  rv   r3   r4   rO  rh  rw  rj  )r  r(  rN   rÏ  r1  Úget_infoÚoperator_topicrX   r©  Ú
topic_nameÚrename_topicr>  ry  s                r>   Ú(_rename_telegram_topic_for_session_titlez6GatewayRunner._rename_telegram_topic_for_session_title‚P  s  è è € õ Ô& tÔ'CÀVÑLÔLÐLÐLÐLÐLÐLÐLð 	ÐTZÔTbð 	ÐjpÔjzð 	ØˆFð ×4Ò4°VÑ<Ô<ð 	ØˆFð ×*Ò*¨6Ñ2Ô2ˆØÐÝ�t G™}œ}Ð.BÀDÑIÔIˆHÝ˜Ñ!Ô!ð ð*Ø%- X¨gµs¸6¼>Ñ7JÔ7JÍCÐPVÔP`ÑLaÔLaÑ%bÔ%b�N�NøÝ ð *ð *ð *Ø%)�N�N�Nð*øøøõ ˜n­dÑ3Ô3ð Ø�Få˜T =°$Ñ7Ô7ˆ
ØÐ!ð	Ø *× EÒ EÝ ¤Ñ/Ô/Ý! &Ô"2Ñ3Ô3ð !Fñ !ô !ð ð ð ð ð ð �ð ð �s 7§;¢;¨|Ñ#<Ô#<Ð#BÀÑCÔCÅsÈ:ÁÄÒVÐVØ�FøøÝð ð ð Ý—’ÐTÐ_c�ÑdÔdÐdØ��ðøøøð ˆ?ØˆFØ×8Ò8¸Ñ?Ô?ˆ
ð	dÝ" 7Ð,=¸tÑDÔDˆLØÐ'Ø"�lÝ ¤Ñ/Ô/Ý! &Ô"2Ñ3Ô3Ø#ðñ ô ð ð ð ð ð ð ð ð
 �å˜' 6¨4Ñ0Ô0ˆCØILÈ�w sÐ,>ÀÑEÔEÐEÐ^bÐØÐ'ØKNÈ?¥7¨3Ð0@À$Ñ#GÔ#GÐ#GÐ`dÐ ØÐ'Ø�ðØ&Ð&Ý ¤Ñ/Ô/Ý&)¨&Ô*:Ñ&;Ô&;Ø#ðñ ô ð ð ð ð ð ð ð ð ð øõ
 �zÐ*ð ð ð Ø&Ð&Ø"œNØ&,Ô&6Ø#ðñ ô ð ð ð ð ð ð ð ð ð ð ðøøøøõ ð 	dð 	dð 	dÝ�LŠLÐSÐ^bˆLÑcÔcÐcÐcÐcÐcð	døøøs\   Â1C ÃCÃCÃ>A8E9 Å9&F#Æ"F#Ç AJ? È?J? É8J	 Ê	/J<Ê8J? Ê;J<Ê<J? Ê?&K)Ë(K)c                 óÂ  — t          | dd¦  «        r:t          | j        dd¦  «        r$| j        j                             |j        ¦  «        nd}|€dS t          |dd¦  «        pi }|                     d¦  «        }|€dS t          |t          ¦  «        r|S t          |t          ¦  «        r(|                     ¦   «          	                    ¦   «         dv S t          |¦  «        S )züReturn True when operator disabled per-topic auto-rename for this Telegram chat.

        Controlled via ``gateway.platforms.telegram.extra.disable_topic_auto_rename``.
        Default is False (auto-rename enabled, preserves prior behaviour).
        rz   NrE  FrÁ  Údisable_topic_auto_rename>   ro   rp   rq   rr   )
rV   rz   rE  rv   r�   rt   rº   rw   rx   ry   )r  r(  rG  rÁ  r­   s        r>   r|  z2GatewayRunner._telegram_topic_auto_rename_disabled×P  sæ   € õ �t˜X tÑ,Ô,ðÝ18¸¼ÀkÐSWÑ1XÔ1XðˆDŒKÔ!×%Ò% f¤oÑ6Ô6Ð6àð 	ð
 ÐØ�5Ý˜ g¨tÑ4Ô4Ð:¸ˆØ—	’	Ð5Ñ6Ô6ˆØˆ=Ø�5Ý�e�TÑ"Ô"ð 	ØˆLÝ�e�SÑ!Ô!ð 	GØ—;’;‘=”=×&Ò&Ñ(Ô(Ð,FÐFÐFÝ�E‰{Œ{ÐrM   c                 óæ  — |r|                       |¦  «        sdS |                      |¦  «        rdS 	 t          j        ¦   «         }n!# t          $ r t          | dd¦  «        }Y nw xY w|�|                     ¦   «         rdS 	 t          j        |¦  «        }n# t          $ r |}Y nw xY wt          |                      |||¦  «        |t          d¬¦  «        }|€dS dd„}|                     |¦  «         dS )z>Schedule a topic rename from the auto-title background thread.Nr“  z.Telegram topic title rename failed to scheduler¬  r-   c                 óŠ   — 	 |                       ¦   «          d S # t          $ r  t                               dd¬¦  «         Y d S w xY w)Nz"Telegram topic title rename failedTrß   rp  rq  s    r>   rr  zPGatewayRunner._schedule_telegram_topic_title_rename.<locals>._log_rename_failureQ  sX   € ðRØ—
’
‘”���øÝð Rð Rð RÝ—’ÐAÈD�ÑQÔQÐQÐQÐQÐQðRøøørs  rŽ  )rÕ  r|  r  r!
  r¾  rV   rt  ri  rl  r2   r   r�  r3   rä  )r  r(  rN   rÏ  rØ   ru  rÜ   rr  s           r>   rÍ  z3GatewayRunner._schedule_telegram_topic_title_renameîP  sM  € ð ð 	˜D×8Ò8¸Ñ@Ô@ð 	ØˆFØ×4Ò4°VÑ<Ô<ð 	ØˆFð	8ÝÔ+Ñ-Ô-ˆDˆDøÝð 	8ð 	8ð 	8Ý˜4 °$Ñ7Ô7ˆDˆDˆDð	8øøøàˆ<˜4Ÿ>š>Ñ+Ô+ˆ<ØˆFð	#Ý'Ô/°Ñ7Ô7ˆMˆMøÝð 	#ð 	#ð 	#Ø"ˆMˆMˆMð	#øøøå)Ø×9Ò9¸-ÈÐUZÑ[Ô[ØÝØHð	
ñ 
ô 
ˆð ˆ>ØˆFð	Rð 	Rð 	Rð 	Rð 	× Ò Ð!4Ñ5Ô5Ð5Ð5Ð5s#   ²A ÁA$Á#A$Â B ÂB$Â#B$r-  c                 ó  — t          | d¦  «        si | _        t          |j        pd¦  «        }|sdS ddl}|                     ¦   «         }| j                             |d¦  «        }||z
  | j        k     rdS || j        |<   dS )zÑRate-limit the BotFather Threads Settings screenshot.

        If a user sends /topic repeatedly while Threads Settings are still
        off, we shouldn't keep re-uploading the screenshot every time.
        Ú_telegram_capability_hint_tsr®   Tr   Nr@  F)rá   r‡  rw   r2  rU   r—  rv   Ú$_TELEGRAM_CAPABILITY_HINT_COOLDOWN_SrP  s         r>   Ú%_should_send_telegram_capability_hintz3GatewayRunner._should_send_telegram_capability_hintQ  sœ   € õ �tÐ;Ñ<Ô<ð 	3Ø02ˆDÔ-Ý�f”nÐ*¨Ñ+Ô+ˆØð 	Ø�4ØÐÐÐØ�oŠoÑÔˆØÔ0×4Ò4°W¸cÑBÔBˆØ�‰:˜ÔAÒAÐAØ�5Ø58ˆÔ)¨'Ñ2ØˆtrM   c                 ó   — 	 dS )Nuz  /topic â€” enable multi-session DM mode (one bot, many parallel chats)

Usage:
  /topic             Enable topic mode, or show status if already on
  /topic help        Show this message
  /topic off         Disable topic mode and clear topic bindings
  /topic <id>        Inside a topic: restore a previous session by ID

How it works:
1. Run /topic once in this DM â€” Hermes checks BotFather Threads
   Settings are enabled and flips on multi-session mode.
2. Tap All Messages at the top of the bot and send any message.
   Telegram creates a new topic for that message; each topic is
   an independent Hermes session (fresh history, fresh context).
3. The root DM becomes a system lobby â€” send /topic, /status,
   /help, /usage there. Normal prompts go in a topic.
4. /new inside a topic resets just that topic's session.
5. /topic <id> inside a topic restores an old session into it.rN  rN  s    r>   Ú_telegram_topic_help_textz'GatewayRunner._telegram_topic_help_text(Q  s   € ðMð	
ð 	
rM   c              ƒ   ó\  K  — | j         sddlm}  |t          d¦  «        ¬¦  «        S t	          |j        pd¦  «        }|sdS 	 | j                              |t	          |j        pd¦  «        ¬¦  «        ƒ d{V —†}n# t          $ r d	}Y nw xY w|sd
S 	 | j          	                    |¬¦  «        ƒ d{V —† n6# t          $ r)}t                               d¦  «         d|› �cY d}~S d}~ww xY wdD ]>}t          | |d¦  «        }t          |t          ¦  «        r|                     |d¦  «         Œ?	 dS )z5Cleanly disable topic mode for a chat via /topic off.r   )Úformat_session_db_unavailablez,gateway.shared.session_db_unavailable_prefix)r  r®   zCould not determine chat ID.rC  NFz@Multi-session topic mode is not currently enabled for this chat.rÊ  z%Failed to disable Telegram topic modezFailed to disable topic mode: )rN  r‡  ué   Multi-session topic mode is now OFF for this chat.

Existing topics in Telegram aren't removed â€” they'll just stop being gated as independent sessions. The root DM works as a normal Hermes chat again. Run /topic to re-enable later.)rR   r°  r�  r   rw   r2  rD  r¹  r2   Údisable_telegram_topic_moder3   rÛ   rV   rt   ru   rU  )r  r(  r�  r2  Úcurrently_enabledr<   ré  Ústores           r>   Ú%_disable_telegram_topic_mode_for_chatz3GatewayRunner._disable_telegram_topic_mode_for_chat>Q  sÔ  è è € àÔð 	kØBÐBÐBÐBÐBÐBØ0Ð0½Ð:hÑ8iÔ8iÐjÑjÔjÐjÝ�f”nÐ*¨Ñ+Ô+ˆØð 	2Ø1Ð1ð	&Ø&*Ô&6×&UÒ&UØÝ˜FœNÐ0¨bÑ1Ô1ð 'Vñ 'ô 'ð !ð !ð !ð !ð !ð !ÐÐøõ ð 	&ð 	&ð 	&Ø %ÐÐÐð	&øøøà ð 	VØUÐUð	:ØÔ"×>Ò>ÀwÐ>ÑOÔOÐOÐOÐOÐOÐOÐOÐOÐOøÝð 	:ð 	:ð 	:Ý×ÒÐDÑEÔEÐEØ9°CÐ9Ð9Ð9Ð9Ð9Ð9Ð9Ð9øøøøð	:øøøð
 Tð 	)ð 	)ˆDÝ˜D $¨Ñ-Ô-ˆEÝ˜%¥Ñ&Ô&ð )Ø—	’	˜' 4Ñ(Ô(Ð(øðGð	
ð 	
s0   Á6A; Á;B
Â	B
Â!B4 Â4
C'Â>C"ÃC'Ã"C'c           
   ƒ   óH  K  — g d¢}	 | j                              t          |j        ¦  «        t          |j        ¦  «        d¬¦  «        ƒ d {V —†}n.# t
          $ r! t                               dd¬¦  «         g }Y nw xY w|rø|                     d¦  «         |D ]¨}t          | 	                    d¦  «        pd	¦  «        }t          | 	                    d
¦  «        pd¦  «        }t          | 	                    d¦  «        pd	¦  «         
                    ¦   «         }d|› d|› d�}|r|d|› �z  }|                     |¦  «         Œ©|                     d	dddd|d          	                    d¦  «        › d�g¦  «         n|                     g d¢¦  «         d                     |¦  «        S )N)z*Telegram multi-session topics are enabled.r®   z”To create a new Hermes chat, open All Messages at the top of this bot interface and send any message there. Telegram will create a new topic for it.r®   rG  )r2  r¹  Úlimitz)Failed to list unlinked Telegram sessionsTrß   zPrevious unlinked sessions:rÍ   r®   rÏ  zUntitled sessionr  z- u    â€” `r  r2
  zTo restore one:ú]1. Create or open a topic. To create a new one, open All Messages and send any message there.ú.2. Send /topic <session-id> inside that topic.zExample: Send /topic r   z inside a topic.)z-No previous unlinked Telegram sessions found.r®   z$To restore a previous session later:r”  r•  r  )rR   Ú(list_unlinked_telegram_sessions_for_userrw   r2  r¹  r2   r3   r4   r”   rv   rx   Úextendrf   )	r  r(  rq  r“  râ	  rN   rÏ  r  r[  s	            r>   Ú#_telegram_topic_root_status_messagez1GatewayRunner._telegram_topic_root_status_messagecQ  s  è è € ð
ð 
ð 
ˆð	Ø!Ô-×VÒVÝ˜FœNÑ+Ô+Ý˜FœNÑ+Ô+Øð Wñ ô ð ð ð ð ð ð ˆHˆHøõ
 ð 	ð 	ð 	Ý�LŠLÐDÈtˆLÑTÔTÐTØˆHˆHˆHð	øøøð ð 	Ø�LŠLÐ6Ñ7Ô7Ð7Ø#ð #ð #�Ý  §¢¨TÑ!2Ô!2Ð!8°bÑ9Ô9�
Ý˜GŸKšK¨Ñ0Ô0ÐFÐ4FÑGÔG�Ý˜gŸkšk¨)Ñ4Ô4Ð:¸Ñ;Ô;×AÒAÑCÔC�Ø6˜EÐ6Ð6¨Ð6Ð6Ð6�Øð .ØÐ- GÐ-Ð-Ñ-�DØ—’˜TÑ"Ô"Ð"Ð"Ø�LŠLØØ!ØoØ@ØO¨°¬¯ª¸Ñ(=Ô(=ÐOÐOÐOðñ ô ð ð ð �LŠLð ð ð ñ ô ð ð �yŠy˜ÑÔÐs   ˆAA Á(A;Á:A;Úraw_session_idc              ƒ   óÄ  K  — |j         }| j                             |                     ¦   «         ¦  «        ƒ d{V —†}|sd|                     ¦   «         › �S | j                             |¦  «        ƒ d{V —†}|sd|                     ¦   «         › �S t          |                     d¦  «        pd¦  «        dk    rdS t          |                     d¦  «        pd¦  «        t          |j        ¦  «        k    rdS | j                             |¬	¦  «        ƒ d{V —†}| j         	                    t          |j
        ¦  «        t          |j        ¦  «        ¬
¦  «        ƒ d{V —†}|r|r|                     d¦  «        |k    rdS |                      |¦  «        }	 | j                             t          |j
        ¦  «        t          |j        ¦  «        t          |j        ¦  «        ||d¬¦  «        ƒ d{V —† n*# t          $ r}	dt          |	¦  «        v rY d}	~	dS ‚ d}	~	ww xY w| j                             |¦  «        ƒ d{V —†p|}
d}	 t!          | j                             |¦  «        ƒ d{V —†¦  «        D ]T}|                     d¦  «        dk    r9|                     d¦  «        r$t          |                     d¦  «        ¦  «        } nŒUn# t$          $ r d}Y nw xY wd|
› �}|r|d|› �z  }|S )zBRestore an existing Telegram-owned Hermes session into this topic.NzSession not found: r(  r®   rY  zNThat session is not a Telegram session and cannot be restored into this topic.r¹  z3That session does not belong to this Telegram user.r~  r  rN   z9That session is already linked to another Telegram topic.Úrestored)r2  r›  r¹  r+   rN   Úmanaged_modezalready linkedr¦  r­  r4  zSession restored: z

Last Hermes message:
)r(  rR   Úresolve_session_idrx   r�  rw   rv   r¹  Ú#is_telegram_session_linked_to_topicrq  r2  r›  rA  r[  rj  Úget_session_titler  Úget_messagesr2   )r  rÖ  r™  r(  rN   râ	  ÚlinkedÚcurrent_bindingr+   r<   rÏ  Úlast_assistantr$  rJ  s                 r>   Ú_restore_telegram_topic_sessionz-GatewayRunner._restore_telegram_topic_session‘Q  s¤  è è € à”ˆØÔ+×>Ò>¸~×?SÒ?SÑ?UÔ?UÑVÔVÐVÐVÐVÐVÐVÐVˆ
Øð 	BØA¨×)=Ò)=Ñ)?Ô)?ÐAÐAÐAàÔ(×4Ò4°ZÑ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@ˆØð 	BØA¨×)=Ò)=Ñ)?Ô)?ÐAÐAÐAÝˆw�{Š{˜8Ñ$Ô$Ð*¨Ñ+Ô+¨zÒ9Ð9ØcÐcÝˆw�{Š{˜9Ñ%Ô%Ð+¨Ñ,Ô,µ°F´NÑ0CÔ0CÒCÐCØHÐHàÔ'×KÒKÐWaÐKÑbÔbÐbÐbÐbÐbÐbÐbˆØ $Ô 0× KÒ KÝ˜œÑ'Ô'Ý˜&Ô*Ñ+Ô+ð !Lñ !
ô !
ð 
ð 
ð 
ð 
ð 
ð 
ˆð ð 	SØ"ð S o×&9Ò&9¸,Ñ&GÔ&GÈ:Ò&UÐ&UØRÐRà×2Ò2°6Ñ:Ô:ˆð	ØÔ"×6Ò6Ý˜FœNÑ+Ô+Ý˜fÔ.Ñ/Ô/Ý˜FœNÑ+Ô+Ø'Ø%Ø'ð 7ñ ô ð ð ð ð ð ð ð ð øõ ð 	ð 	ð 	Ø¥3 s¡8¤8Ð+Ð+ØRÐRÐRÐRÐRÐRØøøøøð	øøøð
 Ô&×8Ò8¸ÑDÔDÐDÐDÐDÐDÐDÐDÐRÈ
ˆØˆð	"Ý#¨$Ô*:×*GÒ*GÈ
Ñ*SÔ*SÐ$SÐ$SÐ$SÐ$SÐ$SÐ$SÑTÔTð ð �Ø—;’;˜vÑ&Ô&¨+Ò5Ð5¸'¿+º+ÀiÑ:PÔ:PÐ5Ý%(¨¯ª°YÑ)?Ô)?Ñ%@Ô%@�NØ�EøøøÝð 	"ð 	"ð 	"Ø!ˆNˆNˆNð	"øøøð 0¨Ð/Ð/ˆØð 	FØÐE°^ÐEÐEÑEˆHØˆs2   ÆAG- Ç-
HÇ7HÈHÈHÈ<BJ? Ê?KËKc           
   ƒ   óV	  K  — t          j        ¦   «         }	 ddlm}m}m}m} |5  t          |                     ¦   «         ¦  «        }ddd¦  «         n# 1 swxY w Y   | 	                    d|¦  «        ƒ d{V —† | 	                    d|¦  «        ƒ d{V —†}|5  t          |                     ¦   «         ¦  «        }	ddd¦  «         n# 1 swxY w Y   |	|z
  }
||	z
  }|	|z  }t          d¦  «        g}|rD|                     t          dd                     t          |¦  «        ¦  «        ¬¦  «        ¦  «         |
rD|                     t          dd                     t          |
¦  «        ¦  «        ¬¦  «        ¦  «         |rD|                     t          d	d                     t          |¦  «        ¦  «        ¬¦  «        ¦  «         |	s#|                     t          d
¦  «        ¦  «         n?|                     t          dt          |¦  «        t          |	¦  «        ¬¦  «        ¦  «         	 ddlm} t!          | dd¦  «        }t!          | dd¦  «        }|�…|rƒ|5  t#          |                     ¦   «         ¦  «        D ]F\  }}	 t'          |t(          ¦  «        r|d         n|}n# t*          $ r Y Œ2w xY w|€Œ9 ||d¬¦  «         ŒG	 ddd¦  «         n# 1 swxY w Y   n2# t*          $ r%}t,                               d|¦  «         Y d}~nd}~ww xY wg }|
r8|                     dd                     t          |
¦  «        ¦  «        › �¦  «         |r8|                     dd                     t          |¦  «        ¦  «        › �¦  «         |r8|                     dd                     t          |¦  «        ¦  «        › �¦  «         |rt          |¦  «        › d�nd}|rd                     |¦  «        dz   nd}dd|› |› d�dœ}	 | j                             |j        ¦  «        ƒ d{V —†}| j                             |j        |¦  «        ƒ d{V —† n# t*          $ r Y nw xY wd                     |¦  «        S # t*          $ r6}t,                               d|¦  «         t          d |¬!¦  «        cY d}~S d}~ww xY w)"a  Actually disconnect, reconnect, and notify MCP tool changes.

        Split out from ``_handle_reload_mcp_command`` so the confirmation
        wrapper can invoke the same path whether the user confirmed via
        button, text reply, or has the confirm gate disabled.
        r   )Úshutdown_mcp_serversÚdiscover_mcp_toolsÚ_serversrº	  Nzgateway.reload_mcp.headerzgateway.reload_mcp.reconnectedr  )Únameszgateway.reload_mcp.addedzgateway.reload_mcp.removedz!gateway.reload_mcp.none_connectedz"gateway.reload_mcp.tools_available)r»  Úservers)Úrefresh_agent_mcp_toolsr  r  T)r  z8Failed to update cached agent tools after MCP reload: %szAdded servers: zRemoved servers: zReconnected servers: z MCP tool(s) now availablezNo MCP tools availablez. r®   r¬  z,[IMPORTANT: MCP servers have been reloaded. zD. The tool list for this conversation has been updated accordingly.]rª  r  zMCP reload failed: %szgateway.reload_mcp.failed)rP   )r  r!
  Útools.mcp_toolr¦  r§  r¨  rº	  r•   rž  r„  r   r”   rf   r  r7   r«  rV   r½  rñ  rt   r€  r2   r3   r4   r8
  rù  r(  rš  rN   rã   )r  rÖ  rØ   r¦  r§  r¨  rº	  Úold_serversÚ	new_toolsÚconnected_serversÚaddedr,	  Úreconnectedrq  r«  ræ  rå  Ú	_sess_keyrš  r  Ú_excÚchange_partsÚtool_summaryÚchange_detailÚ
reload_msgr\  r¨  s                              r>   Ú_execute_mcp_reloadz!GatewayRunner._execute_mcp_reloadÍQ  s~  è è € õ Ô'Ñ)Ô)ˆða	;Ø`Ð`Ð`Ð`Ð`Ð`Ð`Ð`Ð`Ð`Ð`Ð`ð ð 3ð 3Ý! (§-¢-¡/¤/Ñ2Ô2�ð3ð 3ð 3ñ 3ô 3ð 3ð 3ð 3ð 3ð 3ð 3øøøð 3ð 3ð 3ð 3ð
 ×&Ò& tÐ-AÑBÔBÐBÐBÐBÐBÐBÐBÐBð #×2Ò2°4Ð9KÑLÔLÐLÐLÐLÐLÐLÐLˆIð ð 9ð 9Ý$'¨¯ª©¬Ñ$8Ô$8Ð!ð9ð 9ð 9ñ 9ô 9ð 9ð 9ð 9ð 9ð 9ð 9øøøð 9ð 9ð 9ð 9ð &¨Ñ3ˆEØ!Ð$5Ñ5ˆGØ+¨kÑ9ˆKåÐ2Ñ3Ô3Ð4ˆEØð hØ—’�QÐ?ÀtÇyÂyÕQWÐXcÑQdÔQdÑGeÔGeÐfÑfÔfÑgÔgÐgØð \Ø—’�QÐ9ÀÇÂÍ6ÐRWÉ=Ì=ÑAYÔAYÐZÑZÔZÑ[Ô[Ð[Øð `Ø—’�QÐ;À4Ç9Â9ÍVÐT[É_Ì_ÑC]ÔC]Ð^Ñ^Ô^Ñ_Ô_Ð_Ø$ð |Ø—’�QÐBÑCÔCÑDÔDÐDÐDà—’�QÐCÍ3ÈyÉ>Ì>ÕcfÐgxÑcyÔcyÐzÑzÔzÑ{Ô{Ð{ðØBÐBÐBÐBÐBÐBÝ   ~°tÑ<Ô<�Ý% dÐ,?ÀÑFÔF�ØÐ*¨vÐ*Ø$ð Mð MÝ15°f·l²l±n´nÑ1EÔ1Eð Mð MÑ-˜I vð)Ý6@ÀÍÑ6OÔ6OÐ)[¨°¬¨ÐU[  øÝ#,ð )ð )ð )Ø ( ð)øøøà%˜~Ø (ð 4Ð3°FÀtÐLÑLÔLÐLÐLð!MðMð Mð Mñ Mô Mð Mð Mð Mð Mð Mð Møøøð Mð Mð Mð Møøõ$ ð ð ð Ý—’ØNØñô ð ð ð ð ð ð øøøøðøøøð ˆLØð RØ×#Ò#Ð$P°d·i²iÅÀuÁÄÑ6NÔ6NÐ$PÐ$PÑQÔQÐQØð VØ×#Ò#Ð$T¸¿	º	Å&ÈÁ/Ä/Ñ8RÔ8RÐ$TÐ$TÑUÔUÐUØð ^Ø×#Ò#Ð$\¸D¿IºIÅfÈ[ÑFYÔFYÑ<ZÔ<ZÐ$\Ð$\Ñ]Ô]Ð]ØLUÐs�c )™nœnÐHÐHÐHÐHÐ[sˆLØ>JÐR˜DŸIšI lÑ3Ô3°dÑ:Ð:ÐPRˆMàð lÈ-ð  lÐYeð  lð  lð  lðð ˆJðØ&*Ô&>×&TÒ&TÐUZÔUaÑ&bÔ&bÐ bÐ bÐ bÐ bÐ bÐ b�ØÔ.×CÒCØ!Ô,¨jñô ð ð ð ð ð ð ð ð øõ ð ð ð Ø�ðøøøð —9’9˜UÑ#Ô#Ð#øåð 	;ð 	;ð 	;Ý�NŠNÐ2°AÑ6Ô6Ð6ÝÐ0¸Ð:Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:øøøøð	;øøøsý   —Q( ¥"AÁQ( ÁAÁQ( ÁAÁ=Q( Â"CÂ:Q( ÃC
Ã
Q( ÃC
ÃEQ( È'.K É'KÉ=JÊKÊ
J*Ê'KÊ)J*Ê*KÊ?K ËKËK ËKËK ËQ( Ë
LË!LË<Q( ÌLÌC0Q( Ï7AQ ÑQ( Ñ
QÑQ( ÑQÑQ( Ñ(
R(Ñ2+R#ÒR(Ò#R(r   r²  rq  c             ƒ   ó<  ‡‡‡K  — d}	 |                       ¦   «         }t          |t          ¦  «        r|                     d¦  «        nd}t          |t          ¦  «        r#t	          |                     dd¦  «        ¦  «        }n# t
          $ r Y nw xY w|s ‰¦   «         ƒ d{V —†S |                      |j        ¦  «        Šdt          fˆˆˆfd„}	|  	                    |j        j
        ¦  «        }
d‰› d|› d	|
› d
|
› d|
› d�}|                      |‰|||	¬¦  «        ƒ d{V —†S )u  Gate a destructive session slash command (/new, /reset, /undo).

        ``execute`` is an async callable ``execute() -> str | EphemeralReply``
        that performs the destructive action.  If the
        ``approvals.destructive_slash_confirm`` config gate is off, ``execute``
        runs immediately (returning its result).  Otherwise this routes
        through ``_request_slash_confirm`` â€” native yes/no buttons on
        Telegram/Discord/Slack, text fallback elsewhere.

        Three-option resolution:

          - ``once``  â€” run ``execute`` and return its result
          - ``always`` â€” persist ``approvals.destructive_slash_confirm: false``,
                        then run ``execute``
          - ``cancel`` â€” return a "cancelled" message; do not run ``execute``
        Tre  NÚdestructive_slash_confirmÚchoicec              “   ó¾  •K  — | dk    rd‰› d�S d}| dk    rŒ	 ddl m} t           |dd¦  «        ¦  «        }|rt                               d	‰¦  «         nt                               d
‰¦  «         n2# t          $ r%}t                               d|¦  «         Y d }~nd }~ww xY w ‰¦   «         ƒ d {V —†}| dk    r#|rd}nd}t          |t          ¦  «        r||z   S |S |S )Nr  u   ðŸŸ¡ /z# cancelled. Conversation unchanged.FrÞ	  r   )Úsave_config_valuez#approvals.destructive_slash_confirmz8User opted out of destructive slash confirm (session=%s)z[Could not persist destructive_slash_confirm=false (session=%s); config.yaml is not writablez5Failed to persist destructive_slash_confirm=false: %su˜   

â„¹ï¸� Future /clear, /new, /reset, and /undo will run without confirmation. Re-enable via `approvals.destructive_slash_confirm: true` in config.yaml.uß   

âš ï¸� Could not save that preference (config.yaml is not writable), so /clear, /new, /reset, and /undo will ask again next time. To silence it permanently, set `approvals.destructive_slash_confirm: false` in config.yaml.)	rs  r½  rº   r3   rz  rã   r2   rt   rw   )	r»  Ú	persistedr½  r<   r·  Únoter   r³  r+   s	         €€€r>   Ú_on_confirmzCGatewayRunner._maybe_confirm_destructive_slash.<locals>._on_confirmrR  s~  øè è € Ø˜Ò!Ð!ØL ÐLÐLÐLÐLØˆIØ˜Ò!Ð!ðØ5Ð5Ð5Ð5Ð5Ð5õ !%Ø)Ð)Ð*OÐQVÑWÔWñ!ô !�Ið !ð 
ÝŸšØVØ'ñô ð ð õ
 ŸšðHà'ñô ð øøõ
 !ð ð ð Ý—N’NØOÐQTñô ð ð ð ð ð ð øøøøðøøøð #˜7™9œ9�_�_�_�_�_�_ˆFØ˜Ò!Ð!Øð ðVð �DðWð õ ˜f¥cÑ*Ô*ð )Ø! D™=Ð(ð �ØˆMs   ™AA2 Á2
B!Á<BÂB!u   âš ï¸� **Confirm /z**

uÆ   

Choose:
â€¢ **Approve Once** â€” proceed this time only
â€¢ **Always Approve** â€” proceed and silence this prompt permanently
â€¢ **Cancel** â€” keep current conversation

_Text fallback: reply `zapprove`, `zalways`, or `z	cancel`._)rÖ  r   rÏ  r$  Úhandler)Ú_read_user_configrt   ru   rv   rº   r2   rA  r(  rw   Ú_typed_command_prefix_forr�   Ú_request_slash_confirm)r  rÖ  r   rÏ  r²  r³  Úconfirm_requiredrœ  re  rÀ  rf  Úprompt_messager+   s     `  `      @r>   rõ  z.GatewayRunner._maybe_confirm_destructive_slashJR  sÎ  øøøè è € ð4  Ðð	Ø×(Ò(Ñ*Ô*ˆCÝ0:¸3ÅÑ0EÔ0EÐO˜Ÿš Ñ,Ô,Ð,È4ˆIÝ˜)¥TÑ*Ô*ð ZÝ#'¨	¯ªÐ6QÐSWÑ(XÔ(XÑ#YÔ#YÐ øøÝð 	ð 	ð 	ØˆDð	øøøð  ð 	#Ø ˜™œ�?�?�?�?�?�?Ð"à×2Ò2°5´<Ñ@Ô@ˆð4	¥cð 4	ð 4	ð 4	ð 4	ð 4	ð 4	ð 4	ð 4	ðl ×+Ò+¨E¬LÔ,AÑBÔBˆðT ð Tð TØðTð Tð ')ðTð Tð 68ðTð Tð GIðTð Tð Tð 	ð ×0Ò0ØØØØ"Øð 1ñ 
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ð 	
s   ‰A8B Â
BÂBc             ƒ   ó|  K  — ddl m} |j        }|                      |¦  «        }t	          | dd¦  «        }	|	€ ddl}
|
                     d¦  «        }	|	| _        t          |	¦  «        › }| 	                    ||||¦  «         |  
                    |¦  «        }|                      ||                      |¦  «        ¦  «        }d}|�v	 |                     |j        |||||¬¦  «        ƒ d{V —†}|rt	          |dd¦  «        rd	}n9# t          $ r,}t                                d
||j        |¦  «         Y d}~nd}~ww xY w|rdS |S )aR  Ask the user to confirm an expensive slash command.

        ``handler`` is an async callable ``handler(choice: str) -> str``
        where ``choice`` is ``"once"``, ``"always"``, or ``"cancel"``.
        The handler runs on the event loop when the user responds; its
        return value is sent back as a gateway message.

        Returns a short acknowledgment string to send immediately (before
        the user's response).  If buttons rendered successfully the ack
        is ``None`` (buttons are self-explanatory); if we fell back to
        text the message itself IS the ack.
        r   r™  r®  Nr(   F)r2  rÏ  r$  r+   r¤  r¯   r/  Tz*send_slash_confirm failed for %s on %s: %s)r»  rš  r(  rA  rV   r­  r  r®  ÚnextrN  r@  rî	  ru  Úsend_slash_confirmr2  r2   r3   r4   r�   )r  rÖ  r   rÏ  r$  rÁ  rI  r(  r+   ÚcounterrÁ  r¤  r1  r¯   Úused_buttonsÚbutton_resultr<   s                    r>   rÄ  z$GatewayRunner._request_slash_confirmºR  sÃ  è è € ð* 	>Ð=Ð=Ð=Ð=Ð=à”ˆØ×2Ò2°6Ñ:Ô:ˆõ
 ˜$Ð 8¸$Ñ?Ô?ˆØˆ?Ø*Ð*Ð*Ð*Ø ×&Ò& qÑ)Ô)ˆGØ*1ˆDÔ'Ý˜W™œÐ'ˆ
ð 	×#Ò# K°¸WÀgÑNÔNÐNà×*Ò*¨6Ñ2Ô2ˆØ×3Ò3°F¸D×<XÒ<XÐY^Ñ<_Ô<_Ñ`Ô`ˆàˆØÐðØ&-×&@Ò&@Ø"œNØØ#Ø +Ø)Ø%ð 'Añ 'ô 'ð !ð !ð !ð !ð !ð !�ð !ð (¥W¨]¸IÀuÑ%MÔ%Mð (Ø#'�LøøÝð ð ð Ý—’Ø@Ø˜Vœ_¨cñô ð ð ð ð ð ð øøøøðøøøð ð 	à�4àˆs   Ã;C? Ã?
D5Ä	"D0Ä0D5c                 óz   — 	 ddl m}  |¦   «         }t          |t          ¦  «        r|ni S # t          $ r i cY S w xY w)zÙRead the user's raw config.yaml (cached) for gate lookups.

        Used by slash-confirm gates that must reflect on-disk state changes
        (e.g. a prior "Always Approve" click) without a gateway restart.
        r   rc  )r˜  rd  rt   ru   r2   )r  rd  rœ  s      r>   rÂ  zGatewayRunner._read_user_configþR  sa   € ð	Ø5Ð5Ð5Ð5Ð5Ð5Ø�+‘-”-ˆCÝ$ S­$Ñ/Ô/Ð7�3�3°RÐ7øÝð 	ð 	ð 	ØˆIˆIˆIð	øøøs   ‚(+ «:¹:r5
  c                 ó~  — |                       t          |dd¦  «        t          |dd¦  «        t          |dd¦  «        t          |dd¦  «        |pt          |dd¦  «        ¬¦  «        }t          |dd¦  «        t          j        k    r6t          |dd¦  «        }|r#t	          |pi ¦  «        }t          |¦  «        |d	<   |S )
z@Build the metadata dict platforms need for thread-aware replies.r�   Nr2  r›  r´  rj  ©r´  r5
  Úscope_idÚslack_team_id)r<
  rV   rÄ  rÅ  ru   rw   )r  r(  r5
  r¯   Úteam_ids        r>   rî	  z)GatewayRunner._thread_metadata_for_sourceS  sÉ   € ð ×3Ò3Ý�F˜J¨Ñ-Ô-Ý�F˜I tÑ,Ô,Ý�F˜K¨Ñ.Ô.Ý˜f k°4Ñ8Ô8Ø 3Ð Zµw¸vÀ|ÐUYÑ7ZÔ7Zð 4ñ 
ô 
ˆõ �6˜: tÑ,Ô,µ´Ò>Ð>Ý˜f j°$Ñ7Ô7ˆGØð 9Ý  ¨BÑ/Ô/�Ý,/°©L¬L�˜Ñ)ØˆrM   r4
  r´  c                óø   — |€dS d|i}|                       |||||¬¦  «        r3d|d<   t          |¦  «        }|r	|dvr||d<   |�t          |¦  «        |d<   |t          j        k    r|�t          |¦  «        |d	<   |S )
zGBuild thread metadata for synthetic sends that only have routing state.Nr›  ©r´  r1  TÚ telegram_dm_topic_reply_fallback>   r®   ro   Údirect_messages_topic_idÚtelegram_reply_to_message_idrj  )Ú_is_telegram_dm_topic_targetrw   rÄ  rÅ  )	r  r�   r2  r›  r´  r5
  r1  r¯   rJ  s	            r>   r<
  z)GatewayRunner._thread_metadata_for_targetS  sÅ   € ð ÐØ�4Ø$/°Ð#;ˆØ×,Ò,ØØØØØð -ñ 
ô 
ð 	Tð <@ˆHÐ7Ñ8õ �i‘.”.ˆCØð ;�s )Ð+Ð+Ø7:�Ð3Ñ4Ø"Ð.Ý;>Ð?RÑ;SÔ;S�Ð7Ñ8Ø•x”~Ò%Ð%Ð*=Ð*Iõ &)Ð)<Ñ%=Ô%=ˆH�\Ñ"ØˆrM   rÔ  c                ór  — | t           j        k    s|€dS |dk    rdS |�˜|r–t          t          |¦  «        dd¦  «        }t	          |¦  «        ri	  ||t          |¦  «        t          |¦  «        ¦  «        }t          |t          ¦  «        S # t          $ r t           
                    dd¬¦  «         Y nw xY wdS )z>Return True when a target is a Telegram private DM topic lane.NFrµ  Trw  z,Failed to inspect Telegram DM topic metadatarß   )rÄ  rÍ  rV   rÎ   r/  rw   rt   ru   r2   r3   r4   )r�   r2  r›  r´  r1  Úget_dm_topic_infoÚ
topic_infos          r>   rØ  z*GatewayRunner._is_telegram_dm_topic_targetCS  sà   € ð •xÔ(Ò(Ð(¨IÐ,=Ø�5Ø˜ÒÐØ�4ð Ð 7ÐÝ '­¨W©¬Ð7KÈTÑ RÔ RÐÝÐ)Ñ*Ô*ð 8ð8Ø!2Ð!2°7½CÀ¹L¼LÍ#ÈiÉ.Ì.Ñ!YÔ!Y�Jõ & jµ$Ñ7Ô7Ð7øõ !ð `ð `ð `Ý—L’LÐ!OÐZ^�LÑ_Ô_Ð_Ð_Ð_ð`øøøð ˆus   Á'B Â&B4Â3B4c                 ó    — t          | ¦  «        S )zBReturn the platform-specific reply anchor for GatewayRunner sends.)ru  )rÖ  s    r>   ru  z%GatewayRunner._reply_anchor_for_eventcS  s   € õ ' uÑ-Ô-Ð-rM   c                 ó  — t          | dd¦  «        }|r|                     ¦   «         sdS 	 t          j        |                      ¦   «         ¦  «        | _        dS # t          $ r t                               d¦  «         Y dS w xY w)z;Ensure a background task is watching for update completion.Ú_update_notification_taskNz;Skipping update notification watcher: no running event loop)	rV   r  r  r”  Ú_watch_update_progressrÞ  r¾  r3   r4   )r  Úexisting_tasks     r>   r¨  z1GatewayRunner._schedule_update_notification_watch€S  s¡   € å Ð&AÀ4ÑHÔHˆØð 	 ×!3Ò!3Ñ!5Ô!5ð 	ØˆFð	XÝ-4Ô-@Ø×+Ò+Ñ-Ô-ñ.ô .ˆDÔ*Ð*Ð*øõ ð 	Xð 	Xð 	XÝ�LŠLÐVÑWÔWÐWÐWÐWÐWð	Xøøøs   «+A Á$B Á?B ç      @ç      œ@r<  Ústream_intervalc              ƒ   ó¶  ‡#‡$‡%‡&‡'‡(‡)‡*K  — t           dz  }t           dz  }t           dz  }t           dz  }t           dz  }t          j        ¦   «         Š(‰(                     ¦   «         |z   }	dŠ$dŠ&d}
dŠ)||fD �]#}|                     ¦   «         �r	 t          j        |                     d¬¦  «        ¦  «        }|                     d	¦  «        }|                     d
¦  «        Š&|                     d¦  «        }|                     d¦  «        }
|                     d¦  «        }|                     d¦  «        }|rO‰&rMt          |¦  «        Š*| j
                             ‰*¦  «        Š$|                      ‰*‰&|||‰$¬¦  «        Š)|
s|› d‰&› �}
 n# t          $ r Y �Œw xY w�Œ%‰$r‰&�sSt                               d¦  «         |                     ¦   «         s|                     ¦   «         r¢‰(                     ¦   «         |	k     rŠ|                     ¦   «         r|                      ¦   «         ƒ d{V —†rdS t          j        |¦  «        ƒ d{V —† |                     ¦   «         s|                     ¦   «         r‰(                     ¦   «         |	k     °Š|                     ¦   «         s|                     ¦   «         rE|                     ¦   «         s1|                     dd¬¦  «         |                      ¦   «         ƒ d{V —† dS dt$          dt$          fd„Š#dt&          dt(          dt*          t$          t(          f         fd„}d}‰(                     ¦   «         Š'dŠ%d9ˆ#ˆ$ˆ%ˆ&ˆ'ˆ(ˆ)ˆ*fd„}‰(                     ¦   «         |	k     �rt|                     ¦   «         �r¬|                     ¦   «         r(	  |||¦  «        \  }}|r‰%|z  Š%n# t,          $ r Y nw xY w |¦   «         ƒ d{V —† 	 |                     d¬¦  «                             ¦   «         pd}t)          |¦  «        }|dk    r.‰$                     ‰&dt3          ‰)‰*¬¦  «        ¬¦  «        ƒ d{V —† n@‰$                     ‰&d                      |¦  «        t3          ‰)‰*¬¦  «        ¬¦  «        ƒ d{V —† t                               d!||
¦  «         n2# t          $ r%}t                               d"|¦  «         Y d}~nd}~ww xY w|||||fD ]}|                     d#¬$¦  «         Œt           d%z                       d#¬$¦  «         |                      |
¦  «        }|�d&|j        _        dS |                     ¦   «         r(	  |||¦  «        \  }}|r‰%|z  Š%n# t,          $ r Y nw xY w‰%                     ¦   «         r+‰(                     ¦   «         ‰'z
  |k    r |¦   «         ƒ d{V —† |
r|                      |
¦  «        nd}|                     ¦   «         �r×|
�rÔ|�|j        j        �sÅ	 t          j        |                     d¬¦  «        ¦  «        }|                     d'd¦  «        }|                     d(d¦  «        }|�r. |¦   «         ƒ d{V —† d&}tA          tC          ‰$¦  «        d)d¦  «        �e	 ‰$ "                    ‰&|||
t3          ‰)‰*¬¦  «        ¬*¦  «        ƒ d{V —† d#}n2# t          $ r%}t           #                    d+|¦  «         Y d}~nd}~ww xY w|sT|rd,|› d-�nd} tA          ‰$d.d/¦  «        }!‰$                     ‰&d0|› | › d1|!› d2|!› d3�t3          ‰)‰*¬¦  «        ¬¦  «        ƒ d{V —† d#|  $                    |
¦  «        j        _        t                               d4|
|dd5…         ¦  «         n># t
          j%        t,          f$ r%}t           #                    d6|¦  «         Y d}~nd}~ww xY wt          j        |¦  «        ƒ d{V —† ‰(                     ¦   «         |	k     �°t|                     ¦   «         sät                               d7|¦  «         |                     dd¬¦  «          |¦   «         ƒ d{V —† 	 ‰$                     ‰&d8t3          ‰)‰*¬¦  «        ¬¦  «        ƒ d{V —† n# t          $ r Y nw xY w|||||fD ]}|                     d#¬$¦  «         Œt           d%z                       d#¬$¦  «         |                      |
¦  «        }"|"�d&|"j        _        dS dS dS ):a»  Watch ``hermes update --gateway``, streaming output + forwarding prompts.

        Polls ``.update_output.txt`` for new content and sends chunks to the
        user periodically.  Detects ``.update_prompt.json`` (written by the
        update process when it needs user input) and forwards the prompt to
        the messenger.  The user's next message is intercepted by
        ``_handle_message`` and written to ``.update_response``.
        ro  rp  ú.update_output.txtú.update_exit_coderœ  NrQ  r‚  r�   r2  r´  r+   r›  rj  r4
  rÉ  zOUpdate watcher: cannot resolve adapter/chat_id, falling back to completion-onlyÚ124rè   r-   c                 ó$   — ddl m}  || ¦  «        S )Nr   ©Ú
strip_ansi)Útools.ansi_striprê  )rè   rê  s     r>   Ú_strip_ansiz9GatewayRunner._watch_update_progress.<locals>._strip_ansi×S  s$   € Ø3Ð3Ð3Ð3Ð3Ð3Ø�:˜dÑ#Ô#Ð#rM   r™   Úoffsetc                 óú   — 	 |                       ¦   «         }n# t          $ r d|fcY S w xY wt          |¦  «        |k    rdt          |¦  «        fS ||d…                              dd¬¦  «        t          |¦  «        fS )z?Read update output defensively; logs may contain invalid UTF-8.r®   NrQ  rl  ©rS  )Ú
read_bytesr–   r7   r  )r™   rí  rî  s      r>   Ú_read_output_sincez@GatewayRunner._watch_update_progress.<locals>._read_output_sinceÛS  s�   € ð"Ø—’Ñ(Ô(��øÝð "ð "ð "Ø˜6�zÐ!Ð!Ð!ð"øøøå�4‰yŒy˜FÒ"Ð"Ø�3˜t™9œ9�}Ð$Ø˜˜˜”=×'Ò'¨¸	Ð'ÑBÔBÅCÈÁIÄIÐMÐMs   ‚ —(§(r   r®   c            	   “   óÚ  •‡‡K  — ‰                      ¦   «         sdŠdS  ‰‰¦  «                              ¦   «         ŠdŠ‰
                     ¦   «         Š	‰sdS dŠˆˆfd„t          dt          ‰¦  «        ‰¦  «        D ¦   «         } | D ]f}	 ‰                     ‰d|› d�t          ‰‰¬¦  «        ¬	¦  «        ƒ d{V —† Œ5# t          $ r%}t                               d
|¦  «         Y d}~Œ_d}~ww xY wdS )z!Send buffered output to the user.r®   Né¬  c                 ó*   •— g | ]}‰||‰z   …         ‘ŒS rN  rN  )rb   rî  ÚcleanÚ	max_chunks     €€r>   r  zOGatewayRunner._watch_update_progress.<locals>._flush_buffer.<locals>.<listcomp>÷S  s&   ø€ ÐVÐVÐV°�e˜A˜a )™m˜OÔ,ÐVÐVÐVrM   r   r$  r%  r…   r.  zUpdate stream send failed: %s)	rx   rU   r  r7   r0  r´   r2   r3   r4   )ÚchunksÚchunkr¨  rõ  rö  rì  r1  Úbufferr2  Úlast_stream_timerØ   r¯   r�   s      @@€€€€€€€€r>   Ú_flush_bufferz;GatewayRunner._watch_update_progress.<locals>._flush_bufferéS  s_  øøøè è € ð —<’<‘>”>ð Ø�Ø�à�K Ñ'Ô'×-Ò-Ñ/Ô/ˆEØˆFØ#Ÿyšy™{œ{ÐØð Ø�àˆIØVÐVÐVÐVÐVµe¸A½sÀ5¹z¼zÈ9Ñ6UÔ6UÐVÑVÔVˆFØð Eð E�ðEØ!Ÿ,š,ØØ, Ð,Ð,Ð,Ý!=¸hÐQYÐ!ZÑ!ZÔ!Zð 'ñ ô ð ð ð ð ð ð ð ð øõ
 !ð Eð Eð EÝ—L’LÐ!@À!ÑDÔDÐDÐDÐDÐDÐDÐDøøøøðEøøøðEð Es   Â1B9Â9
C(ÃC#Ã#C(ro   u   âœ… Hermes update finished.r…   r.  u(   â�Œ Hermes update failed (exit code {}).z&Update finished (exit=%s), notified %sz$Update final notification failed: %sTrs  r›  FrY	  rJ  Úsend_update_prompt)r2  rY	  rJ  r+   r¯   z%Button-based update prompt failed: %sz (default: rŠ  rc  r]  u"   âš• **Update needs your input:**

z	

Reply `zapprove` (yes) or `z)deny` (no), or type your answer directly.z!Forwarded update prompt to %s: %sr  z Failed to read update prompt: %sz$Update watcher timed out after %.0fsu-   â�Œ Hermes update timed out after 30 minutes.rŽ  )&rl  r  r!
  rU   r˜   r3  r4  rX  rv   rÄ  r°  r<
  r2   r3   rã   r§  r–  rö  rw   r   rh  r€  r–   rx   r0  r´   Úformatrz  ru  rA   r0   rê  rV   rÎ   rü  r4   r/   rí  )+r  r<  rã  rÓ  Úpending_pathÚclaimed_pathré  Úexit_code_pathrA  r+
  r+   r™   r5  rB
  r´  r›  rj  rñ  Ú
bytes_sentrû  rø  Úexit_code_rawr8  r¨  r;  Ú_up_doneÚ_up_pending_stateÚprompt_dataÚprompt_textrJ  Úsent_buttonsÚbtn_errÚdefault_hintrf  Ú_up_timeout_staterì  r1  rù  r2  rú  rØ   r¯   r�   s+                                      @@@@@@@@r>   rß  z$GatewayRunner._watch_update_progress�S  sÞ  øøøøøøøøè è € õ $Ð&<Ñ<ˆÝ#Ð&DÑDˆÝ"Ð%9Ñ9ˆÝ%Ð(;Ñ;ˆÝ"Ð%:Ñ:ˆåÔ'Ñ)Ô)ˆØ—9’9‘;”; Ñ(ˆð ˆØˆØˆØˆØ! <Ð0ð 	ñ 	ˆDØ�{Š{‰}Œ}ñ ðÝ"œj¨¯ªÀ¨Ñ)IÔ)IÑJÔJ�GØ#*§;¢;¨zÑ#:Ô#:�LØ%Ÿkšk¨)Ñ4Ô4�GØ '§¢¨KÑ 8Ô 8�IØ")§+¢+¨mÑ"<Ô"<�KØ '§¢¨KÑ 8Ô 8�IØ!(§¢¨\Ñ!:Ô!:�JØ#ð F¨ð FÝ#+¨LÑ#9Ô#9˜Ø"&¤-×"3Ò"3°HÑ"=Ô"=˜Ø#'×#CÒ#CØ$Ø#Ø%Ø&/Ø0:Ø$+ð $Dñ $ô $˜ð  +ð FØ-9Ð*EÐ*E¸GÐ*EÐ*E˜KØ�EøÝ ð ð ð Ø‘Dðøøøñ1ð6 ð 	˜gñ 	Ý�NŠNÐlÑmÔmÐmð  ×&Ò&Ñ(Ô(ð 3¨L×,?Ò,?Ñ,AÔ,Að 3ÀtÇyÂyÁ{Ä{ÐU]ÒG]ÐG]Ø!×(Ò(Ñ*Ô*ð °T×5SÒ5SÑ5UÔ5UÐ/UÐ/UÐ/UÐ/UÐ/UÐ/Uð Ø�FÝ”m MÑ2Ô2Ð2Ð2Ð2Ð2Ð2Ð2Ð2ð  ×&Ò&Ñ(Ô(ð 3¨L×,?Ò,?Ñ,AÔ,Að 3ÀtÇyÂyÁ{Ä{ÐU]ÒG]ÐG]ð ×#Ò#Ñ%Ô%ð 7¨×)<Ò)<Ñ)>Ô)>ð 7È×H]ÒH]ÑH_ÔH_ð 7Ø×)Ò)¨%¸'Ð)ÑBÔBÐBØ×4Ò4Ñ6Ô6Ð6Ð6Ð6Ð6Ð6Ð6Ð6ØˆFð	$�cð 	$¥cð 	$ð 	$ð 	$ð 	$ð	N¥Tð 	Nµ3ð 	N½5ÅÅcÀ¼?ð 	Nð 	Nð 	Nð 	Nð ˆ
ØŸ9š9™;œ;ÐØˆð	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð 	Eð2 �iŠi‰kŒk˜HÒ$Ñ$à×$Ò$Ñ&Ô&ñ 'à×%Ò%Ñ'Ô'ð ðØ,>Ð,>¸{ÈJÑ,WÔ,WÑ)˜˜zØ ð ,Ø" e™O˜FøøÝ"ð ð ð Ø˜ðøøøà#�m‘o”oÐ%Ð%Ð%Ð%Ð%Ð%Ð%ðNØ$2×$<Ò$<ÀgÐ$<Ñ$NÔ$N×$TÒ$TÑ$VÔ$VÐ$]ÐZ]�MÝ # MÑ 2Ô 2�IØ  A’~�~Ø%ŸlšlØ#Ø9Ý%AÀ(ÐU]Ð%^Ñ%^Ô%^ð +ñ ô ð ð ð ð ð ð ð ð ð &ŸlšlØ#ØF×MÒMÈiÑXÔXÝ%AÀ(ÐU]Ð%^Ñ%^Ô%^ð +ñ ô ð ð ð ð ð ð ð õ
 —K’KÐ HÈ)ÐU`ÑaÔaÐaÐaøÝ ð Nð Nð NÝ—N’NÐ#IÈ1ÑMÔMÐMÐMÐMÐMÐMÐMøøøøðNøøøð '¨°kØ(¨+ð7ð .ð .�Aà—H’H¨�HÑ-Ô-Ð-Ð-ÝÐ 2Ñ2×:Ò:ÀdÐ:ÑKÔKÐKØ×3Ò3°KÑ@Ô@�ØÐ'Ø@E�HÔ'Ô=Ø�ð ×!Ò!Ñ#Ô#ð ðØ(:Ð(:¸;È
Ñ(SÔ(SÑ%�E˜:Øð (Ø %™˜øøÝð ð ð Ø�Dðøøøð �|Š|‰~Œ~ð & 4§9¢9¡;¤;Ð1AÑ#AÀoÒ"UÐ"UØ#�m‘o”oÐ%Ð%Ð%Ð%Ð%Ð%Ð%ð :EÐN�×(Ò(¨Ñ5Ô5Ð5È$ð ð ×"Ò"Ñ$Ô$ñ 1H¨ñ 1Hà)Ð5Ø-Ô8ÔNñ 6ð,HÝ"&¤*¨[×-BÒ-BÈGÐ-BÑ-TÔ-TÑ"UÔ"U�KØ"-§/¢/°(¸BÑ"?Ô"?�KØ)Ÿošo¨i¸Ñ<Ô<�GØ"ñ &hð ,˜m™oœoÐ-Ð-Ð-Ð-Ð-Ð-Ð-à',˜Ý"¥4¨¡=¤=Ð2FÈÑMÔMÐYð
_Ø&-×&@Ò&@Ø,3Ø+6Ø,3Ø0;Ý-IÈ(Ð]eÐ-fÑ-fÔ-fð 'Añ '"ô '"ð !"ð !"ð !"ð !"ð !"ð !"ð !"ð 04  øÝ#,ð _ð _ð _Ý &§¢Ð-TÐV]Ñ ^Ô ^Ð ^Ð ^Ð ^Ð ^Ð ^Ð ^øøøøð_øøøà+ð 
ØGNÐ+VÐ+C¸Ð+CÐ+CÐ+CÐ+CÐTV˜LÝ!(¨Ð2HÈ#Ñ!NÔ!N˜BØ")§,¢,Ø 'ð!AØ#.ð!AØ0<ð!Að !Aà*,ð!Að !AàACð!Að !Að !Aõ *FÀhÐYaÐ)bÑ)bÔ)bð #/ñ #ô #ð ð ð ð ð ð ð ð >Bð ×+Ò+Ø'ñô ä$Ô%:åŸšÐ$GÈÐVaÐbeÐceÐbeÔVfÑgÔgÐgøøÝÔ,­gÐ6ð Hð Hð HÝ—L’LÐ!CÀQÑGÔGÐGÐGÐGÐGÐGÐGøøøøðHøøøõ ”- Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.ðe �iŠi‰kŒk˜HÒ$Ñ$ðj ×$Ò$Ñ&Ô&ð 	KÝ�NŠNÐAÀ7ÑKÔKÐKØ×%Ò% e°gÐ%Ñ>Ô>Ð>Ø�-‘/”/Ð!Ð!Ð!Ð!Ð!Ð!Ð!ðØ—l’lØØCÝ9¸(ÈXÐVÑVÔVð #ñ ô ð ð ð ð ð ð ð ð øõ
 ð ð ð Ø�ðøøøà" L°+Ø$ kð3ð *ð *�à—’ D�Ñ)Ô)Ð)Ð)ÝÐ.Ñ.×6Ò6À$Ð6ÑGÔGÐGØ $× 8Ò 8¸Ñ EÔ EÐØ Ð,ØEJÐ!Ô,ÔBÐBÐBð%	Kð 	Kð" -Ð,s¦   ÂC7FÆ
FÆFÎN, Î,
N9Î8N9ÏC	R Ò
SÒ!SÓSÕU Õ
U%Õ$U%×(B]. Ù01Z" Ú!]. Ú"
[Ú,[Û]. Û[ÛB]. Ý.^)Þ^$Þ$^)à6-a$ á$
a1á0a1c              ƒ   óN  K  — t           dz  }t           dz  }t           dz  }t           dz  }|                     ¦   «         s|                     ¦   «         sdS d}|}	 |                     ¦   «         rš	 |                     |¦  «         nö# t          $ rv |                     ¦   «         s_Y |rZ|                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         dS dS Y nww xY w|                     ¦   «         s_	 |rZ|                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         dS dS t          j        |                     d¬	¦  «        ¦  «        }|                     d
¦  «        }|                     d¦  «        }	|                     d¦  «        }
|                     d¦  «        }|                     d¦  «        }|                     ¦   «         s’t           
                    d¦  «         d}|}|                     |¦  «         	 |rZ|                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         dS dS |                     d¬	¦  «                             ¦   «         pd}t          |¦  «        }d}|                     ¦   «         r)|                     ¦   «                              dd¬¦  «        }t          |¦  «        }| j                             |¦  «        }|s•|	r“t           
                    d|¦  «         d}|}|                     |¦  «         	 |rZ|                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         dS dS |rË|	rÉ|                      ||	||
||¬¦  «        }ddlm}  ||¦  «                             ¦   «         }|r4t)          |¦  «        dk    rd|dd…         z   }|dk    rd|› d�}nd|› d�}n|dk    rd}nd }|                     |	|t-          ||¬!¦  «        ¬"¦  «        ƒ d{V —† t           
                    d#||	|¦  «         n2# t.          $ r%}t                               d$|¦  «         Y d}~nd}~ww xY w|rX|                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         n`# |rY|                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         |                     d¬¦  «         w w xY wdS )%a„  If an update finished, notify the user.

        Returns False when the update is still running so a caller can retry
        later. Returns True after a definitive send/skip decision.

        This is the legacy notification path used when the streaming watcher
        cannot resolve the adapter (e.g. after a gateway restart where the
        platform hasn't reconnected yet).
        ro  rp  rå  ræ  FTrs  rQ  r‚  r�   r2  r´  r›  rj  z2Update notification deferred: update still runningro   r®   rl  rï  z:Update notification deferred: %s adapter not connected yetr4
  r   ré  ró  rž  iTòÿÿNu!   âœ… Hermes update finished.

```
r%  u   â�Œ Hermes update failed.

```
u(   âœ… Hermes update finished successfully.u]   â�Œ Hermes update failed. Check the gateway logs or run `hermes update` manually for details.r…   r.  z0Sent post-update notification to %s:%s (exit=%s)z#Post-update notification failed: %s)rl  r˜   rl  rì  ru  r3  r4  rX  rv   r3   rz  rx   rh  rð  r  rÄ  r°  r<
  rë  rê  r7   r0  r´   r2   rã   )r  rþ  rÿ  ré  r   ÚcleanupÚactive_pending_pathr5  rB
  r2  r´  r›  rj  r  r8  rÀ  r�   r1  r¯   rê  r§  r¨  s                         r>   r§  z'GatewayRunner._send_update_notification‹T  sù  è è € õ $Ð&<Ñ<ˆÝ#Ð&DÑDˆÝ"Ð%9Ñ9ˆÝ%Ð(;Ñ;ˆà×"Ò"Ñ$Ô$ð 	¨\×-@Ò-@Ñ-BÔ-Bð 	Ø�5àˆØ*Ðð_	7Ø×"Ò"Ñ$Ô$ð ð$Ø ×(Ò(¨Ñ6Ô6Ð6Ð6øÝ(ð $ð $ð $Ø'×.Ò.Ñ0Ô0ð $Ø#ðj ð 7Ø#×*Ò*°dÐ*Ñ;Ô;Ð;Ø×#Ò#¨tÐ#Ñ4Ô4Ð4Ø×"Ò"¨dÐ"Ñ3Ô3Ð3Ø×%Ò%°Ð%Ñ6Ô6Ð6Ð6Ð6ð	7ð 7ðm$ð $ð$øøøð "×(Ò(Ñ*Ô*ð Øðf ð 7Ø#×*Ò*°dÐ*Ñ;Ô;Ð;Ø×#Ò#¨tÐ#Ñ4Ô4Ð4Ø×"Ò"¨dÐ"Ñ3Ô3Ð3Ø×%Ò%°Ð%Ñ6Ô6Ð6Ð6Ð6ð	7ð 7õc ”j ×!7Ò!7ÀÐ!7Ñ!IÔ!IÑJÔJˆGØ"Ÿ;š; zÑ2Ô2ˆLØ—k’k )Ñ,Ô,ˆGØŸš KÑ0Ô0ˆIØŸš KÑ0Ô0ˆIØ Ÿš \Ñ2Ô2ˆJà!×(Ò(Ñ*Ô*ð Ý—’ÐPÑQÔQÐQØ�Ø&2Ð#Ø×$Ò$ \Ñ2Ô2Ð2ØðJ ð 7Ø#×*Ò*°dÐ*Ñ;Ô;Ð;Ø×#Ò#¨tÐ#Ñ4Ô4Ð4Ø×"Ò"¨dÐ"Ñ3Ô3Ð3Ø×%Ò%°Ð%Ñ6Ô6Ð6Ð6Ð6ð	7ð 7ðG +×4Ò4¸gÐ4ÑFÔF×LÒLÑNÔNÐUÐRUˆMÝ˜MÑ*Ô*ˆIð ˆFØ×!Ò!Ñ#Ô#ð TØ$×/Ò/Ñ1Ô1×8Ò8¸ÈÐ8ÑSÔS�õ   Ñ-Ô-ˆHØ”m×'Ò'¨Ñ1Ô1ˆGàð ˜wð õ —’ØPØ ñô ð ð  �Ø&2Ð#Ø×$Ò$ \Ñ2Ô2Ð2ØðN ð 7Ø#×*Ò*°dÐ*Ñ;Ô;Ð;Ø×#Ò#¨tÐ#Ñ4Ô4Ð4Ø×"Ò"¨dÐ"Ñ3Ô3Ð3Ø×%Ò%°Ð%Ñ6Ô6Ð6Ð6Ð6ð	7ð 7ðK ð !˜7ð !Ø×;Ò;ØØØØ'Ø(2Ø#ð <ñ ô �ð 8Ð7Ð7Ð7Ð7Ð7Ø#˜ FÑ+Ô+×1Ò1Ñ3Ô3�Øð 
zÝ˜6‘{”{ TÒ)Ð)Ø!&¨°°°¬Ñ!7˜Ø  A’~�~ØRÀVÐRÐRÐR˜˜àPÀ6ÐPÐPÐP˜˜Ø !’^�^ØD�C�Cày�CØ—l’lØØÝ9¸(ÈXÐVÑVÔVð #ñ ô ð ð ð ð ð ð ð õ
 —’ØFØ ØØñ	ô ð øøõ ð 	Eð 	Eð 	EÝ�NŠNÐ@À!ÑDÔDÐDÐDÐDÐDÐDÐDøøøøð	Eøøøð ð 7Ø#×*Ò*°dÐ*Ñ;Ô;Ð;Ø×#Ò#¨tÐ#Ñ4Ô4Ð4Ø×"Ò"¨dÐ"Ñ3Ô3Ð3Ø×%Ò%°Ð%Ñ6Ô6Ð6øøð	 ð 7Ø#×*Ò*°dÐ*Ñ;Ô;Ð;Ø×#Ò#¨tÐ#Ñ4Ô4Ð4Ø×"Ò"¨dÐ"Ñ3Ô3Ð3Ø×%Ò%°Ð%Ñ6Ô6Ð6Ð6ð	7øøøð ˆtsp   ÁR8 Á/B ÂR8 ÂDÂ#R8 ÄR8 ÄDÄR8 Å;CR8 Ê2CR8 Ï*CR8 Ò7U Ò8
S'ÓS"ÓU Ó"S'Ó'U ÕAV"c           
   ƒ   ó  K  — t           dz  }|                     ¦   «         sdS 	 t          j        |                     d¬¦  «        ¦  «        }|                     d¦  «        }|                     d¦  «        }|                     d¦  «        }|                     d¦  «        }|                     d	¦  «        }|r|s	 |                     d
¬¦  «         dS t          |¦  «        }t          || j	        | j
        ¦  «        }	|	€4t                               d|¦  «         	 |                     d
¬¦  «         dS | j	        j                             |¦  «        }
|
�;|
j        s4t                               d|¦  «         	 |                     d
¬¦  «         dS |                      ||||||	j        ¬¦  «        }|                     d¦  «        d
u rkt%          |pi ¦  «        }|                     d¦  «        rt'          |d         ¦  «        |d<   |                     d¦  «        rt'          |d         ¦  «        |d<   |	                     |t'          |¦  «        dt+          ||¬¦  «        ¬¦  «        ƒ d{V —†}|�Xt-          |dd
¦  «        du rEt                               d||t-          |dd¦  «        ¦  «         	 |                     d
¬¦  «         dS t                               d||¦  «         t'          |¦  «        t'          |¦  «        |rt'          |¦  «        ndf|                     d
¬¦  «         S # t0          $ r<}t                               d|¦  «         Y d}~|                     d
¬¦  «         dS d}~ww xY w# |                     d
¬¦  «         w xY w)zANotify the chat that initiated /restart that the gateway is back.rk  NrQ  r‚  r�   r2  r´  r›  rj  Trs  z6Restart notification skipped: no live transport for %szJRestart notification suppressed: %s has gateway_restart_notification=falser4
  rT  r¹  rÐ  u;   â™» Gateway restarted successfully. Your session continues.r…   r.  r/  Fz3Restart notification to %s:%s was not delivered: %srP   r6
  z"Sent restart notification to %s:%szRestart notification failed: %s)rl  r˜   r3  r4  rX  rv   ru  rÄ  re  rz   r°  r3   r4   rE  r;
  rz  r<
  r1  ru   rw   r0  r´   rV   rã   r2   )r  Únotify_pathrî  rB
  r2  r´  r›  rj  r�   r”  rG  r¯   r·  r¨  s                 r>   r©  z(GatewayRunner._send_restart_notificationU  s	  è è € å"Ð%;Ñ;ˆØ×!Ò!Ñ#Ô#ð 	Ø�4ðG	0Ý”:˜k×3Ò3¸WÐ3ÑEÔEÑFÔFˆDØŸ8š8 JÑ/Ô/ˆLØ—h’h˜yÑ)Ô)ˆGØŸš Ñ-Ô-ˆIØŸš Ñ-Ô-ˆIØŸš ,Ñ/Ô/ˆJàð  wð Øð| ×Ò¨$ÐÑ/Ô/Ð/Ð/Ð/õy   Ñ-Ô-ˆHÝ2°8¸T¼[È$Ì-ÑXÔXˆIØÐ Ý—’ØLØ ñô ð ð ðj ×Ò¨$ÐÑ/Ô/Ð/Ð/Ð/ðg  œ;Ô0×4Ò4°XÑ>Ô>ˆLØÐ'°Ô0YÐ'Ý—’Ø`Ø ñô ð ð ðZ ×Ò¨$ÐÑ/Ô/Ð/Ð/Ð/ðW ×7Ò7ØØØØ#Ø$.Ø!Ô)ð 8ñ ô ˆHð �xŠxÐ6Ñ7Ô7¸4Ð?Ð?Ý  ¨BÑ/Ô/�Ø—8’8˜IÑ&Ô&ð ?Ý*-¨d°9¬oÑ*>Ô*>�H˜YÑ'Ø—8’8˜JÑ'Ô'ð AÝ+.¨t°JÔ/?Ñ+@Ô+@�H˜ZÑ(Ø$Ÿ>š>ØÝ�G‘”ØMÝ5°hÈÐRÑRÔRð	 *ñ ô ð ð ð ð ð ð ˆFð Ð!¥g¨f°iÀÑ&FÔ&FÈ%Ð&OÐ&OÝ—’ØIØ ØÝ˜F GÐ-JÑKÔKñ	ô ð ð ð ×Ò¨$ÐÑ/Ô/Ð/Ð/Ð/õ �KŠKØ4ØØñô ð õ
 �|Ñ$Ô$¥c¨'¡l¤lÀiÐ4YµC¸	±N´N°NÐUYÐYð
 ×Ò¨$ÐÑ/Ô/Ð/Ð/øõ	 ð 	ð 	ð 	Ý�NŠNÐ<¸aÑ@Ô@Ð@Ø�4�4�4à×Ò¨$ÐÑ/Ô/Ð/Ð/Ð/øøøøð		øøøøð ×Ò¨$ÐÑ/Ô/Ð/Ð/øøøsF   ¤BL' ÃAL' Ä2AL' ÆDL' ËAL' Ì'
M-Ì1M(ÍM0 Í(M-Í-M0 Í0Nrq  rr  c             ƒ   ó  K  — t          ¦   «         }|pt          ¦   «         }d}| j        j                             ¦   «         D �]F\  }}|j        }|r|j        sŒt          || j        | j        ¦  «        }|€Œ5|j        s!t           
                    d|j        ¦  «         Œ]|j        t          |j        ¦  «        |j        rt          |j        ¦  «        ndf}	|	|v s|	|v rŒ�	 |                      ||j        |j        |j        ¬¦  «        }
|j        r3t#          |
pi ¦  «        }
|j        r
|j        |
d<   |j        r
|j        |
d<   t)          |
|¬¦  «        }|€|j        r2|                     |t          |j        ¦  «        ||¬¦  «        ƒ d{V —†}n3|j                             t          |j        ¦  «        |¦  «        ƒ d{V —†}|�Kt-          |d	d
¦  «        du r8t                               d|j        |j        t-          |dd¦  «        ¦  «         �ŒÌ|                     |	¦  «         t           
                    d|j        |j        ¦  «         �Œ	# t2          $ r2}t                               d|j        |j        |¦  «         Y d}~�Œ@d}~ww xY w|S )a3  Notify configured home channels that the gateway is back online.

        The notification is best-effort and sent once per connected platform
        home channel. ``skip_targets`` lets startup avoid duplicate messages
        when a more specific restart notification is queued for the same chat.
        u3   â™»ï¸� Gateway online â€” Hermes is back and ready.NzWHome-channel startup notification suppressed: %s has gateway_restart_notification=falser   r¹  rÐ  r…   r.  r/  TFz6Home-channel startup notification failed for %s:%s: %srP   r6
  z/Sent home-channel startup notification to %s:%s)r•   rz   rE  rñ  Úhome_channelr2  re  r°  r;
  r3   rz  r­   rw   r›  r<
  r1  Úis_relayru   r¹  rÐ  r´   r0  rV   rã   r—   r2   )r  rr  Ú	deliveredÚskippedr$  r�   rG  r‰  r”  r  r¯   r  r·  r<   s                 r>   rª  z6GatewayRunner._send_home_channel_startup_notificationsQU  s  è è € õ :=¹¼ˆ	ØÐ'¥#¡%¤%ˆØGˆà&*¤kÔ&;×&AÒ&AÑ&CÔ&Cð @	ñ @	Ñ"ˆH�lØÔ,ˆDØð ˜tœ|ð Øå2°8¸T¼[È$Ì-ÑXÔXˆIØÐ ØàÔ<ð Ý—’ØmØ”Nñô ð ð à”n¥c¨$¬,Ñ&7Ô&7ÐPTÔP^Ð9h½¸T¼^Ñ9LÔ9LÐ9LÐdhÐiˆFØ˜Ð Ð  F¨iÐ$7Ð$7Øð,Ø×;Ò;ØØ”LØ”NØ%Ô-ð	 <ñ ô �ð Ô%ð =Ý# H N°Ñ3Ô3�HØ”|ð ;Ø.2¬l˜ Ñ+Ø”}ð =Ø/3¬}˜ Ñ,Ý <¸XÐPXÐ YÑ YÔ Y�Ø Ð,°	Ô0BÐ,Ø#,§>¢>Ø Ý˜DœLÑ)Ô)ØØ!.ð	 $2ñ $ô $ð ð ð ð ð ð �F�Fð $-Ô#4×#9Ò#9½#¸d¼lÑ:KÔ:KÈWÑ#UÔ#UÐUÐUÐUÐUÐUÐU�FØÐ%­'°&¸)ÀTÑ*JÔ*JÈeÐ*SÐ*SÝ—N’NØPØ œØœÝ ¨Ð1NÑOÔOñ	ô ð ñ à—’˜fÑ%Ô%Ð%Ý—’ØEØ”NØ”Lñô ð ñ øõ
 ð ð ð Ý—’ØLØ”NØ”LØñ	ô ð ð ð ð ð ñ øøøøðøøøð Ðs   ÃD,I
È;I
É

JÉ'JÊJc                 ó´  — ddl m} t          | dd¦  «        pi }|                     |j        j        ¦  «        }t          |dd¦  «        } ||j        j        j        |j        j        |j        j        rt          |j        j        ¦  «        nd|j        j
        pd|j        j        rt          |j        j        ¦  «        nd|j        j        rt          |j        j        ¦  «        nd|j        j        rt          |j        j        ¦  «        nd|j        |j        j        rt          |j        j        ¦  «        ndt          |j        dd¦  «        pd|d¬	¦  «        S )
a@  Set session context variables for the current async task.

        Uses ``contextvars`` instead of ``os.environ`` so that concurrent
        gateway messages cannot overwrite each other's session state.

        Returns a list of reset tokens; pass them to ``_clear_session_env``
        in a ``finally`` block.
        r   )Úset_session_varsr°  NÚsupports_async_deliveryTr®   r  )r�   r2  r´  r*  r›  r¹  r)  r+   rj  r  Úasync_deliveryÚcron_session)râ  r  rV   rv   r(  r�   r­   r2  r´  rw   r*  r›  r¹  r)  r+   rj  )r  rÙ   r  Ú	_adaptersr³  Ú_async_deliverys         r>   rs  zGatewayRunner._set_session_env¤U  sP  € ð 	=Ð<Ð<Ð<Ð<Ð<õ ˜D *¨dÑ3Ô3Ð9°rˆ	Ø—=’= ¤Ô!8Ñ9Ô9ˆÝ! (Ð,EÀtÑLÔLˆØÐØ”^Ô,Ô2Ø”NÔ*à18´Ô1IÐQ•�G”NÔ,Ñ-Ô-Ð-Èrà”nÔ.Ð4°"Ø7>´~Ô7OÐW•c˜'œ.Ô2Ñ3Ô3Ð3ÐUWØ3:´>Ô3IÐQ•C˜œÔ.Ñ/Ô/Ð/ÈrØ7>´~Ô7OÐW•c˜'œ.Ô2Ñ3Ô3Ð3ÐUWØÔ+Ø9@¼Ô9RÐZ•s˜7œ>Ô4Ñ5Ô5Ð5ÐXZÝ˜GœN¨I°rÑ:Ô:Ð@¸bØ*Øð
ñ 
ô 
ð 	
rM   rd	  c                 ó(   — ddl m}  ||¦  «         dS )z>Restore session context variables to their pre-handler values.r   )Úclear_session_varsN)râ  r  )r  rd	  r  s      r>   r|  z GatewayRunner._clear_session_envÉU  s+   € à>Ð>Ð>Ð>Ð>Ð>ØÐ˜6Ñ"Ô"Ð"Ð"Ð"rM   c              ‡   ó¢   K  — t          j        ¦   «         }t          ¦   «         } |j        |                      ¦   «         |j        |g|¢R Ž ƒ d{V —†S )zJRun blocking work in the thread pool while preserving session contextvars.N)r  r!
  r   r„  Ú_get_executorr®
  )r  Úfuncr¸  rØ   r  s        r>   rc
  z+GatewayRunner._run_in_executor_with_contextÎU  sx   è è € åÔ'Ñ)Ô)ˆÝ‰nŒnˆØ)�TÔ)Ø×ÒÑ Ô ØŒGØð
ð ð	
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 	
rM   c                 óp  — t          | dd¦  «        }|€t          j        ¦   «         }|| _        |5  t          | dd¦  «        rt	          d¦  «        ‚t          | dd¦  «        }|�t          |dd¦  «        r(t
          j                             dd	¬
¦  «        }|| _        |cddd¦  «         S # 1 swxY w Y   dS )z:Return the gateway-owned executor for blocking agent work.r›  Nr�  Fz.Gateway is shutting down; executor unavailablerœ  Ú	_shutdownrG  rª
  )Úmax_workersÚthread_name_prefix)	rV   r¤  rº  r›  r¾  Ú
concurrentÚfuturesÚThreadPoolExecutorrœ  ©r  r°	  Úexecutors      r>   r  zGatewayRunner._get_executorÙU  s  € å�tÐ-¨tÑ4Ô4ˆØˆ<Ý”>Ñ#Ô#ˆDØ"&ˆDÔàð 
	ð 
	Ý�tÐ0°%Ñ8Ô8ð UÝ"Ð#SÑTÔTÐTÝ˜t [°$Ñ7Ô7ˆHØÐ¥7¨8°[À%Ñ#HÔ#HÐÝ%Ô-×@Ò@Ø "Ø'7ð Añ ô �ð "*�”Øð
	ð 
	ð 
	ð 
	ñ 
	ô 
	ð 
	ð 
	ð 
	ð 
	ð 
	ð 
	øøøð 
	ð 
	ð 
	ð 
	ð 
	ð 
	s   °A.B+Â+B/Â2B/c                 ó(  — t          | dd¦  «        }|€dS |5  d| _        t          | dd¦  «        }d| _        ddd¦  «         n# 1 swxY w Y   |€dS 	 |                     dd¬¦  «         dS # t          $ r |                     d¬¦  «         Y dS w xY w)zBStop the gateway-owned executor without touching the loop default.r›  NTrœ  F)rB  Úcancel_futures)rB  )rV   r�  rœ  r	  rw  r(  s      r>   rŽ  z GatewayRunner._shutdown_executorìU  s  € å�tÐ-¨tÑ4Ô4ˆØˆ<ØˆFàð 	"ð 	"Ø%)ˆDÔ"Ý˜t [°$Ñ7Ô7ˆHØ!ˆDŒNð	"ð 	"ð 	"ñ 	"ô 	"ð 	"ð 	"ð 	"ð 	"ð 	"ð 	"øøøð 	"ð 	"ð 	"ð 	"ð
 ÐØˆFð	*Ø×Ò 5¸ÐÑ>Ô>Ð>Ð>Ð>øÝð 	*ð 	*ð 	*Ø×Ò 5ÐÑ)Ô)Ð)Ð)Ð)Ð)ð	*øøøs#   ˜ AÁAÁAÁA- Á- BÂB)r(  r+   rA  r  r  r  c                óî  — 	 ddl m} ddlm}m} ddlm}	 t          |t          ¦  «        r|n	 |	¦   «         }
|pd 	                    ¦   «         }|pd 	                    ¦   «         }d}| p| }|dup|}|�r)|�r&	 |  
                    |||
¬¦  «        \  }}|s)t          |t          ¦  «        r| 	                    ¦   «         }t          |t          ¦  «        r|                     d¦  «        nd}t          |t          ¦  «        r|                     d	¦  «        nd}|s)t          |t          ¦  «        r| 	                    ¦   «         }t          |t          ¦  «        r| 	                    ¦   «         }n2# t          $ r%}t                               d
|¦  «         Y d}~nd}~ww xY w|s
 |¦   «         }|s
 |¦   «         } ||||
|¬¦  «        S # t          $ r&}t                               d|¦  «         Y d}~dS d}~ww xY w)ai  Resolve image-input routing for the effective model this turn.

        Returns ``"native"`` (attach pixels on the user turn) or ``"text"``
        (pre-analyze with vision_analyze and prepend the description). See
        agent/image_routing.py for the full decision table.

        Gateway sessions can have /model overrides that live outside
        config.yaml. Image preprocessing runs before AIAgent sets the
        auxiliary_client runtime globals, so resolve the same per-session
        runtime bundle the upcoming agent turn will use instead of consulting
        only the persisted default model.
        r   )Údecide_image_input_mode)Ú_read_main_modelÚ_read_main_providerrc  r®   Nrê  r  r¶  uO   image_routing: session runtime resolution failed, falling back to config â€” %s)r¶  u;   image_routing: decision failed, falling back to text â€” %srè   )rÆ  r-  rm
  r.  r/  r˜  rd  rt   ru   rx   r�  rw   rv   r2   r3   r4   )r  r(  r+   rA  r  r  r-  r.  r/  rd  rœ  Úresolved_providerÚresolved_modelÚresolved_requested_providerÚneeds_session_runtimeÚhas_session_identityrÛ  rÔ  Úruntime_providerÚruntime_requested_providerr<   s                        r>   rÂ  z&GatewayRunner._decide_image_input_modeÿU  s¼  € ð*2	ØCÐCÐCÐCÐCÐCØTÐTÐTÐTÐTÐTÐTÐTØ5Ð5Ð5Ð5Ð5Ð5å!+¨K½Ñ!>Ô!>ÐQ�+�+ÀKÀKÁMÄMˆCØ!) ¨R× 6Ò 6Ñ 8Ô 8ÐØ#˜k r×0Ò0Ñ2Ô2ˆNØ*,Ð'à(9Ð$9Ð$OÀÐ=OÐ!Ø#)°Ð#5Ð#D¸Ð Ø$ñ Ð)=ñ ðØ15×1TÒ1TØ%Ø$/Ø$'ð 2Uñ 2ô 2Ñ.�J ð
 *ð <­j¸ÅSÑ.IÔ.Ið <Ø)3×)9Ò)9Ñ);Ô);˜ÝISÐTbÕdhÑIiÔIiÐ's ~×'9Ò'9¸*Ñ'EÔ'EÐ'EÐosÐ$õ & nµdÑ;Ô;ð"˜×*Ò*Ð+?Ñ@Ô@Ð@à!ð /ð
 -ð EµÐ<LÍcÑ1RÔ1Rð EØ,<×,BÒ,BÑ,DÔ,DÐ)Ý!Ð"<½cÑBÔBð YØ6P×6VÒ6VÑ6XÔ6XÐ3øøÝ ð ð ð Ý—L’LØiØñô ð ð ð ð ð ð øøøøðøøøð %ð :Ø$7Ð$7Ñ$9Ô$9Ð!Ø!ð 4Ø!1Ð!1Ñ!3Ô!3�à*Ð*Ø!ØØØ#>ð	ñ ô ð øõ ð 	ð 	ð 	Ý�LŠLÐVÐX[Ñ\Ô\Ð\Ø�6�6�6�6�6øøøøð	øøøsC   ‚A5G Á8C2E+ Å*G Å+
FÅ5FÆG ÆFÆ)G Ç
G4ÇG/Ç/G4Ú	user_textr×  c              ƒ   ól  K  — ddl m} ddlm} d}g }|D ]ü}	 t                               d|¦  «          |||¬¦  «        ƒ d{V —†}t          j        |¦  «        }	|	                     d¦  «        r>|	                     d	d
¦  «        }
 ||
¦  «        }
| 	                    d|
› d|› d�¦  «         n| 	                    d|› d�¦  «         Œ²# t          $ r>}t                               d|¦  «         | 	                    d|› d�¦  «         Y d}~Œõd}~ww xY w|r d                     |¦  «        }|r|› d|› �S |S |S )a°  
        Auto-analyze user-attached images with the vision tool and prepend
        the descriptions to the message text.

        Each image is analyzed with a general-purpose prompt.  The resulting
        description *and* the local cache path are injected so the model can:
          1. Immediately understand what the user sent (no extra tool call).
          2. Re-examine the image with vision_analyze if it needs more detail.

        Args:
            user_text:   The user's original caption / message text.
            image_paths: List of local file paths to cached images.

        Returns:
            The enriched message string with vision descriptions prepended.
        r   )Úvision_analyze_tool)Úsanitize_contexta(  Concisely describe this image in 2-4 sentences (~200 Chinese characters or ~150 English words). Cover the main subject, key visible text/data/code, and overall context. If it is a chart, diagram, or scientific figure, include the important labels, legend, and key values. Skip decorative details.zAuto-analyzing user image: %s)rq  Úuser_promptNr/  Úanalysisr®   z0[The user sent an image~ Here's what I can see:
zA]
[If you need a closer look, use vision_analyze with image_url: z ~]zŒ[The user sent an image but I couldn't quite see it this time (>_<) You can try looking at it yourself with vision_analyze using image_url: rš  zVision auto-analysis error: %sz”[The user sent an image but something went wrong when I tried to look at it~ You can try examining it yourself with vision_analyze using image_url: r  )Útools.vision_toolsr9  Úagent.memory_managerr:  r3   r4   r3  r4  rv   r”   r2   rP   rf   )r  r7  r×  r9  r:  Úanalysis_promptÚenriched_partsr™   ró  r·  r  r¨  r  s                r>   rÄ  z)GatewayRunner._enrich_message_with_visionHV  s$  è è € ð* 	;Ð:Ð:Ð:Ð:Ð:Ø9Ð9Ð9Ð9Ð9Ð9ðGð 	ð ˆØð 	ð 	ˆDðÝ—’Ð<¸dÑCÔCÐCØ$7Ð$7Ø"Ø /ð%ñ %ô %ð ð ð ð ð ð �õ œ KÑ0Ô0�Ø—:’:˜iÑ(Ô(ð Ø"(§*¢*¨Z¸Ñ"<Ô"<�KØ"2Ð"2°;Ñ"?Ô"?�KØ"×)Ò)ð0ÈKð 0ð 0à&*ð0ð 0ð 0ñô ð ð ð #×)Ò)ðHà@DðHð Hð Hñô ð øøõ
 ð ð ð Ý—’Ð=¸qÑAÔAÐAØ×%Ò%ðDà<@ðDð Dð Dñô ð ð ð ð ð ð øøøøðøøøð ð 	Ø—[’[ Ñ0Ô0ˆFØð 2Ø Ð1Ð1 iÐ1Ð1Ð1ØˆMØÐs   ˜B.CÃ
DÃ4D
Ä
DrØ  c              ƒ   ól  ‡K  — t          ¦   «         Šˆfd„|D ¦   «         }t          | j        dd¦  «        s½g }|D ]n}t          j                             |¦  «        }t          |¦  «        ƒ d{V —†}|r|                     d|› d|› d�¦  «         ŒU|                     d|› d�¦  «         Œo|s|g fS d	                     |¦  «        }d
}|r| 	                    ¦   «         |k    r|g fS |r	|› d	|› �g fS |g fS 	 ddl
m}	m}
 nm# t          $ r`}t                               d|¦  «         d}d
}|r!| 	                    ¦   «         |k    r	|g fcY d}~S |r|› d	|› �g fcY d}~S |g fcY d}~S d}~ww xY wg }g }|D �]ú}	 t                               d|¦  «         t#          j        |	|¦  «        ƒ d{V —†}|                     d¦  «        sMt#          j        |
|¦  «        ƒ d{V —†}|                     d¦  «        rt                               d|¦  «         |}|d         rc|d         }|pd 	                    ¦   «         s|                     d¦  «         ŒØ|                     |¦  «         |                     d|› d�¦  «         ny|                     dd¦  «        }t                               d||¦  «         ddlm}  |t          j                             |¦  «        ¦  «        }|                     d|› d�¦  «         �Œ‚# t.          $ rm}t                               d|¦  «         ddlm}  |t          j                             |¦  «        ¦  «        }|                     d|› d�¦  «         Y d}~�Œôd}~ww xY w|rDd	                     |¦  «        }d
}|r| 	                    ¦   «         |k    r||fS |r	|› d	|› �|fS ||fS ||fS )aF  
        Auto-transcribe user voice/audio messages using the configured STT provider
        and prepend the transcript to the message text.

        Args:
            user_text:   The user's original caption / message text.
            audio_paths: List of local file paths to cached audio files.

        Returns:
            A tuple of ``(enriched_text, successful_transcripts)``:
              - ``enriched_text``: the message string with transcription wrappers
                prepended (same as before).
              - ``successful_transcripts``: the raw transcript strings for audio
                clips that were successfully transcribed, in input order. Empty
                list if every clip failed or STT is disabled. Callers can use
                this to echo transcripts back to the user before the agent loop.
        c                 óF   •— g | ]}|‰v¯‰                      |¦  «        °|‘ŒS rN  )r—   )rb   r;  r¢   s     €r>   r  zDGatewayRunner._enrich_message_with_transcription.<locals>.<listcomp>¦V  s-   ø€ ÐSÐSÐS˜Q°¸$°°ÀtÇxÂxÐPQÁ{Ä{°�q°°°rM   Ústt_enabledTNz [The user sent a voice message: z (duration: z)]rš  r  z.(The user sent a message with no text content)r   )Útranscribe_audioÚtranscribe_audio_local_fallbackz$Transcription module unavailable: %sz([voice message could not be transcribed]zTranscribing user voice: %sr/  z6Configured STT failed for %s; recovered with local STTr  r®   u°   [The user sent a voice message but it came through empty or inaudible â€” speech-to-text returned no words. Do not guess at the content; ask the user to resend or type it out.]rU  rP   rÛ  z%Voice transcription failed for %s: %sr£  zR[voice message could not be transcribed automatically; the audio is available at: zTranscription error: %s)r•   rV   rz   r’   r™   Úabspathr"  r”   rf   rx   Útools.transcription_toolsrD  rE  ÚModuleNotFoundErrorr3   rP   r4   r  r  rv   rz  rÇ  r¤  r2   )r  r7  rØ  Únotesr™   Úabs_pathÚduration_strr  Ú_placeholderrD  rE  r¨  Úunavailable_noter@  rÉ	  r·  r.  r  rP   r¤  rò  r¢   s                        @r>   rÅ  z0GatewayRunner._enrich_message_with_transcription�V  s‰  øè è € õ, ‰uŒuˆØSÐSÐSÐS +ÐSÑSÔSˆÝ�t”{ M°4Ñ8Ô8ð 	ØˆEØ#ð Qð Q�Ýœ7Ÿ?š?¨4Ñ0Ô0�Ý%:¸8Ñ%DÔ%DÐDÐDÐDÐDÐDÐD�Øð QØ—L’LØa¸8ÐaÐaÐQ]ÐaÐaÐañô ð ð ð —L’LÐ!OÀHÐ!OÐ!OÐ!OÑPÔPÐPÐPØð %Ø  "�}Ð$Ø—[’[ Ñ'Ô'ˆFØKˆLØð "˜YŸ_š_Ñ.Ô.°,Ò>Ð>Ø˜r�zÐ!Øð 6Ø Ð1Ð1 iÐ1Ð1°2Ð5Ð5Ø˜2�:Ðð	(ðð ð ð ð ð ð ð ð øõ #ð 	(ð 	(ð 	(Ý�LŠLÐ?ÀÑCÔCÐCØIÐØKˆLØð ,˜YŸ_š_Ñ.Ô.°,Ò>Ð>Ø'¨Ð+Ð+Ð+Ð+Ð+Ð+Ð+Øð @Ø*Ð;Ð;°	Ð;Ð;¸RÐ?Ð?Ð?Ð?Ð?Ð?Ð?Ø# RÐ'Ð'Ð'Ð'Ð'Ð'Ð'øøøøð	(øøøð ˆØ,.ÐØð @	ñ @	ˆDð?Ý—’Ð:¸DÑAÔAÐAÝ&Ô0Ð1AÀ4ÑHÔHÐHÐHÐHÐHÐHÐH�Ø—z’z )Ñ,Ô,ð 
*Ý%,Ô%6Ø7Øñ&ô &ð  ð  ð  ð  ð  ð  �Hð  —|’| IÑ.Ô.ð *ÝŸšØTØ ñô ð ð "*˜Ø˜)Ô$ð (Ø!'¨Ô!5�Jð 'Ð,¨"×3Ò3Ñ5Ô5ð !Ø&×-Ò-ð9ñô ð ð !Ø*×1Ò1°*Ñ=Ô=Ð=ð #×)Ò)Ð*;¨jÐ*;Ð*;Ð*;Ñ<Ô<Ð<Ð<à"ŸJšJ w°Ñ@Ô@�Eõ —K’KÐ GÈÈuÑUÔUÐUØRÐRÐRÐRÐRÐRà!<Ð!<½R¼W¿_º_ÈTÑ=RÔ=RÑ!SÔ!S�JØ"×)Ò)ðDØ6@ðDð Dð Dñô ð ùøõ ð ð ð Ý—’Ð6¸Ñ:Ô:Ð:ØNÐNÐNÐNÐNÐNà8Ð8½¼¿ºÈÑ9NÔ9NÑOÔO�
Ø×%Ò%ð@Ø2<ð@ð @ð @ñô ð ð ð ð ð ñ øøøøðøøøð ð 		2Ø—[’[ Ñ0Ô0ˆFð LˆLØð 6˜YŸ_š_Ñ.Ô.°,Ò>Ð>ØÐ5Ð5Ð5Øð JØ Ð1Ð1 iÐ1Ð1Ð3IÐIÐIØÐ1Ð1Ð1ØÐ0Ð0Ð0sW   Ã4C= Ã=
E'Ä<E"ÅE'Å	
E"ÅE'ÅE"ÅE'Å"E'Å4CK2ÉB(K2Ë2
M)Ë<A"M$Í$M)c                 ó¤   — g }t          |dd¦  «        pg }t          |¦  «        D ]*\  }}t          ||¦  «        r|                     |¦  «         Œ+|S )z7Return STT-eligible paths from a pending voice message.rì  N)rV   rí  ræ  r”   )r  rÖ  rØ  rì  rî  r™   s         r>   rÆ	  z(GatewayRunner._pending_event_audio_pathsW  se   € à!#ˆÝ˜U L°$Ñ7Ô7Ð=¸2ˆ
Ý  Ñ,Ô,ð 	)ð 	)‰GˆAˆtÝ(¨°Ñ2Ô2ð )Ø×"Ò" 4Ñ(Ô(Ð(øØÐrM   c              ƒ   óÀ  K  — t          |d¦  «        r4t          |d¦  «        }t          |dg ¦  «        pg }|t          |¦  «        fS |                      |¦  «        }|s|�|nt          |dd¦  «        pdg fS |�|nt          |dd¦  «        pd}|                      ||¦  «        ƒ d{V —†\  }}t          |d|¦  «         t          |dt          |¦  «        ¦  «         ||fS )aW  Transcribe a pending audio event once and cache the result on the event.

        Voice follow-ups can be inspected first by the interrupt monitor and
        later consumed by the pending-drain path.  Both need the same transcript,
        but only one STT call and one transcript echo should happen for the
        platform message.
        r�  Ú _gateway_pending_stt_transcriptsNrè   r®   )rá   rV   r½  rÆ	  rÅ  rÔ
  )	r  rÖ  r7  Úcached_textÚcached_transcriptsrØ  rè   rÈ	  rÉ	  s	            r>   r  z2GatewayRunner._transcribe_pending_audio_event_once$W  s9  è è € õ �5Ð5Ñ6Ô6ð 	9Ý! %Ð)DÑEÔEˆKÝ!(¨Ð0RÐTVÑ!WÔ!WÐ!]Ð[]ÐØ¥Ð%7Ñ 8Ô 8Ð8Ð8à×5Ò5°eÑ<Ô<ˆØð 	fØ )Ð 5�9�9½GÀEÈ6ÐSWÑ<XÔ<XÐ<`Ð\`ÐceÐeÐeà%Ð1ˆyˆy½ÀÀvÈrÑ8RÔ8RÐ8XÐVXˆØ6:×6]Ò6]ØØñ7
ô 7
ð 1
ð 1
ð 1
ð 1
ð 1
ð 1
Ñ-ˆÐ-õ 	�Ð2°MÑBÔBÐBÝ�Ð9½4Ð@VÑ;WÔ;WÑXÔXÐXØÐ4Ð4Ð4rM   Ú
Transcript©r¯   rÅ	  ÚtranscriptsrÅ	  c             ƒ   ó”  K  — |r|                       ¦   «         r|€dS t          t          |dd¦  «        pd¦  «        }||d…         }t          |d|t	          |¦  «        z   ¦  «         |D ]]}		 |                     |j        d|	› d�|¬¦  «        ƒ d{V —† Œ+# t          $ r&}
t           	                    d||
¦  «         Y d}
~
ŒVd}
~
ww xY wdS )aÕ  Echo pending-event STT transcripts to the chat at most once.

        The already-echoed transcripts are tracked as a COUNT rather than a
        single boolean.  ``merge_pending_message_event`` can append a second
        voice note to an event whose first transcript was already echoed and
        invalidates the transcription cache; the re-run transcription then
        returns the earlier transcripts as a prefix of the new list, so
        echoing only the unsent tail suppresses the repeat while still
        surfacing the newly merged note.  A count rather than a set of seen
        values because two separate notes that transcribe identically are two
        distinct deliveries and both must be echoed.
        NÚ_gateway_pending_stt_echoedr   r¢  rU  r.  z%s echo failed (non-fatal): %s)
rÆ  rh  rV   rÔ
  r7   r0  r2  r2   r3   r4   )r  rÖ  r1  r(  rU  r¯   rÅ	  Úalready_echoedÚunsentÚtxÚecho_excs              r>   Ú"_echo_pending_stt_transcripts_oncez0GatewayRunner._echo_pending_stt_transcripts_onceBW  s>  è è € ð. ð	à×4Ò4Ñ6Ô6ð	ð ˆàˆFÝ�W UÐ,IÈ1ÑMÔMÐRÐQRÑSÔSˆØ˜^˜_˜_Ô-ˆÝ�Ð4°nÅsÈ6Á{Ä{Ñ6RÑSÔSÐSØð 	Vð 	VˆBðVØ—l’lØ”NØ% Ð%Ð%Ð%Ø%ð #ñ ô ð ð ð ð ð ð ð ð øõ
 ð Vð Vð VÝ—’Ð=¸{ÈHÑUÔUÐUÐUÐUÐUÐUÐUøøøøðVøøøð	Vð 	Vs   Á-'BÂ
CÂC Ã Cr.  c             ƒ   óœ  K  — |                       |¦  «        s|g fS 	 |                      ||¦  «        ƒ d{V —†\  }}|t          u r)|                      ||                      |¦  «        ¦  «        n|}	|                      |||||	|¬¦  «        ƒ d{V —† |p||fS # t          $ r*}
t                               d||
¦  «         |g fcY d}
~
S d}
~
ww xY w)a]  Transcribe a pending voice event and echo transcripts once.

        Unified helper for all interrupt/monitor/backup/drain paths that need
        to transcribe a pending voice event and echo the transcript to chat.
        Returns ``(enriched_text, transcripts)`` so the caller can feed the
        enriched text into ``agent.interrupt()`` or the pending-drain flow.

        If the event has no STT-eligible media, returns ``(text, [])`` unchanged.
        The caller is responsible for the ``_build_media_placeholder`` fallback
        when ``text`` is empty and the event has non-audio media.
        NrT  z%s transcription failed: %s)	rÆ	  r  Ú_UNSETrî	  ru  r\  r2   r3   rã   )r  rÖ  r1  r(  rè   rÅ	  r¯   rÈ	  rU  Ú	echo_metaÚ	trans_excs              r>   rÇ	  z0GatewayRunner._transcribe_and_echo_pending_voicekW  sY  è è € ð* ×.Ò.¨uÑ5Ô5ð 	Ø˜�8ˆOð	Ø/3×/XÒ/XØØñ0ô 0ð *ð *ð *ð *ð *ð *Ñ&ˆM˜;ð �VÐ#Ð#ð ×8Ò8ØØ×,Ò,¨UÑ3Ô3ñô ð ð *2ð ð ×9Ò9ØØØØØ"Ø'ð :ñ ô ð ð ð ð ð ð ð ð !Ð( D¨+Ð5Ð5øÝð 	ð 	ð 	Ý�NŠNÐ8¸+ÀyÑQÔQÐQØ˜�8ˆOˆOˆOˆOˆOˆOøøøøð	øøøs   �A9B Â
CÂ!CÃ CÃCr¹  c                 óÂ  — ddl m} t          |                     d¦  «        pd¦  «                             ¦   «         }d}d}d}|rÉ	 | j                             ¦   «          | j        j                             |¦  «        }|rt          |dd¦  «        r|j	        S n3# t          $ r&}t                               d||¦  «         Y d}~nd}~ww xY w|                      |¦  «        }	|	�|	S t          |¦  «        }
|
r|
d         }|
d	         }|
d
         }t          |                     d¦  «        p|pd¦  «                             ¦   «                              ¦   «         }t          |                     d	¦  «        p|pd¦  «                             ¦   «                              ¦   «         }t          |                     d
¦  «        p|pd¦  «                             ¦   «         }|r|r|s5t                               d|||||                     dd¦  «        ¦  «         dS 	 t#          |¦  «        }|j        t&          vrN	 ddlm} |                     |j        ¦  «        st/          |¦  «        ‚n# t          $ r t/          |¦  «        ‚w xY wn,# t          $ r t                               d|¦  «         Y dS w xY w ||||t          |                     d¦  «        pd¦  «                             ¦   «         pdt          |                     d¦  «        pd¦  «                             ¦   «         pdt          |                     d¦  «        pd¦  «                             ¦   «         pd¬¦  «        S )a  Resolve the canonical source for a synthetic background-process event.

        Prefer the persisted session-store origin for the event's session key.
        Falling back to the currently active foreground event is what causes
        cross-topic bleed, so don't do that.
        r   )r[  r+   r®   r3
  Nz>Synthetic process-event session-store lookup failed for %s: %sr�   r´  r2  zcSynthetic event source unresolvable: session_key=%r platform=%r chat_type=%r chat_id=%r evt_type=%srÎ   r¿  rM  z9Synthetic process event has invalid platform metadata: %rr›  r¹  r)  )r�   r2  r´  r›  r¹  r)  )rr  r[  rw   rv   rx   r›  r9
  rÄ  rV   r3
  r2   r3   r4   r:
  r¸  ry   rã   rÄ  r­   rV  r‘  rN  rÿ  rj  )r  r¹  r[  r+   Úderived_platformÚderived_chat_typeÚderived_chat_idr®  r<   Úcached_sourcerC
  r_  r´  r2  r�   rN  s                   r>   Ú_build_process_event_sourcez)GatewayRunner._build_process_event_source˜W  sÑ  € ð 	2Ð1Ð1Ð1Ð1Ð1å˜#Ÿ'š' -Ñ0Ô0Ð6°BÑ7Ô7×=Ò=Ñ?Ô?ˆØÐØÐØˆàð 	5ð
ØÔ"×1Ò1Ñ3Ô3Ð3ØÔ*Ô3×7Ò7¸ÑDÔD�Øð (�W U¨H°dÑ;Ô;ð (Ø œ<Ð'øøÝð ð ð Ý—’ØTØØñô ð ð ð ð ð ð øøøøðøøøð !×;Ò;¸KÑHÔHˆMØÐ(Ø$Ð$å(¨Ñ5Ô5ˆGØð 5Ø#*¨:Ô#6Ð Ø$+¨KÔ$8Ð!Ø")¨)Ô"4�å˜CŸGšG JÑ/Ô/ÐIÐ3CÐIÀrÑJÔJ×PÒPÑRÔR×XÒXÑZÔZˆÝ˜Ÿš Ñ,Ô,ÐGÐ0AÐGÀRÑHÔH×NÒNÑPÔP×VÒVÑXÔXˆ	Ý�c—g’g˜iÑ(Ô(ÐA¨OÐA¸rÑBÔB×HÒHÑJÔJˆØð 	 Ið 	°Wð 	Ý�NŠNðð ˜]¨I°wØ—’˜ Ñ$Ô$ñô ð ð �4ð	Ý Ñ.Ô.ˆHð Œ~Õ%=Ð=Ð=ð4ØKÐKÐKÐKÐKÐKØ,×:Ò:¸8¼>ÑJÔJð 8Ý(¨Ñ7Ô7Ð7ð8øå ð 4ð 4ð 4Ý$ ]Ñ3Ô3Ð3ð4øøøøøåð 	ð 	ð 	Ý�NŠNØKØñô ð ð �4�4ð	øøøð ˆ}ØØØÝ˜#Ÿ'š' +Ñ.Ô.Ð4°"Ñ5Ô5×;Ò;Ñ=Ô=ÐEÀÝ˜Ÿš 	Ñ*Ô*Ð0¨bÑ1Ô1×7Ò7Ñ9Ô9ÐA¸TÝ˜#Ÿ'š' +Ñ.Ô.Ð4°"Ñ5Ô5×;Ò;Ñ=Ô=ÐEÀð
ñ 
ô 
ð 	
sC   ÁAB Â
C	Â#CÃC	ÈJ È4/I$ É#J É$I>É>J Ê%J+Ê*J+r)  c              ƒ   ó’  K  — |                       |¦  «        }|�spt          |                     d¦  «        pd¦  «                             ¦   «         }|sIt          |                     d¦  «        pd¦  «                             ¦   «         }|rt	          |¦  «        €|}|r¼| j                             t          j        ¦  «        }ddlm	}m
} |�q ||¦  «        sf	 t                               d|¦  «          ||||¬¦  «        ƒ d{V —† d	S # t          $ r'}	t                               d
||	¦  «         Y d}	~	dS d}	~	ww xY wt                               d|¦  «         dS t                               d|                     dd¦  «        ¦  «         dS t          |j        d¦  «        r|j        j        nt          |j        ¦  «        }
d}| j                             ¦   «         D ]\  }}|j        |
k    r|} nŒ|sdS ddlm	}  ||¦  «        s¸ddlm
} t          |                     d¦  «        pd¦  «                             ¦   «         pt          |j        pd¦  «        }	 t                               d|¦  «          ||||¬¦  «        ƒ d{V —† d	S # t          $ r'}	t                               d
||	¦  «         Y d}	~	dS d}	~	ww xY w	 i }t          |                     d¦  «        pd¦  «                             ¦   «         }|r||d<   t)          |t*          j        |d	t          |                     d¦  «        pd¦  «                             ¦   «         pd|¬¦  «        }t                               d|
|j        |j        ¦  «         |                     |¦  «        ƒ d{V —† d	S # t          $ r&}	t                               d|	¦  «         Y d}	~	dS d}	~	ww xY w)a  Inject a watch/completion notification as a synthetic message event.

        Routing must come from the queued event itself, not from whatever
        foreground message happened to be active when the queue was drained.
        Returns ``True`` after adapter acceptance, ``False`` after a retryable
        adapter failure, and ``None`` when the event has no gateway route. This
        is not a transactional boundary: a process crash after adapter
        acceptance can still cause durable at-least-once replay.
        Úorigin_session_idr®   r+   Nr   )Úadapter_supports_pushÚdeliver_wakeuI   Watch pattern notification â€” waking api_server session %s via self-post)rè   rN   Tz;Watch notification self-post wake failed for session %s: %sFzZDropping watch notification for raw session %s: no api_server adapter to self-post throughzCDropping watch notification with no routing metadata for process %srN   r¼  r­   )ri  )rj  Úparent_session_idr  rj  )rè   rÚ  r(  rã	  rj  r¯   uA   Watch pattern notification â€” injecting for %s chat=%s thread=%sre  )rf  rw   rv   rx   r¸  r°  rÄ  rÒ  Úgateway.wakeri  rj  r3   rz  r2   rã   rá   r�   r­   rñ  r2  rr  rs  rÀ	  r›  rË
  rP   )r  r)  r¹  r(  Úraw_sidr“  r1  ri  rj  r¨  r_  r;  r  Ú_wake_push_okr¯   rk  Úsynth_events                    r>   r˜  z(GatewayRunner._inject_watch_notificationæW  s±  è è € ð ×1Ò1°#Ñ6Ô6ˆØñ *	õ ˜#Ÿ'š'Ð"5Ñ6Ô6Ð<¸"Ñ=Ô=×CÒCÑEÔEˆGØð "Ý˜#Ÿ'š' -Ñ0Ô0Ð6°BÑ7Ô7×=Ò=Ñ?Ô?�Øð "Õ-¨cÑ2Ô2Ð:Ø!�GØð Øœ-×+Ò+­HÔ,?Ñ@Ô@�ØLÐLÐLÐLÐLÐLÐLÐLØÐ&Ð/DÐ/DÀWÑ/MÔ/MÐ&ð%ÝŸšð7à#ñô ð ð
 +˜l¨7¸ÐPWÐXÑXÔXÐXÐXÐXÐXÐXÐXÐXØ#˜tøÝ$ð %ð %ð %ÝŸšð-à# Qñô ð ð
  %˜u˜u˜u˜u˜uøøøøð%øøøõ —’ð>àñô ð ð
 �tÝ�NŠNØUØ—’˜ iÑ0Ô0ñô ð ð �4Ý18¸¼È'Ñ1RÔ1RÐl˜œÔ-Ð-ÕX[Ð\bÔ\kÑXlÔXlˆØˆØ”M×'Ò'Ñ)Ô)ð 	ð 	‰DˆAˆqØŒw˜-Ò'Ð'Ø�Ø�ð (ð ð 	Ø�4ØGÐGÐGÐGÐGÐGØˆ}˜WÑ%Ô%ð 	ð 2Ð1Ð1Ð1Ð1Ð1Ý˜#Ÿ'š'Ð"5Ñ6Ô6Ð<¸"Ñ=Ô=×CÒCÑEÔEÐbÍÈVÌ^ÐMaÐ_aÑIbÔIbˆGðÝ—’ð'àñô ð ð
 #�l 7°ÈÐPÑPÔPÐPÐPÐPÐPÐPÐPÐPØ�tøÝð ð ð Ý—’ðà˜Qñô ð ð
 �u�u�u�u�uøøøøðøøøð	ØˆHÝ # C§G¢GÐ,?Ñ$@Ô$@Ð$FÀBÑ GÔ G× MÒ MÑ OÔ OÐØ ð CØ1B�Ð-Ñ.Ý&ØÝ(Ô-ØØÝ˜sŸwšw |Ñ4Ô4Ð:¸Ñ;Ô;×AÒAÑCÔCÐKÀtØ!ðñ ô ˆKõ �KŠKØSØØ”ØÔ ñ	ô ð ð ×(Ò(¨Ñ5Ô5Ð5Ð5Ð5Ð5Ð5Ð5Ð5Ø�4øÝð 	ð 	ð 	Ý�LŠLÐAÀ1ÑEÔEÐEØ�5�5�5�5�5øøøøð	øøøsI   Ã/D	 Ä	
D:ÄD5Ä5D:É/J	 Ê	
J:ÊJ5Ê5J:Ê>CN Î
OÎ OÏOc                 óD  — t          |                      d¦  «        pd¦  «        }|dk    r-t          |                      d¦  «        pd¦  «        }|r||dfndS |dk    rBt          |                      d¦  «        pd¦  «        }|                      d¦  «        }|r|�|||fS dS )	a½  Return a producer-stable identity when one is available.

        Delegation UUIDs identify one producer completion. Process session IDs
        are normally unique too, but include the persisted spawn epoch so an
        explicitly reused ID represents a distinct process incarnation. Legacy
        process events without ``started_at`` are delivered without deduplication
        rather than risking suppression of a real completion.
        rÎ   r®   rÂ  Údelegation_idNr»  rN   r  )rw   rv   )r¹  rÄ  Úproducer_idr  s       r>   Ú_completion_delivery_identityz+GatewayRunner._completion_delivery_identityWX  sº   € õ �s—w’w˜v‘”Ð,¨"Ñ-Ô-ˆØÐ)Ò)Ð)Ý˜cŸgšg oÑ6Ô6Ð<¸"Ñ=Ô=ˆKØ2=ÐG�H˜k¨2Ð.Ð.À4ÐGØ�|Ò#Ð#Ý˜cŸgšg lÑ3Ô3Ð9°rÑ:Ô:ˆKØŸš Ñ.Ô.ˆJØð ;˜zÐ5Ø  +¨zÐ:Ð:ØˆtrM   rk  c              ƒ   óH  K  — t          | dd¦  «        }|€dS 	 |                     |¦  «        ƒ d{V —†}n.# t          $ r! t                               d|d¬¦  «         Y dS w xY w|€dS |                     d¦  «        sd	S |                     d
¦  «        dk    rdS 	 |                     |¦  «        ƒ d{V —†}|r||k    rdS |                     |¦  «        ƒ d{V —†}n.# t          $ r! t                               d|d¬¦  «         Y dS w xY w|�|                     d¦  «        rdS d	S )u0  Classify an async-completion delivery target before adapter acceptance.

        Returns one of:

        - ``"deliver"`` â€” the spawning session is live, or ended by a
          compression rotation with a verified live continuation. The inner
          #55578 resolver (:meth:`_resolve_async_delegation_session`) still
          owns the actual route retarget; this pre-flight only proves the
          completion is deliverable so the durable ack stays honest.
        - ``"terminal"`` â€” the spawning session is gone for good (unknown, or
          ended at an explicit user boundary such as /new). Delivery can never
          succeed; the durable row should be terminally dropped rather than
          falsely acknowledged as delivered or replayed forever as pending.
        - ``"retry"`` â€” transient uncertainty (session DB unavailable, lookup
          error, or a compression rotation caught mid-flight before its
          continuation exists). The claim should be released so a later
          consumer can retry; the attempt cap bounds the churn.
        rR   NrÀ  z7Async-completion pre-flight parent lookup failed for %sTrß   rÌ  r  Údeliverr  rm   z4Async-completion pre-flight tip lookup failed for %s)rV   r�  r2   r3   r4   rv   r  )r  rk  rX   r‘   Útip_session_idÚtips         r>   Ú_classify_completion_targetz)GatewayRunner._classify_completion_targetlX  s­  è è € õ& ˜T =°$Ñ7Ô7ˆ
ØÐØ�7ð	Ø%×1Ò1Ð2CÑDÔDÐDÐDÐDÐDÐDÐDˆFˆFøÝð 	ð 	ð 	Ý�LŠLØIØ!¨Dð ñ ô ð ð �7�7ð	øøøð ˆ>Ø�:Ø�zŠz˜*Ñ%Ô%ð 	Ø�9Ø�:Š:�lÑ#Ô# }Ò4Ð4Ø�:ð	Ø#-×#AÒ#AÐBSÑ#TÔ#TÐTÐTÐTÐTÐTÐTˆNØ!ð  ^Ð7HÒ%HÐ%Hð �wØ"×.Ò.¨~Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>ˆCˆCøÝð 	ð 	ð 	Ý�LŠLØFØ!¨Dð ñ ô ð ð �7�7ð	øøøð ˆ;˜#Ÿ'š' *Ñ-Ô-ˆ;Ø�7Øˆys'   ™5 µ'A ÁA Â#C Â?C Ã'DÄDc              ƒ   ó´	  K  — |                       |¦  «        }d}d}|                     d¦  «        dk    �r®t          |                     d¦  «        pd¦  «        }|rƒ	 ddlm} dt          | ¦  «        › dt          d	¦  «                             ¦   «         j        › �} |||¦  «        sd
S n4# t          $ r'}t                               d||¦  «         Y d
}~dS d
}~ww xY wt          |                     d¦  «        pd¦  «                             ¦   «         }|rÍ|                      |¦  «        ƒ d
{V —†}	|	dk    rbt                               d|pd|¦  «         |r@	 ddlm}
  |
||¦  «         n,# t          $ r t                               dd¬¦  «         Y nw xY wd
S |	dk    rD|r@	 ddlm}  |||¦  «         n,# t          $ r t                               dd¬¦  «         Y nw xY wdS |�Y| j        5  || j        v s	|| j        v r	 d
d
d
¦  «         d
S | j                             |¦  «         d
d
d
¦  «         n# 1 swxY w Y   d}	 |                      ||¦  «        ƒ d
{V —†}|dur„||�;|s9| j        5  | j                             |¦  «         d
d
d
¦  «         n# 1 swxY w Y   |rB|sA	 ddlm}  |||¦  «         S # t          $ r t                               dd¬¦  «         Y S w xY wS S d}|�˜| j        5  | j                             |¦  «         d
| j        |<   t/          | j        ¦  «        | j        k    r8| j                             d¬¦  «         t/          | j        ¦  «        | j        k    °8d
d
d
¦  «         n# 1 swxY w Y   |rG	 ddlm}  |||¦  «         n3# t          $ r&}t                               d||¦  «         Y d
}~nd
}~ww xY w	 |�;|s9| j        5  | j                             |¦  «         d
d
d
¦  «         n# 1 swxY w Y   |rD|sD	 ddlm}  |||¦  «         dS # t          $ r  t                               dd¬¦  «         Y dS w xY wdS dS # |�;|s9| j        5  | j                             |¦  «         d
d
d
¦  «         n# 1 swxY w Y   |rB|sA	 ddlm}  |||¦  «         w # t          $ r t                               dd¬¦  «         Y w w xY ww w xY w)aœ  Deliver once per live gateway, or return False for a retry.

        ``True`` means this caller reached adapter acceptance, ``False`` means
        injection failed and the claim was released for retry, and ``None``
        means either another same-lifecycle caller owns/delivered the producer
        event or the event has no gateway route. No cross-process exactly-once
        guarantee is claimed.
        r®   rÎ   rÂ  rq  r   )Úclaim_completion_deliveryr§	  rÉ  rK  Nz/Could not claim durable async completion %s: %sFrk  rÌ  z�Async delegation %s targets permanently-gone session %s; terminally dropping delivery (result remains in the delegation records).z<legacy>)Údrop_completion_deliveryz'Could not drop durable completion claimTrß   rÀ  )Úrelease_completion_deliveryz*Could not release durable completion claimr  )Úcomplete_completion_deliveryz5Could not acknowledge durable async completion %s: %s)rs  rv   rw   rÌ  rz  rÍ   Ú
__import__rL  rM  r2   r3   rã   rx   rx  r{  r4   r|  r£  r¤  r¥  r—   r˜  rü  r7   r¦  r  r}  )r  r)  r¹  ÚidentityÚdurable_claim_idÚdurable_delegation_idrz  r<   rk  Úverdictr{  r|  r†  Úinjection_resultr}  s                  r>   Ú _deliver_completion_notificationz.GatewayRunner._deliver_completion_notification¡X  s"	  è è € ð ×5Ò5°cÑ:Ô:ˆØÐØ "ÐØ�7Š7�6‰?Œ?Ð0Ò0Ñ0Ý$'¨¯ª°Ñ(@Ô(@Ð(FÀBÑ$GÔ$GÐ!Ø$ð !ð!ØPÐPÐPÐPÐPÐPà']µ"°T±(´(Ð']Ð']½ZÈÑ=OÔ=O×=UÒ=UÑ=WÔ=WÔ=[Ð']Ð']Ð$Ø4Ð4Ø-Ð/?ñô ð $ð  $˜tð$øõ !ð !ð !ð !Ý—N’NØIØ-¨sñô ð ð !˜5˜5˜5˜5˜5øøøøð!øøøõ !$ C§G¢GÐ,?Ñ$@Ô$@Ð$FÀBÑ GÔ G× MÒ MÑ OÔ OÐØ ð )!ð !%× @Ò @ÐARÑ SÔ SÐSÐSÐSÐSÐSÐS�Ø˜jÒ(Ð(Ý—N’Nð/ð .Ð;°Ð=Nñ	ô ð ð (ð ð
ØWÐWÐWÐWÐWÐWà4Ð4Ø 5Ð7Gñô ð ð øõ  )ð ð ð Ý"ŸLšLØ IØ)-ð )ñ ô ð ð ð ðøøøð
  ˜4Ø˜gÒ%Ð%Ø'ð ð
ØZÐZÐZÐZÐZÐZà7Ð7Ø 5Ð7Gñô ð ð øõ  )ð ð ð Ý"ŸLšLØ LØ)-ð )ñ ô ð ð ð ðøøøð
 !˜5ØÐØÔ/ð Cð Cà Ô DÐDÐDØ 4Ô#HÐHÐHàðCð Cð Cñ Cô Cð Cð Cð Cð Ô4×8Ò8¸ÑBÔBÐBðCð Cð Cñ Cô Cð Cð Cð Cð Cð Cð Cøøøð Cð Cð Cð Cð ˆð,	^Ø%)×%DÒ%DÀZÐQTÑ%UÔ%UÐUÐUÐUÐUÐUÐUÐØ tÐ+Ð+Ø'ð< Ð#¨HÐ#ØÔ3ð Kð KØÔ8×@Ò@ÀÑJÔJÐJðKð Kð Kñ Kô Kð Kð Kð Kð Kð Kð Køøøð Kð Kð Kð Kàð ^¨ð ^ð^ØRÐRÐRÐRÐRÐRà/Ð/Ø-Ð/?ñô ð ð øõ !ð ^ð ^ð ^Ý—L’LÐ!MÐX\�LÑ]Ô]Ð]Ð]Ð]ð^øøøð^ð ^ðA ˆHàÐ#ØÔ3ð Rð RØÔ8×@Ò@ÀÑJÔJÐJØFJ�DÔ9¸(ÑCå˜DÔAÑBÔBØÔ=ò>ð >ð Ô=×EÒEÈ5ÐEÑQÔQÐQõ ˜DÔAÑBÔBØÔ=ò>ð >ð	Rð Rð Rñ Rô Rð Rð Rð Rð Rð Rð Røøøð Rð Rð Rð Rð  ð ð
ØSÐSÐSÐSÐSÐSà0Ð0Ø-Ð/?ñô ð ð øõ !ð ð ð Ý—N’NØOØ-¨sñô ð ð ð ð ð ð øøøøðøøøð
 àÐ#¨HÐ#ØÔ3ð Kð KØÔ8×@Ò@ÀÑJÔJÐJðKð Kð Kñ Kô Kð Kð Kð Kð Kð Kð Køøøð Kð Kð Kð Kàð ^¨ð ^ð^ØRÐRÐRÐRÐRÐRà/Ð/Ø-Ð/?ñô ð ð ð øõ !ð ^ð ^ð ^Ý—L’LÐ!MÐX\�LÑ]Ô]Ð]Ð]Ð]Ð]ð^øøøð^ð ^ð ^ð ^øð Ð#¨HÐ#ØÔ3ð Kð KØÔ8×@Ò@ÀÑJÔJÐJðKð Kð Kñ Kô Kð Kð Kð Kð Kð Kð Køøøð Kð Kð Kð Kàð ^¨ð ^ð^ØRÐRÐRÐRÐRÐRà/Ð/Ø-Ð/?ñô ð ð øõ !ð ^ð ^ð ^Ý—L’LÐ!MÐX\�LÑ]Ô]Ð]Ð]Ð]ð^øøøð^ð ^øøøsF  ÁAB+ Â+
CÂ5CÃCÅE, Å,&FÆFÆ#F6 Æ6&GÇGÇ-H4ÈH4È4H8È;H8É!Q É.JÊJ	ÊJ	Ê%J8Ê8&K!Ë K!Ë&Q Ë1A:M7Í+Q Í7M;Í;Q Í>M;Í?Q ÎN ÎQ Î
OÎ"OÎ>Q ÏOÏQ ÏO>Ï>PÐPÐP" Ð"&QÑQÑSÑRÑ:SÒR
Ò
SÒR
ÒSÒR)Ò(SÒ)&SÓSÓSÓSc                 ó`  — |                      d¦  «        rdS t          |                      dd¦  «        pd¦  «        }|sdS |                      dd¦  «        |d<   |                      dd¦  «        |d<   |                      dd¦  «        |d<   |                      d¦  «        r|d         |d<   dS dS )aý  Fill platform/chat_id/thread_id/chat_type on an async-delegation event.

        Async-delegation completion events only carry ``session_key`` (the
        daemon worker has no access to the per-message routing metadata the
        terminal background watcher captures at spawn time). Parse the
        session_key into the routing fields ``_build_process_event_source``
        expects. Best-effort: a CLI-origin event (empty session_key) is left
        as-is and simply won't route on the gateway.
        r�   Nr+   r®   r´  r2  r›  )rv   r¸  )r  r¹  rÞ  s      r>   Ú _enrich_async_delegation_routingz.GatewayRunner._enrich_async_delegation_routing#Y  sÃ   € ð �7Š7�:ÑÔð 	ØˆFÝ# C§G¢G¨M¸2Ñ$>Ô$>Ð$DÀ"ÑEÔEˆØð 	ØˆFØ Ÿ*š* Z°Ñ4Ô4ˆˆJ‰Ø!Ÿ:š: k°2Ñ6Ô6ˆˆKÑØŸš I¨rÑ2Ô2ˆˆI‰Ø�:Š:�kÑ"Ô"ð 	3Ø% kÔ2ˆC�ÑÐÐð	3ð 	3rM   c              ƒ   óø  K  — t          j        d¦  «        ƒ d{V —† ddlm} | j        �rÏ	 g }g }|j                             ¦   «         sˆ	 |j                             ¦   «         }n# t          $ r Y naw xY w| 	                    d¦  «        dk    r| 
                    |¦  «         n| 
                    |¦  «         |j                             ¦   «         ¯ˆ|D ]}|j                             |¦  «         Œ|D ]°}|                      |¦  «         t          |¦  «        }|sŒ)	 |                      ||¦  «        ƒ d{V —†}|du r|j                             |¦  «         Œe# t          $ r?}|j                             |¦  «         t                               d|¦  «         Y d}~Œ©d}~ww xY wn2# t          $ r%}t                               d	|¦  «         Y d}~nd}~ww xY wt          j        |¦  «        ƒ d{V —† | j        �°ÍdS dS )
uØ  Drain async-delegation completions and inject them as new turns.

        Background subagents (``delegate_task(background=true)``) run on the
        async-delegation daemon executor â€” they have no per-process watcher
        task, so their completion events would only be seen by the post-turn
        queue drain. This watcher covers the IDLE case: when a background
        subagent finishes while no agent turn is running, its result still
        re-enters the originating session promptly.

        Mirrors the CLI's idle ``process_loop`` drain. Stays silent when the
        queue has nothing for us; ignores non-async event types (those are
        handled by ``_run_process_watcher`` / the post-turn drain).
        r)   Nr   r*  rÎ   rÂ  Fz$Async delegation injection error: %sz"Async delegation watcher error: %s)r  r–  r-  r+  r’  rÐ  rÍ  rÎ  r2   rv   r”   rÏ  r†  rÊ  r„  r3   rP   r4   )	r  r		  r'  rÒ  Úasync_eventsr¹  r)  r  r¨  s	            r>   r²  z'GatewayRunner._async_delegation_watcher8Y  s¬  è è € õ Œm˜AÑÔÐÐÐÐÐÐÐØBÐBÐBÐBÐBÐBØŒmñ  	*ðFð �Ø!�ØÔ.×4Ò4Ñ6Ô6ð ,ðØ!Ô2×=Ò=Ñ?Ô?˜˜øÝ$ð ð ð Ø˜ðøøøà—w’w˜v‘”Ð*<Ò<Ð<Ø$×+Ò+¨CÑ0Ô0Ð0Ð0àŸš sÑ+Ô+Ð+ð Ô.×4Ò4Ñ6Ô6ð ,ð #ð 2ð 2�CØÔ(×,Ò,¨SÑ1Ô1Ð1Ð1Ø'ð Pð P�CØ×9Ò9¸#Ñ>Ô>Ð>Ý!EÀcÑ!JÔ!J�JØ%ð !Ø ðPØ*.×*OÒ*OÐPZÐ\_Ñ*`Ô*`Ð$`Ð$`Ð$`Ð$`Ð$`Ð$`˜	Ø$¨Ð-Ð-ØÔ0×4Ò4°SÑ9Ô9Ð9øøÝ$ð Pð Pð PØÔ,×0Ò0°Ñ5Ô5Ð5ÝŸšÐ%KÈQÑOÔOÐOÐOÐOÐOÐOÐOøøøøðPøøøðPøõ ð Fð Fð FÝ—’ÐAÀ1ÑEÔEÐEÐEÐEÐEÐEÐEøøøøðFøøøå”- Ñ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)ðA Œmñ  	*ð  	*ð  	*ð  	*ð  	*sf   ¬F$ Á
A$ Á#F$ Á$
A1Á.F$ Á0A1Á1B*F$ Ä:EÅF$ Å
F Å!5FÆF$ ÆF Æ F$ Æ$
GÆ.GÇGr�
  c              ƒ   ó.  K  — ddl m} |d         }|d         }|                     dd¦  «        }|                     dd¦  «        }|                     dd¦  «        }|                     d	d¦  «        }|                     d
d¦  «        }	|                     dd¦  «        }
t          |                     d¦  «        pd¦  «                             ¦   «         pd}|                     dd¦  «        }|                      ¦   «         }t                               d||||¦  «         |dk    rZ|sX	 t          j	        |¦  «        ƒ d{V —† |                     |¦  «        }|�|j
        rnŒ:t                               d|¦  «         dS d}	 t          j	        |¦  «        ƒ d{V —† |                     |¦  «        }|€�nÇt          |j        ¦  «        }||k    }|}|j
        �r´ddl m}m} |�rv|                     |¦  «        �s`ddlm} ddlm} t'          |dd¦  «        pd}|j        r ||j        ¦  «        nd} |||¦  «        }t)          |¦  «        }d}t          |¦  «        |k    rK|| d…         }|                     d¦  «        }|dk    r||dz   d…         n|}dt          |¦  «        › d|› �}n|}i dd“d|“d|“d|“d |                     d d¦  «        “d|“d	|“d
|	“d|
“d|“d!t'          |d!d¦  «        “d|“d"|j        “d#t'          |d#d$¦  «        “d%t'          |d%d¦  «        “d&|“} ||¦  «        }|s�nF|                      ||¦  «        ƒ d{V —†}|du r�Œ×�n"|                     |¦  «        rt                               d'|¦  «         �nð|d(v p|d)k    o|j        d*v}|rë|j        r|j        d+d…         nd} | r#ddlm}  || t'          |dd¦  «        pd¦  «        } d,|› d-|j        › d.| › d/�}!d}"| j                             ¦   «         D ]\  }#}$|#j        |k    r|$}" nŒ|"rk|ri	 |rd	|ind}%|"                     ||!t9          |%|¬0¦  «        ¬1¦  «        ƒ d{V —† n2# t:          $ r%}&t                               d2|&¦  «         Y d}&~&nd}&~&ww xY wnï|rë|d3k    rå|sã|j        r|j        d4d…         nd} | r#ddlm}  || t'          |dd¦  «        pd¦  «        } d,|› d5| › d/�}!d}"| j                             ¦   «         D ]\  }#}$|#j        |k    r|$}" nŒ|"rk|ri	 |rd	|ind}%|"                     ||!t9          |%|¬0¦  «        ¬1¦  «        ƒ d{V —† n2# t:          $ r%}&t                               d2|&¦  «         Y d}&~&nd}&~&ww xY w�Œút                               d6|¦  «         dS )7u  
        Periodically check a background process and push updates to the user.

        Runs as an asyncio task. Stays silent when nothing changed.
        Auto-removes when the process exits or is killed.

        Notification mode (from ``display.background_process_notifications``):
          - ``all``    â€” running-output updates + final message
          - ``result`` â€” final completion message only
          - ``error``  â€” final message only when exit code != 0
          - ``off``    â€” no messages at all
        r   r*  rN   Úcheck_intervalr+   r®   r�   r2  r›  r¹  r)  rj  NÚnotify_on_completeFzCProcess watcher started: %s (every %ss, notify=%s, agent_notify=%s)r  Tz"Process watcher ended (silent): %s)rÃ  r+  )Úredact_terminal_outputré  r   rÍ  r  r	  r(   u'   [â€¦ output truncated â€” showing last z chars]
rÎ   r»  r´  r  r8  Úcompletion_reasonÚexitedÚtermination_sourcerÀ  ug   Process watcher: completion for %s already consumed via wait/log â€” skipping raw notification (#65379)>   r�  r·  rP   >   Nr   iüÿÿz[Background process z finished with exit code z~ Here's the final output:
rš  r…   r.  zWatcher delivery error: %sr�  iþÿÿz is still running~ New output:
zProcess watcher ended: %s)r-  r+  rv   rw   rx   r‰	  r3   r4   r  r–  rŽ  r7   Úoutput_bufferrÃ  Úis_completion_consumedró   rŒ  rë  rê  rV   rø   r"  r8  r„  r°  rñ  r­   r0  r´   r2   rP   )'r  r�
  r+  rN   r		  r+   r_  r2  r›  r¹  r)  rj  Úagent_notifyÚnotify_moderâ	  Úlast_output_lenÚcurrent_output_lenÚhas_new_outputrÃ  Ú	_pr_checkrŒ  rê  Ú_commandÚ_rawÚ_LIMITÚ_tailÚ_nlrÈ  Úcompletion_evtr)  r  rµ  Ú
new_outputrÐ  r1  r;  r  Ú	send_metar¨  s'                                          r>   rt  z"GatewayRunner._run_process_watcherjY  s˜  è è € ð 	<Ð;Ð;Ð;Ð;Ð;à˜\Ô*ˆ
ØÐ+Ô,ˆØ—k’k -°Ñ4Ô4ˆØŸš J°Ñ3Ô3ˆØ—+’+˜i¨Ñ,Ô,ˆØ—K’K ¨RÑ0Ô0ˆ	Ø—+’+˜i¨Ñ,Ô,ˆØ—K’K ¨RÑ0Ô0ˆ	Ý˜Ÿš \Ñ2Ô2Ð8°bÑ9Ô9×?Ò?ÑAÔAÐIÀTˆ
Ø—{’{Ð#7¸Ñ?Ô?ˆØ×>Ò>Ñ@Ô@ˆå�ŠÐZØ  (¨K¸ñ	Gô 	Gð 	Gð ˜%ÒÐ¨ÐðÝ”m HÑ-Ô-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ø*×.Ò.¨zÑ:Ô:�Ø�? g¤n�?Øð	õ
 �LŠLÐ=¸zÑJÔJÐJØˆFàˆðP	FÝ”- Ñ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)à&×*Ò*¨:Ñ6Ô6ˆGØˆÙå!$ WÔ%:Ñ!;Ô!;ÐØ/°/ÒAˆNØ0ˆOàŒ~ñ EFð
 nÐmÐmÐmÐmÐmÐmÐmØñ /¨	×(HÒ(HÈÑ(TÔ(Tñ /ØCÐCÐCÐCÐCÐCØ;Ð;Ð;Ð;Ð;Ð;Ý& w°	¸2Ñ>Ô>ÐDÀ"�HØ@GÔ@UÐ]˜:˜: gÔ&;Ñ<Ô<Ð<Ð[]�DØ1Ð1°$¸ÑAÔA�DÝBÀ8ÑLÔL�Hð
 "�FÝ˜4‘y”y 6Ò)Ð)Ø $ f W X X¤˜Ø#Ÿjšj¨Ñ.Ô.˜Ø36¸"²9°9  c¨A¡g h h¤ À%˜ØeÍÈUÉÌÐeÐeÐ^cÐeÐe˜˜à#˜ð&Ø ð&à$ jð&ð & {ð&ð # Mð	&ð
 $ W§[¢[°¸bÑ%AÔ%Að&ð " 7ð&ð $ Yð&ð " 7ð&ð $ Yð&ð % jð&ð %¥g¨g°|ÀTÑ&JÔ&Jð&ð " 8ð&ð $ WÔ%6ð&ð ,­W°WÐ>QÐS[Ñ-\Ô-\ð&ð -­g°gÐ?SÐUWÑ.XÔ.Xð&ð  ! $ð!&�Nð$ "=Ð!<¸^Ñ!LÔ!L�JØ%ð ÙØ&*×&KÒ&KØ" Nñ'ô 'ð !ð !ð !ð !ð !ð !�Ið ! EÐ)Ð)ñ !Ùð ×3Ò3°JÑ?Ô?ð Ý—L’LðNà"ñô ð ñ
 ð  Ð#4Ð4ð WØ# wÒ.ÐU°7Ô3DÈIÐ3Uð ð !ð JØBIÔBWÐ!_ Ô!6°u°v°vÔ!>Ð!>Ð]_�JØ!ð ØGÐGÐGÐGÐGÐGØ%;Ð%;Ø&­°¸ÀBÑ(GÔ(GÐ(MÈ2ñ&ô &˜
ðC¨zð Cð CÐT[ÔTeð Cð CØ5?ðCð Cð Cð !ð #�GØ $¤× 3Ò 3Ñ 5Ô 5ð "ð "™˜˜1Øœ7 mÒ3Ð3Ø&'˜GØ!˜Eð 4ð ð 	J 7ð 	JðJØDMÐ(W¨°iÐ(@Ð(@ÐSW˜IØ")§,¢,Ø 'Ø ,Ý)EÀiÐZgÐ)hÑ)hÔ)hð #/ñ #ô #ð ð ð ð ð ð ð ð øõ
  )ð Jð Jð JÝ"ŸLšLÐ)EÀqÑIÔIÐIÐIÐIÐIÐIÐIøøøøðJøøøààð F K°5Ò$8Ð$8ÀÐ$8ð >EÔ=RÐZ˜WÔ2°4°5°5Ô9Ð9ÐXZ�
Øð ØCÐCÐCÐCÐCÐCØ!7Ð!7Ø"¥G¨G°YÀÑ$CÔ$CÐ$IÀrñ"ô "�Jð2¨:ð 2ð 2Ø$.ð2ð 2ð 2ð ð �Ø œM×/Ò/Ñ1Ô1ð ð ‘D�A�qØ”w -Ò/Ð/Ø"#˜Ø˜ð 0ð ð 	F˜wð 	FðFØ@IÐ$S [°)Ð$<Ð$<Èt˜	Ø%ŸlšlØ#Ø(Ý%AÀ)ÐVcÐ%dÑ%dÔ%dð +ñ ô ð ð ð ð ð ð ð ð øõ
 %ð Fð Fð FÝŸšÐ%AÀ1ÑEÔEÐEÐEÐEÐEÐEÐEøøøøðFøøøñ_P	Fõd 	�ŠÐ0°*Ñ=Ô=Ð=Ð=Ð=s0   Ð"5Q Ñ
RÑ"RÒRÔ5U Õ
U5ÕU0Õ0U5))r  r|  )r  r´  )rm   rÓ  )rm   rn   )rm   Ú	threshold)rm   Úmodel_thresholds)rm   Úthreshold_tokens)rm   Úcodex_gpt55_autoraise)rm   Úcodex_app_server_auto)rm   Útarget_ratio)rm   Úprotect_last_n)rm   Úproactive_prune_tokens)rm   Ú proactive_prune_min_result_chars)rm   Ú"proactive_prune_min_reclaim_tokens)rm   Úmin_tail_user_messages)rµ   r  )r¶  r  )rŠ  rÓ  )rŠ  r‹  )rŠ  rŒ  )rŠ  r�  Ú_CACHE_BUSTING_CONFIG_KEYS©zhoncho.peer_namezhoncho.ai_peerzhoncho.pin_peer_namezhoncho.runtime_peer_prefixzhoncho.user_peer_aliasesÚ_HONCHO_CACHE_BUSTING_MEMOc                 ó$   — d„ | j         D ¦   «         S )Nc                 ó   — i | ]}|d “ŒS r^   rN  )rb   r  s     r>   rê  zDGatewayRunner._empty_honcho_cache_busting_config.<locals>.<dictcomp>UZ  s   € ÐDÐDÐD˜c��TÐDÐDÐDrM   )Ú_HONCHO_CACHE_BUSTING_KEYS)Úclss    r>   Ú"_empty_honcho_cache_busting_configz0GatewayRunner._empty_honcho_cache_busting_configSZ  s   € àDÐD SÔ%CÐDÑDÔDÐDrM   c                 ór  — 	 ddl m}m}  |¦   «         }	 |                     ¦   «         j        }n# t
          $ r d}Y nw xY wt          |¦  «        |f}| j                             |¦  «        }|�t          |¦  «        S | 
                    |¬¦  «        }|j        pi }|j        |j        t          |j        ¦  «        |j        pdt#          |t          ¦  «        r!t%          |                     ¦   «         ¦  «        ng dœ}	||	i| _        t          |	¦  «        S # t(          $ r |                      ¦   «         cY S w xY w)z<Extract Honcho identity keys, memoized by honcho.json mtime.r   )ÚHonchoClientConfigÚresolve_config_pathN)r›  r®   r¬  )Úplugins.memory.honcho.clientr´  rµ  ÚstatÚst_mtime_nsr–   rw   r­  rv   ru   Úfrom_global_configÚuser_peer_aliasesÚ	peer_nameÚai_peerrº   Úpin_peer_nameÚruntime_peer_prefixrt   r  rñ  r2   r²  )
r±  r´  rµ  r™   Úmtime_nsÚmemo_keyrí  ÚhcfgÚaliasesr•  s
             r>   Ú$_extract_honcho_cache_busting_configz2GatewayRunner._extract_honcho_cache_busting_configWZ  sj  € ð	<Ø\Ð\Ð\Ð\Ð\Ð\Ð\Ð\à&Ð&Ñ(Ô(ˆDð ØŸ9š9™;œ;Ô2��øÝð  ð  ð  Ø���ð øøøå˜D™	œ	 8Ð,ˆHØÔ3×7Ò7¸ÑAÔAˆFØÐ!Ý˜F‘|”|Ð#à%×8Ò8ÀTÐ8ÑJÔJˆDØÔ,Ð2°ˆGà$(¤NØ"&¤,Ý(,¨TÔ-?Ñ(@Ô(@Ø.2Ô.FÐ.LÈ"ÝGQÐRYÕ[_ÑG`ÔG`Ð,h­F°7·=²=±?´?Ñ,CÔ,CÐ,CÐfhðð ˆFð /7¸Ð-?ˆCÔ*Ý˜‘<”<ÐøÝð 	<ð 	<ð 	<Ø×9Ò9Ñ;Ô;Ð;Ð;Ð;ð	<øøøs3   ‚D •/ ®D ¯>»D ½>¾>D Á=BD ÄD6Ä5D6c                 óÒ  — i }t          |t          ¦  «        r|ni }| j        D ]…\  }}|                     |¦  «        }|dk    r(t          |t          ¦  «        r|dk    r|nd||› d|› �<   ŒHt          |t          ¦  «        r|                     |¦  «        ||› d|› �<   Œ{d||› d|› �<   Œ†	 ddlm} t          |dd¦  «        |d<   n# t          $ r d|d<   Y nw xY wt          |d	d
¦  «        }t          |t          ¦  «        r@|                     ¦   «         dk    r(|                     |                      ¦   «         ¦  «         n'|                     |                      ¦   «         ¦  «         |S )al  Pull values that must bust the cached agent.

        Returns a flat dict keyed by 'section.key'.  Missing config keys and
        non-dict sections yield None values, which still contribute to the
        signature (so 'absent' vs 'present-and-null' differ).

        The live tool registry generation is included too.  MCP reloads and
        dynamic MCP tool-list changes mutate the registry without necessarily
        changing config.yaml.  Cached AIAgent instances freeze their tool
        schemas at construction time, so a registry generation change must
        rebuild the agent before the next turn.
        rŠ  rÓ  Nr
  r   )ÚregistryÚ_generationztools.registry_generationr¶  r  Úhoncho)rt   ru   r«  rv   rº   Útools.registryrÅ  rV   r2   r!   rw   ry   rI  rÃ  r²  )	r±  rA  r°
  rœ  Úsectionr  Úsection_valrÅ  r  s	            r>   rš  z+GatewayRunner._extract_cache_busting_configuZ  s½  € ð !ˆÝ'¨µTÑ:Ô:ÐBˆkˆkÀˆØÔ:ð 		/ð 		/‰LˆG�SØŸ'š' 'Ñ*Ô*ˆKØ˜-Ò'Ð'­J°{ÅDÑ,IÔ,IÐ'ð :=À	Ò9IÐ9I¨+¨+Èt��wÐ&Ð& Ð&Ð&Ñ'Ð'Ý˜K­Ñ.Ô.ð /Ø*5¯/ª/¸#Ñ*>Ô*>��wÐ&Ð& Ð&Ð&Ñ'Ð'à*.��wÐ&Ð& Ð&Ð&Ñ'Ð'ð	4Ø/Ð/Ð/Ð/Ð/Ð/å/6°xÀÐPTÑ/UÔ/UˆCÐ+Ñ,Ð,øÝð 	4ð 	4ð 	4Ø/3ˆCÐ+Ñ,Ð,Ð,ð	4øøøõ
 ˜3 ¨*Ñ5Ô5ˆÝ�h¥Ñ$Ô$ð 	A¨¯ªÑ)9Ô)9¸XÒ)EÐ)EØ�JŠJ�s×?Ò?ÑAÔAÑBÔBÐBÐBà�JŠJ�s×=Ò=Ñ?Ô?Ñ@Ô@Ð@àˆ
s   Â*C ÃCÃCr¿  r  Úephemeral_promptr
  r	  r  c                 ó  — ddl }ddl}	t          |                     dd¦  «        pd¦  «        }
|
r9|                     |
                     ¦   «         ¦  «                             ¦   «         nd}t          |pi                      ¦   «         ¦  «        }|	 	                    | ||                     dd¦  «        |                     dd¦  «        |                     dd¦  «        |                     dd¦  «        |rt          |¦  «        ng |pd|t          |pd¦  «        t          |pd¦  «        t          |¦  «        gd	t          ¬
¦  «        }|                     |                     ¦   «         ¦  «                             ¦   «         dd…         S )u:  Compute a stable string key from agent config values.

        When this signature changes between messages, the cached AIAgent is
        discarded and rebuilt.  When it stays the same, the cached agent is
        reused â€” preserving the frozen system prompt and tool schemas for
        prompt cache hits.

        ``cache_keys`` is an optional flat dict of additional config values
        that should invalidate the cache when they change.  Callers pass
        the output of ``_extract_cache_busting_config(user_config)`` so
        edits to model.context_length / compression.* in config.yaml are
        picked up on the next gateway message without a manual restart.

        ``user_id`` and ``user_id_alt`` are the runtime user identities
        carried by the current message's gateway source.  They participate
        in the cache key because the Honcho memory provider freezes them
        into ``HonchoSessionManager`` at first-message init (see
        ``plugins/memory/honcho/__init__.py::_do_session_init``).  Without
        them in the signature, a shared-thread session_key (one in which
        ``build_session_key`` intentionally omits the participant ID,
        e.g. ``thread_sessions_per_user=False``) would reuse the cached
        AIAgent across distinct users, causing the second user's messages
        to be attributed to the first user's resolved Honcho peer.  This
        broke #27371's per-user-peer contract in multi-user gateways.
        Per-user agent rebuilds in shared threads trade prompt-cache
        warmth for correct memory attribution.
        r   NrÅ  r®   r  r  r¶  r·  T)Ú	sort_keysrJ  rä  )rå  r3  rw   rv   ræ  rç  rè  r  rñ  rB  rº   )r  r¿  r  rË  r
  r¹  r	  r  rå  Ú_jÚ_api_keyÚ_api_key_fingerprintÚ_cache_keys_sortedÚblobs                 r>   r™  z%GatewayRunner._agent_config_signature Z  s‚  € ðL 	#Ð"Ð"Ð"Ð"Ð"Ð"Ð"õ �w—{’{ 9¨bÑ1Ô1Ð7°RÑ8Ô8ˆØPXÐ`˜wŸ~š~¨h¯oªoÑ.?Ô.?Ñ@Ô@×JÒJÑLÔLÐLÐ^`Ðå# ZÐ%5°2×$<Ò$<Ñ$>Ô$>Ñ?Ô?Ðà�xŠxàØ$Ø—’˜J¨Ñ+Ô+Ø—’˜J¨Ñ+Ô+Ø—’Ð0°"Ñ5Ô5Ø—’˜J¨Ñ+Ô+Ø,<ÐD•Ð'Ñ(Ô(Ð(À"ð !Ð& BØ"Ý�G�M˜rÑ"Ô"Ý�KÐ% 2Ñ&Ô&õ Ð'Ñ(Ô(ð#ð& Ýð+ ñ 
ô 
ˆð. �~Š~˜dŸkšk™mœmÑ,Ô,×6Ò6Ñ8Ô8¸¸"¸Ô=Ð=rM   c                 ó¾  — |                       |¦  «        }|�|j        j        �dS t          | dd¦  «        }|€dS 	 |                     |¦  «        }n-# t
          $ r  t                               dd¬¦  «         Y dS w xY w|sdS |                     d¦  «        |                     d¦  «        |                     d¦  «        d	œ}|                     d¦  «        }|r³	 t          |¦  «        }|                     d
¦  «        |d
<   |                     d¦  «        |d<   |                     d¦  «        |d<   |                     d¦  «        s|                     d¦  «        |d<   n-# t
          $ r  t                               d|d¬¦  «         Y nw xY w||  
                    |¦  «        j        _        t                               d||                     d¦  «        |pd¦  «         dS )u÷  Lazily restore a persisted /model override after a gateway restart.

        ``_session_model_overrides`` is in-memory only, so before persistence
        a restart silently reverted every session to the global default model.
        The non-secret parts (model/provider/base_url) are written through to
        the session store when /model runs (and cleared on /new); here we read
        them back on first use and re-resolve credentials via the normal
        runtime provider resolution â€” api_key is never persisted to disk.

        No-op when an in-memory override already exists (live state wins) or
        when the store has nothing persisted (e.g. the user ran /new, which
        clears both the in-memory dict and the persisted field).
        Nr›  z/Failed to read persisted session model overrideTrß   r  r  r  )r  r  r  rÅ  r·  r¹  zdCredential re-resolution failed for persisted override (provider=%s); using credential-less overridezIRehydrated persisted /model override for session=%s: model=%s provider=%sr®   )rA   rm  rn  rV   Úget_model_overrider2   r3   r4   rv   rÈ  r/   rz  )r  r+   Ú_rehydrate_stater�  r¾  r|  r  r¿  s           r>   rr  z/GatewayRunner._rehydrate_session_model_overrideêZ  s/  € ð  ×3Ò3°KÑ@Ô@ÐàÐ(Ø Ô-Ô<ÐHàˆFÝ˜˜o¨tÑ4Ô4ˆØˆ=ØˆFð	Ø×0Ò0°Ñ=Ô=ˆIˆIøÝð 	ð 	ð 	Ý�LŠLØAÈDð ñ ô ð ð ˆFˆFð		øøøð
 ð 	ØˆFà—]’] 7Ñ+Ô+Ø!Ÿš jÑ1Ô1Ø!Ÿš jÑ1Ô1ð$
ð $
ˆð
 —=’= Ñ,Ô,ˆØð 	ð
ÝDÀXÑNÔN�Ø&-§k¢k°)Ñ&<Ô&<�˜Ñ#Ø'.§{¢{°:Ñ'>Ô'>�˜Ñ$Ø.5¯kªkÐ:KÑ.LÔ.L�Ð*Ñ+Ø—|’| JÑ/Ô/ð CØ+2¯;ª;°zÑ+BÔ+B�H˜ZÑ(øøÝð ð ð Ý—’ðDà tð ñ ô ð ð ð ðøøøð HPˆ×Ò˜KÑ(Ô(Ô5ÔDÝ�ŠØWØ˜Ÿš gÑ.Ô.°°¸Bñ	
ô 	
ð 	
ð 	
ð 	
s$   ¼A Á&A<Á;A<ÃBE Å'F	ÆF	c                 ó–  — |                       |¦  «        }|r|j        j        nd}|s||fS |                     d|¦  «        }dD ]}|                     |¦  «        }|�|||<   Œ|                     d¦  «        rO|                     d¦  «        €:|                     d¦  «        r%t	          |                     d¦  «        ¦  «        |d<   ||fS )a±  Apply /model session overrides if present, returning (model, runtime_kwargs).

        The gateway /model command stores per-session overrides in
        ``_session_model_overrides``.  These must take precedence over
        config.yaml defaults so the switched model is actually used for
        subsequent messages.  Fields with ``None`` values are skipped so
        partial overrides don't clobber valid config defaults.
        Nr  )r  rÅ  r  r·  r¹  rÅ  r¹  r  )rA   rm  rn  rv   rÊ  )r  r+   r  rÔ  Ú_apply_stater|  r  rê  s           r>   rs  z+GatewayRunner._apply_session_model_override([  sö   € ð ×/Ò/°Ñ<Ô<ˆØ?KÐU�<Ô,Ô;Ð;ÐQUˆØð 	)Ø˜.Ð(Ð(Ø—’˜W eÑ,Ô,ˆØUð 	*ð 	*ˆCØ—,’,˜sÑ#Ô#ˆCØˆØ&)�˜sÑ#øà×Ò˜yÑ)Ô)ð	à×"Ò"Ð#4Ñ5Ô5Ð=Ø—’˜ZÑ(Ô(ð >õ 1NØ—’˜ZÑ(Ô(ñ1ô 1ˆNÐ,Ñ-ð �nÐ$Ð$rM   c                 ó|   — |                       |¦  «        }|r|j        j        nd}|du|�t          |¦  «        nddœS )z<Capture a gateway session override before a one-turn switch.N)Úhad_overrider|  )rA   rm  rn  ru   )r  r+   Ú_snap_stater|  s       r>   Ú _snapshot_session_model_overridez.GatewayRunner._snapshot_session_model_overrideF[  sS   € à×.Ò.¨{Ñ;Ô;ˆØ>IÐS�;Ô+Ô:Ð:Ètˆà$¨DÐ0Ø*2Ð*>�˜X™œ˜ÀDð
ð 
ð 	
rM   r*
  c                 ó,  — |sdS |                      d¦  «        rBt          |                      d¦  «        pi ¦  «        |                      |¦  «        j        _        n#|                      |¦  «        }|�d|j        _        |                      |¦  «         dS )z?Restore the session override captured before a one-turn switch.NrÙ  r|  )rv   ru   r/   rm  rn  rA   rû  )r  r+   r*
  Ú
_rst_states       r>   rš  z-GatewayRunner._restore_session_model_overrideO[  sŸ   € àð 	ØˆFØ�<Š<˜Ñ'Ô'ð 	>ÝKOØ—’˜ZÑ(Ô(Ð.¨BñLô LˆD×Ò Ñ,Ô,Ô9ÔHÐHð ×1Ò1°+Ñ>Ô>ˆJØÐ%Ø9=�
Ô'Ô6Ø× Ò  Ñ-Ô-Ð-Ð-Ð-rM   Úagent_modelc                 ó†   — |                       |¦  «        }|r|j        j        nd}|duo|                     d¦  «        |k    S )zGReturn True if *agent_model* matches an active /model session override.Nr  )rA   rm  rn  rv   )r  r+   rÞ  Ú
_ims_stater|  s        r>   Ú_is_intentional_model_switchz*GatewayRunner._is_intentional_model_switch][  sK   € à×-Ò-¨kÑ:Ô:ˆ
Ø=GÐQ�:Ô*Ô9Ð9ÈTˆØ˜tÐ#ÐL¨¯ª°WÑ(=Ô(=ÀÒ(LÐLrM   ©r¼  c                ój  — |sdS |�|                       ||¦  «        sdS |                      |¦  «        }|�i|j        j        }|�B	 |                     ¦   «          n,# t
          $ r t                               dd¬¦  «         Y nw xY w|j                             ¦   «          |  	                    ¦   «          dS )uÙ  Pop ALL per-running-agent state entries for ``session_key``.

        Replaces ad-hoc ``del self._running_agents[key]`` calls scattered
        across the gateway.  Those sites had drifted: some popped only
        ``_running_agents``; some also ``_running_agents_ts``; only one
        path also cleared ``_busy_ack_ts``.  Each missed entry was a
        small, persistent leak â€” a (str_key â†’ float) tuple per session
        per gateway lifetime.

        Use this at every site that ends a running turn, regardless of
        cause (normal completion, /stop, /reset, /resume, sentinel
        cleanup, stale-eviction).  Per-session state that PERSISTS
        across turns (``_session_model_overrides``, ``_voice_mode``,
        ``_pending_approvals``, ``_update_prompt_pending``) is NOT
        touched here â€” those have their own lifecycles.

        When ``run_generation`` is provided, only clear the slot if that
        generation is still current for the session.  This prevents an
        older async run whose generation was bumped by /stop or /new from
        clobbering a newer run's state during its own unwind.  Returns
        True when the slot was cleared, False when an ownership guard
        blocked it.
        FNz%Failed to release active session slotTrß   )
r”  rA   rJ  r   Úreleaser2   r3   r4   r4  r=	  )r  r+   r¼  r;   r   s        r>   rÌ
  z*GatewayRunner._release_running_agent_statec[  sé   € ð: ð 	Ø�5ØÐ%¨d×.JÒ.JØ˜ñ/
ô /
Ð%ð �5Ø×(Ò(¨Ñ5Ô5ˆØÐØ”JÔ$ˆEØÐ ðØ—M’M‘O”O�O�OøÝ ð ð ð Ý—L’LØ?È$ð !ñ ô ð ð ð ðøøøð ŒJ×ÒÑÔÐð
 	×#Ò#Ñ%Ô%Ð%Øˆts   ÁA Á&BÂBc                 óH  — |sdS t          | dd¦  «        }|                      |¦  «        }|�|€dS |j        }|j        �|j        |k    rdS |j        }d|_        d|_        	 |                     |¦  «        S # t          $ r  t                               dd¬¦  «         Y dS w xY w)uI  Release the turn lease acquired by (``session_key``, ``run_generation``).

        Companion to the acquisition in ``_handle_message_with_agent``
        (#64934). The token map is keyed by (routing key, run generation), so
        this can only ever free the lease its own turn acquired â€” a stale
        unwind whose generation was bumped by /stop or /new pops ITS token,
        and the registry's identity check refuses it if a newer turn already
        holds the lease. Idempotent and safe for bare test runners built via
        ``object.__new__`` (getattr defaults).
        Frž  NzFailed to release turn leaseTrß   )	rV   rA   rJ  r}  r~  rä  r2   r3   r4   )r  r+   r¼  rÅ  r;   rJ  rÄ  s          r>   r&  z!GatewayRunner._release_turn_leaseœ[  sÐ   € ð ð 	Ø�5Ý˜4 °Ñ6Ô6ˆØ×(Ò(¨Ñ5Ô5ˆØˆ=˜HÐ,Ø�5ØŒzˆØÔÐ# tÔ'<ÀÒ'NÐ'NØ�5ØÔ ˆØˆÔØ $ˆÔð	Ø×#Ò# EÑ*Ô*Ð*øÝð 	ð 	ð 	Ý�LŠLÐ7À$ˆLÑGÔGÐGØ�5�5ð	øøøs   Á"A7 Á7&B!Â B!Únew_session_idc                 ó.  — |r|sdS t          | dd¦  «        }|                      |¦  «        }|�|€dS |j        }|j        �|j        |k    rdS 	 |                     |j        |¦  «        S # t          $ r  t                               dd¬¦  «         Y dS w xY w)u�  Follow a mid-turn session_id rotation with the held turn lease.

        Compression (session-hygiene pre-compression or the agent's own
        compressor) can rotate ``session_entry.session_id`` while this turn
        is in flight. The turn's flush targets the NEW id, so the
        serialization boundary must follow it â€” otherwise an alias routing
        key resolving the new id (topic tip-walk onto the fresh child) could
        start a concurrent turn the lease never sees (#64934 rotation-alias
        window). Call at every site that reassigns session_entry.session_id
        mid-turn. Fail-open no-op when there is no held token.
        Frž  NzFailed to rebind turn leaseTrß   )	rV   rA   rJ  r}  r~  Úrebindr2   r3   r4   )r  r+   r¼  ræ  rÅ  r;   rJ  s          r>   r�  z GatewayRunner._rebind_turn_lease¹[  sÂ   € ð ð 	 .ð 	Ø�5Ý˜4 °Ñ6Ô6ˆØ×(Ò(¨Ñ5Ô5ˆØˆ=˜HÐ,Ø�5ØŒzˆØÔÐ# tÔ'<ÀÒ'NÐ'NØ�5ð	Ø—?’? 4Ô#3°^ÑDÔDÐDøÝð 	ð 	ð 	Ý�LŠLÐ6ÀˆLÑFÔFÐFØ�5�5ð	øøøs   ÁA* Á*&BÂBc                ó\  — |sdS |                       |¦  «        }|�|j                             ¦   «          t          D ]>}t	          | |d¦  «        }t          |t          ¦  «        r|                     |d¦  «         Œ?|                      |¦  «         t           
                    d||¦  «         dS )u‘  Clear ALL conversation-scoped per-session state for ``session_key``.

        THE single conversation-boundary funnel. Call this â€” and nothing
        else â€” whenever a session_key crosses a conversation boundary:
        /new, /resume, auto-reset (idle/daily/suspended), expiry
        finalization, and the compression-exhausted auto-reset.

        Why a funnel: these boundaries used to each carry a hand-copied
        pop-list of the per-session dicts, and the lists drifted every time
        a new dict was added (#48031, #58403, #10702, #35809 were all
        "boundary X forgot dict Y" bugs â€” e.g. /new cleared the /model
        override but not the /model --once restore snapshot). Adding a new
        conversation-scoped dict now means adding its attribute name to
        _CONVERSATION_SCOPED_STATE below; every boundary picks it up
        automatically.

        Scope rules:
        - Conversation-scoped (cleared here): model/reasoning overrides,
          one-turn restore snapshots, pending model notes, last-resolved
          model cache, queued follow-up events, and the boundary security
          state (approvals, /yolo, slash-confirm, update prompts).
        - Turn-scoped (NOT cleared here): _running_agents/_ts, slot leases,
          turn-lease tokens â€” owned by _release_running_agent_state and the
          dispatch finally.
        - Idle agent-cache eviction is NOT a conversation boundary: the
          session is still alive and a resumed turn rebuilds from these
          overrides. Only true boundaries call this.

        Safe on bare test runners built via ``object.__new__`` (every
        access is getattr-guarded).
        Nz&Cleared conversation scope for %s (%s))rA   rm  r4  r¬  rV   rt   ru   rU  Ú&_clear_session_boundary_security_stater3   r4   )r  r+   r•  r;   ré  r�  s         r>   r  z'GatewayRunner._clear_conversation_scopeÖ[  sÆ   € ð@ ð 	ØˆFð ×(Ò(¨Ñ5Ô5ˆØÐØÔ×$Ò$Ñ&Ô&Ð&õ /ð 	-ð 	-ˆDÝ˜D $¨Ñ-Ô-ˆEÝ˜%¥Ñ&Ô&ð -Ø—	’	˜+ tÑ,Ô,Ð,øØ×3Ò3°KÑ@Ô@Ð@Ý�ŠØ4°kÀ6ñ	
ô 	
ð 	
ð 	
ð 	
rM   c                 ób  — |sdS t          | dd¦  «        }t          |t          ¦  «        r|                     |d¦  «         |                      |¦  «        }|�d|j        _        d|j        _        	 ddlm	} n# t          $ r d}Y nw xY w|�J	 |                     |¦  «         n3# t          $ r&}t                               d||¦  «         Y d}~nd}~ww xY w	 ddlm} n# t          $ r Y dS w xY w	  ||¦  «         dS # t          $ r'}t                               d||¦  «         Y d}~dS d}~ww xY w)	zHClear per-session control state that must not survive a boundary switch.Nrn  Fr   r™  z?Failed to clear slash-confirm state for session boundary %s: %srw  z:Failed to clear approval state for session boundary %s: %s)rV   rt   ru   rU  rA   r0   re  rê  r»  rš  r2   r4  r3   r4   rÃ  rR  )r  r+   Úpending_skills_reload_notesÚ
_sec_staterI  r¨  Ú_clear_approval_sessions          r>   rê  z4GatewayRunner._clear_session_boundary_security_state\  sï  € àð 	ØˆFå&-ØÐ0°$ñ'
ô '
Ð#õ Ð1µ4Ñ8Ô8ð 	?Ø'×+Ò+¨K¸Ñ>Ô>Ð>à×-Ò-¨kÑ:Ô:ˆ
ØÐ!Ø.2ˆJÔ!Ô+Ø:?ˆJÔ!Ô7ð	&ØAÐAÐAÐAÐAÐAÐAøÝð 	&ð 	&ð 	&Ø!%ÐÐÐð	&øøøàÐ)ðØ"×(Ò(¨Ñ5Ô5Ð5Ð5øÝð ð ð Ý—’ØUØØñô ð ð ð ð ð ð øøøøðøøøð	ØOÐOÐOÐOÐOÐOÐOøÝð 	ð 	ð 	ØˆFˆFð	øøøð	Ø#Ð# KÑ0Ô0Ð0Ð0Ð0øÝð 	ð 	ð 	Ý�LŠLØLØØñô ð ð ð ð ð ð ð øøøøð	øøøsT   Á1A8 Á8BÂBÂB# Â#
CÂ-CÃCÃC Ã
C,Ã+C,Ã0C= Ã=
D.ÄD)Ä)D.c                 ó„   — |sdS |                       |¦  «        j        }t          |j        ¦  «        dz   |_        |j        S )ae  Claim a fresh run generation token for ``session_key``.

        Every top-level gateway turn gets a monotonically increasing token.
        If a later command like /stop or /new invalidates that token while the
        old worker is still unwinding, the late result can be recognized and
        dropped instead of bleeding into the fresh session.
        r   r(   )r/   r0   rh  r¼  )r  r+   r0   s      r>   r!  z+GatewayRunner._begin_session_run_generation7\  sH   € ð ð 	Ø�1Ø×(Ò(¨Ñ5Ô5Ô@ˆ
å$'¨
Ô(AÑ$BÔ$BÀQÑ$Fˆ
Ô!ØÔ(Ð(rM   c                ón   — |                       |¦  «        }|rt                               d|||¦  «         |S )z7Invalidate any in-flight run token for ``session_key``.u-   Invalidated run generation for %s â†’ %d (%s))r!  r3   rz  )r  r+   r•  r?  s       r>   rò  z0GatewayRunner._invalidate_session_run_generationF\  sG   € à×7Ò7¸ÑDÔDˆ
Øð 	Ý�KŠKØ?ØØØñ	ô ð ð ÐrM   r?  c                 ó”   — |sdS |                       |¦  «        }|�|j        j        nd}t          |¦  «        t          |¦  «        k    S )zEReturn True when ``generation`` is still current for ``session_key``.TNr   )rA   r0   r¼  rh  )r  r+   r?  r;   r‘  s        r>   r”  z%GatewayRunner._is_session_run_currentR\  sN   € àð 	Ø�4Ø×(Ò(¨Ñ5Ô5ˆØ5:Ð5F�%Ô"Ô1Ð1ÈAˆÝ�7‰|Œ|�s :™œÒ.Ð.rM   c                 óÆ   — |r|r|€dS 	 t          |di ¦  «                             |¦  «        }|� t          |dt          |¦  «        ¦  «         dS dS # t          $ r Y dS w xY w)zDBind a gateway run generation to the adapter's active-session event.Nr˜  r™  )rV   rv   rÔ
  rh  r2   )r  r1  r+   r?  Úinterrupt_events        r>   r’  z*GatewayRunner._bind_adapter_run_generationZ\  s‘   € ð ð 	˜kð 	¨ZÐ-?ØˆFð	Ý% gÐ/AÀ2ÑFÔF×JÒJÈ;ÑWÔWˆOØÐ*Ý˜Ð)AÅ3ÀzÁ?Ä?ÑSÔSÐSÐSÐSð +Ð*øåð 	ð 	ð 	ØˆDˆDð	øøøs   ŠAA Á
A ÁA )Úrelease_running_staterq  rr  rô  c          	   ƒ   óp  ‡ ‡‡K  — ‰sdS ‰                       ‰¦  «        }|r|j        j        nd}d}d}	|r;|t          ur2t	          ||¦  «         t          |dd¦  «        }t          |dd¦  «        }	‰                      ‰|¬¦  «        Š|rG|	�Et          j        t          ||	fdˆˆ ˆfd„dœd	|dd
…         › �d¬¦  «         
                    ¦   «          ‰                      |¦  «        }
t          t          |
¦  «        dd¦  «        }|
rÎt          |¦  «        r¿‰                      |¦  «        }	 t          j        |¦  «        j        }d|v p*t%          d„ |                     ¦   «         D ¦   «         ¦  «        }n# t(          t*          f$ r d}Y nw xY w|r$|
                     ‰|j        |¬¦  «        ƒ d{V —† n!|
                     ‰|j        ¦  «        ƒ d{V —† |
r%t1          |
d¦  «        r|
                     ‰¦  «         |�d|j        _        |r,‰                      ‰¦  «         ‰                      ‰¦  «         dS dS )zFInterrupt the current run and clear queued session state consistently.Nr®   rÀ  rÁ  r  Úgateway_turn_interruptc                  ó0   •— ‰                      ‰‰ ¦  «        S r^   ©r”  )Ú_generation_at_interruptr  r+   s   €€€r>   rò   z<GatewayRunner._interrupt_and_clear_session.<locals>.<lambda>’\  s   ø€ °×0LÒ0LØ#Ð%=ñ1ô 1€ rM   r7  úgateway-turn-reaper-rÌ   T)r  r¸  rF  rÖ   r  Úinterrupt_session_activityr¯   c              3   óF   K  — | ]}|j         t          j        j        u V — Œd S r^   rc  rh  s     r>   rd   z=GatewayRunner._interrupt_and_clear_session.<locals>.<genexpr>¡\  sC   è è € ð ?ð ?àð ”J¥'Ô"3Ô"?Ð?ð?ð ?ð ?ð ?ð ?ð ?rM   Fr.  r$  )rA   rJ  rµ   rž  r   rV   rò  r¤  r¥  r1  r§  r@  rÎ   r/  rî	  re  r“  r”  r
  r•  rw  rj  rû  r2  rá   r$  r0   Úpending_command_textrÌ
  rû  )r  r+   r(  rq  rr  rô  Ú
_iac_stater«	  Ú_process_task_idÚ_process_baseliner1  rû  r¯   ÚparamsÚaccepts_metadatarù  s   ``             @r>   rs  z*GatewayRunner._interrupt_and_clear_sessionj\  s2  øøøè è € ð ð 	ØˆFØ×-Ò-¨kÑ:Ô:ˆ
Ø1;ÐE˜
œÔ-Ð-ÀˆØÐØ ÐØð 	˜]Õ2IÐIÐIÝ" =Ð2BÑCÔCÐCÝ&ØÐ>Àñ ô  Ðõ !(ØÐ?Àñ!ô !Ðð $(×#JÒ#JØÐ 3ð $Kñ $
ô $
Ð ð ð 	Ð 1Ð =ÝÔÝ3Ø&Ð(9Ð:à6ð)ð )ð )ð )ð )ð )ðð ð DÐ,<¸S¸b¸SÔ,AÐCÐCØðñ ô ÷ Še‰gŒgˆgØ×*Ò*¨6Ñ2Ô2ˆÝ%,Ý�‰MŒMÐ7¸ñ&
ô &
Ð"ð ð 	V•xÐ :Ñ;Ô;ð 	VØ×7Ò7¸Ñ?Ô?ˆHð)Ý Ô*Ð+EÑFÔFÔQ�Ø#-°Ð#7ð $½3ð ?ð ?à!'§¢¡¤ð?ñ ?ô ?ñ <ô <Ð Ð øõ �zÐ*ð )ð )ð )Ø#(Ð Ð Ð ð)øøøàð VØ×8Ò8Ø ¤¸(ð 9ñ ô ð ð ð ð ð ð ð ð ð ×8Ò8¸ÀfÄnÑUÔUÐUÐUÐUÐUÐUÐUÐUØð 	5•w˜wÐ(=Ñ>Ô>ð 	5Ø×'Ò'¨Ñ4Ô4Ð4ØÐ!Ø9=ˆJÔ!Ô6Ø ð 	2Ø×-Ò-¨kÑ:Ô:Ð:ð ×$Ò$ [Ñ1Ô1Ð1Ð1Ð1ð	2ð 	2s   Ä*AE3 Å3F	ÆF	c              ƒ   ó¶  K  — | j         �|sdS t          | dd¦  «        }t          | dd¦  «        }|r|€dS 	 | j                              |¦  «        ƒ d{V —†}|r|                     dd¦  «        nd}n# t          $ r Y dS w xY w|€dS |5  |                     |¦  «        }t          |t          ¦  «        r�t          |¦  «        dk    rz|d         t          urkt          |¦  «        dk    r|d         nd}|�||k    r	 ddd¦  «         dS |d         |k    r,|€|d         |d         |f||<   n|d         |d         ||f||<   ddd¦  «         dS # 1 swxY w Y   dS )	u°  Re-baseline a cached agent's stored message_count after THIS turn.

        The cross-process coherence guard (#45966) compares the session's
        on-disk ``message_count`` against the count snapshotted next to the
        cached agent, and rebuilds the agent on a mismatch.  But the snapshot
        is taken at agent-BUILD time â€” before this turn writes its own user +
        assistant (+ tool) rows â€” and the cache entry is never rewritten on a
        reuse.  So without this re-baseline, THIS process's own turn would
        grow ``message_count`` and the very next turn would see a mismatch
        and rebuild the agent â€” every turn, for every conversation â€” silently
        destroying the per-conversation prompt caching the cache exists to
        protect.

        Call this once a turn has completed and the agent has flushed its
        rows to the SessionDB.  It snapshots the now-current count (which
        includes this process's own writes) so the guard only fires when a
        DIFFERENT process changes the transcript out from under us.  The
        ``_sig`` is left untouched; only the count element is refreshed, and
        only when the same agent is still cached (no rebuild/eviction raced
        in between).  Fail-safe: any DB error leaves the snapshot as-is, which
        at worst costs one unnecessary rebuild on the next turn.

        When the cache entry records a ``session_id`` (4-tuple form, #54947)
        that differs from the current ``session_id`` â€” meaning the cache
        was built for a DIFFERENT conversation under the same ``session_key``
        â€” the snapshot is intentionally left untouched.  Overwriting it with
        the current session's count would corrupt the original conversation's
        baseline and cause the next switch back to fire the cross-process
        guard spuriously.  Fail-safe: the legacy 3-tuple shape (no
        ``session_id``) is still re-baselined as before.
        Nr  r  r  r   r|  r)   r(   )	rR   rV   r�  rv   r2   rt   r€  r7   rž  )	r  r+   rN   rå  ræ  rë  Ú_liverí  Ú_snapshot_sids	            r>   r�  z0GatewayRunner._refresh_agent_cache_message_count¾\  s"  è è € ðD ÔÐ#¨:Ð#ØˆFÝ˜dÐ$7¸Ñ>Ô>ˆÝ˜˜~¨tÑ4Ô4ˆØð 	˜f˜nØˆFð	Ø"Ô.×:Ò:¸:ÑFÔFÐFÐFÐFÐFÐFÐFˆIØ9BÐL�I—M’M /°1Ñ5Ô5Ð5ÈˆEˆEøÝð 	ð 	ð 	ØˆFˆFð	øøøàˆ=ØˆFØð 	ð 	Ø—Z’Z Ñ,Ô,ˆFõ
 ˜6¥5Ñ)Ô)ðå˜‘K”K !’O�OØ˜1”IÕ%<Ð<Ð<õ .1°©[¬[¸1ª_¨_  q¤	 	À$�Ø Ð,°À*Ò1LÐ1LØð!	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð" ˜!”9 Ò%Ð%Ø$Ð,ð 06°a¬y¸&À¼)ÀUÐ.K˜˜{Ñ+Ð+ð # 1œI v¨a¤y°%¸ð/˜˜{Ñ+ð1	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s*   ·:A2 Á2
B Á?B Â	A3EÄ	8EÅEÅErI  c                 ój   — |r|sdS t          |¦  «        |                      |¦  «        j        _        dS )zDStage per-turn must-deliver notes for the next agent run (one-shot).N)r½  r/   rm  Úsidecar_notes)r  r+   rI  s      r>   r‘  z-GatewayRunner._set_pending_turn_sidecar_notes	]  s;   € àð 	 %ð 	ØˆFÝFJÈ5ÁkÄkˆ×Ò˜KÑ(Ô(Ô5ÔCÐCÐCrM   c                 ó¸   — |sg S |                       |¦  «        }|€g S |j        j        }g |j        _        t          |t          ¦  «        rt	          |¦  «        ng S r^   )rA   rm  r  rt   r½  )r  r+   r;   Ústageds       r>   r·  z1GatewayRunner._consume_pending_turn_sidecar_notes]  sa   € Øð 	ØˆIØ×(Ò(¨Ñ5Ô5ˆØˆ=ØˆIØÔ#Ô1ˆØ+-ˆÔÔ(Ý)¨&µ$Ñ7Ô7Ð?�t�F‰|Œ|ˆ|¸RÐ?rM   c                 óè  — |j         t          j        k    rdS | j                             t          j        ¦  «        }|                      |¦  «        }|r|rt          |d¦  «        sdS 	 |                     |¦  «        pd}n-# t          $ r  t           
                    dd¬¦  «         Y dS w xY wd}|r-|                      |¦  «        }|j        j        }||j        _        ||�|ndk    rdS |sdS d|› d	�S )
ay  Return a ``[Voice channel now: ...]`` note when VC state changed.

        Compares the live Discord voice-channel context against the last
        value delivered for this session and returns a note only on change
        (including leaving the channel).  Unchanged state returns ``None`` so
        the per-turn member/speaking serialization cannot churn the prompt.
        NÚget_voice_channel_contextr®   z!voice-channel context read failedTrß   z5[Voice channel now: not connected to a voice channel]z[Voice channel now: rš  )r�   rÄ  r±  r°  rv   r¨  rá   r  r2   r3   r4   r/   rm  Úvc_last)	r  rÖ  r(  r+   r1  r¦  Úvc_nowÚvc_prevÚ	_vc_states	            r>   r�  z)GatewayRunner._voice_channel_sidecar_note]  s3  € ð Œ?�hÔ.Ò.Ð.Ø�4Ø”-×#Ò#¥HÔ$4Ñ5Ô5ˆØ×%Ò% eÑ,Ô,ˆØð 	˜Wð 	­°Ð:UÑ)VÔ)Vð 	Ø�4ð	Ø×6Ò6°xÑ@Ô@ÐFÀBˆFˆFøÝð 	ð 	ð 	Ý�LŠLÐ<ÀtˆLÑLÔLÐLØ�4�4ð	øøøð ˆØð 	4Ø×+Ò+¨KÑ8Ô8ˆIØÔ,Ô4ˆGØ-3ˆIÔ"Ô*Ø Ð!4�g�g¸"Ò=Ð=Ø�4Øð 	KØJÐJØ/ fÐ/Ð/Ð/Ð/s   Á(B  Â &B*Â)B*r!  c                 ó  — |                       ||¦  «        }d}|r%|                      |¦  «        }|r|j        j        nd}|�|d         |k    r|d         S t	          ||¬¦  «        }|r!||f|                      |¦  «        j        _        |S )uk  Return the session-context prompt, pinned per session.

        Key hit â†’ the pinned bytes are reused VERBATIM (immunizes the
        composed system prompt against renderer nondeterminism); key miss â†’
        re-render ``build_session_context_prompt`` and re-pin (a legitimate
        cache bust: rename, topic edit, /sethome, redact_pii flip, ...).
        Nr   r(   )r!  )Ú_ephemeral_change_keyrA   rm  Úephemeral_pinr^  r/   )r  rÙ   r!  r+   Ú_eph_keyÚ_eph_pinÚ
_pin_staterè   s           r>   rt  z,GatewayRunner._pinned_session_context_prompt7]  s±   € ð ×-Ò-¨g°zÑBÔBˆØˆØð 	UØ×1Ò1°+Ñ>Ô>ˆJØ@JÐT�zÔ.Ô<Ð<ÐPTˆHØÐ H¨Q¤K°8Ò$;Ð$;Ø˜A”;ÐÝ+¨GÀ
ÐKÑKÔKˆØð 	àØðKˆD×Ò Ñ,Ô,Ô9ÔGð ˆrM   c                 óî  — ddl }| j        }|j        r|j        j        nd}d}d}|j        t          j        k    rtddlm}  |¦   «         rdnd}t          |j	        pd¦  «        t          |j
        pd¦  «        t          |j        pd¦  «        t          |j        pd¦  «        |j        rdndf}d}|j        t          j        k    rddlm}	  |	¦   «         rdnd}	 dd	lm}
 t           |
¦   «         ¦  «        }n# t$          $ r d}Y nw xY w|t          |j        pd¦  «        t          |j        pd¦  «        t          |j        pd¦  «        t          |j        pd¦  «        t          |j        pd¦  «        t          |j        pd¦  «        t          |j        pd¦  «        t          t1          |d
d¦  «        pd¦  «        t3          | j        ¦  «        |||t7          d„ | j        D ¦   «         ¦  «        t7          d„ | j                             ¦   «         D ¦   «         ¦  «        t3          |¦  «        |f}|                     tA          |¦  «         !                    d¦  «        ¦  «         "                    ¦   «         S )u  Hash the exact inputs ``build_session_context_prompt`` renders.

        This key decides when the pinned per-session context-prompt bytes are
        reused verbatim vs re-rendered.  The maintained invariant (guarded by
        the parity test in tests/gateway/test_prompt_tail_freeze.py): any
        input whose change alters the rendered bytes MUST appear here â€”
        omission means a stale pinned prompt (cosmetic staleness); inclusion
        of an extra field only costs a spurious re-render.
        r   Nr®   rN  r±  ro   r5  )Ú_slack_tools_loaded)Údisplay_hermes_homer  c              3   ó$   K  — | ]}|j         V — Œd S r^   rç  r:  s     r>   rd   z6GatewayRunner._ephemeral_change_key.<locals>.<genexpr>‘]  s$   è è € Ð?Ð?˜a�!”'Ð?Ð?Ð?Ð?Ð?Ð?rM   c           
   3   ó¨   K  — | ]M\  }}|j         t          t          |d d¦  «        pd¦  «        t          t          |dd¦  «        pd¦  «        fV — ŒNdS )rÖ   r®   r2  N)r­   rw   rV   )rb   r;  Úhcs      r>   rd   z6GatewayRunner._ephemeral_change_key.<locals>.<genexpr>’]  s{   è è € ð ð ñ �A�rð	 ”GÝ�  F¨BÑ/Ô/Ð5°2Ñ6Ô6Ý�  I¨rÑ2Ô2Ð8°bÑ9Ô9ððð ð ð ð ð rM   rQ  )#rå  r(  r�   r­   rÄ  r±  rr  r²  rw   r¦  ré  r›  r2  rj  rÅ  r  r¶  r  r2   r´  r*  Ú
chat_topicr)  r¹  rV   rº   Úshared_multi_user_sessionr€  Úconnected_platformsÚhome_channelsrñ  ræ  râ   rç  rè  )rÙ   r!  rå  Úsrcr�   Údiscord_idsÚdiscord_toolsr²  Úslack_toolsr  r  Úhome_displayÚ	key_tuples                r>   r  z#GatewayRunner._ephemeral_change_keyP]  s¸  € ð 	ˆˆˆàŒnˆØ),¬Ð=�3”<Ô%Ð%¸2ˆàˆØˆØŒ<�8Ô+Ò+Ð+Ø=Ð=Ð=Ð=Ð=Ð=à#8Ð#8Ñ#:Ô#:ÐC˜C˜CÀˆMå�C”LÐ& BÑ'Ô'Ý�CÔ&Ð,¨"Ñ-Ô-Ý�C”MÐ' RÑ(Ô(Ý�C”KÐ% 2Ñ&Ô&ð ”~Ð.��¨3ð	ˆKð  ˆØŒ<�8œ>Ò)Ð)Ø;Ð;Ð;Ð;Ð;Ð;à!4Ð!4Ñ!6Ô!6Ð?˜#˜#¸CˆKð	Ø<Ð<Ð<Ð<Ð<Ð<åÐ2Ð2Ñ4Ô4Ñ5Ô5ˆLˆLøÝð 	ð 	ð 	ØˆLˆLˆLð	øøøð Ý�”Ð!˜rÑ"Ô"Ý�”Ð# Ñ$Ô$Ý�”Ð# Ñ$Ô$Ý�”Ð# Ñ$Ô$Ý�”Ð$ "Ñ%Ô%Ý�”Ð# Ñ$Ô$Ý�”Ð!˜rÑ"Ô"Ý•˜˜Y¨Ñ-Ô-Ð3°Ñ4Ô4Ý�Ô2Ñ3Ô3ØØØÝÐ?Ð? 7Ô#>Ð?Ñ?Ô?Ñ?Ô?Ýð ð ð %Ô2×8Ò8Ñ:Ô:ðñ ô ñ ô õ �ÑÔØð1
ˆ	ð4 �~Š~�d 9™oœo×4Ò4°WÑ=Ô=Ñ>Ô>×HÒHÑJÔJÐJs   ÃC8 Ã8DÄDc           	      ó  — |                       |¦  «        }|�d|j        _        d|j        _        t	          | dd¦  «        }d}|r6|5  | j                             |d¦  «        }ddd¦  «         n# 1 swxY w Y   n)t	          | dd¦  «        }|�|                     |d¦  «        }t          |t          ¦  «        r
|r|d         n|}|�	|t          u rdS d„ |  
                    ¦   «         D ¦   «         }t          |¦  «        |v rdS 	 t          j        | j        |fddt          |¦  «        dd…         › �¬	¦  «                             ¦   «          dS # t"          $ r, 	 |                      |¦  «         Y dS # t"          $ r Y Y dS w xY ww xY w)
u  Remove a cached agent for a session (called on /new, /model, etc).

        Pops the entry AND soft-releases the evicted agent's LLM client
        pool so the httpx connection (sockets + held buffers) is freed
        promptly rather than waiting on CPython GC â€” AIAgent holds
        reference cycles (callbacks, tool state) that delay refcount
        collection, so a manual release is required to keep gateway RSS
        flat across many /new, /model, undo and reset operations (#29298,
        same leak class as #25315).

        The release is soft (``release_clients()``): it frees the client
        pool and per-turn child subagents but PRESERVES the session's
        terminal sandbox, browser daemon, and tracked bg processes (keyed
        on task_id), because the session may resume with a freshly-built
        agent.  Call sites that want a hard teardown (true conversation
        boundaries like /new) already call ``_cleanup_agent_resources``
        before evicting; ``release_clients`` is idempotent and safe to
        run again after that (the client is already None).

        Cleanup runs on a daemon thread so we never block holding
        ``_agent_cache_lock`` on slow socket teardown â€” mirrors the
        cap-enforcer and idle-sweeper paths.
        Nr  r  r   c                 óH   — h | ]\  }}|®|t           u¯t          |¦  «        ’Œ S r^   ©rž  rÍ   ©rb   rK  r  s      r>   rQ  z4GatewayRunner._evict_cached_agent.<locals>.<setcomp>Ï]  ó<   € ð 
ð 
ð 
á��1Øˆ} Õ*AÐ!AÐ!Aõ ˆq‰EŒEà!AÐ!AÐ!ArM   Tzagent-evict-r  r  )rA   rm  r  r  rV   r  rU  rt   r€  rž  rO  rÍ   r¤  r¥  r¦  rw   r§  r2   )r  r+   Ú_evict_staterº	  rò  ræ  rµ   Úrunning_idss           r>   rû  z!GatewayRunner._evict_cached_agentŸ]  s1  € ð6 ×/Ò/°Ñ<Ô<ˆØÐ#Ø6:ˆLÔ%Ô3Ø04ˆLÔ%Ô-å˜Ð1°4Ñ8Ô8ˆØˆØð 	8Øð Cð CØÔ+×/Ò/°¸TÑBÔB�ðCð Cð Cñ Cô Cð Cð Cð Cð Cð Cð Cøøøð Cð Cð Cð Cøõ ˜T >°4Ñ8Ô8ˆFØÐ!Ø Ÿ*š* [°$Ñ7Ô7�å(¨µ%Ñ8Ô8ÐQ¸WÐQ�˜”
�
È'ˆØˆ=˜EÕ%<Ð<Ð<ØˆFð
ð 
à×1Ò1Ñ3Ô3ð
ñ 
ô 
ˆõ
 ˆe‰9Œ9˜Ð#Ð#ØˆFð	ÝÔØÔ7Ø�XØØ;¥C¨Ñ$4Ô$4°S°b°SÔ$9Ð;Ð;ð	ñ ô ÷
 Še‰gŒgˆgˆgˆgøÝð 	ð 	ð 	ðØ×0Ò0°Ñ7Ô7Ð7Ð7Ð7Ð7øÝð ð ð Ø���ðøøøð	øøøs=   ÁA/Á/A3Á6A3ÄAE Å
FÅE1Å1
F Å;FÅ?F Æ FÚinterrupt_depthc                 ó°   — |dk    rHddl m} t          j        ¦   «         | _        d| _        |j        | _        t          | d¦  «        rd| _        d| _	        dS )aø  Reset per-turn state on a cached agent before a new turn starts.

        ``_last_activity_ts``, ``_last_activity_desc``, and
        ``_last_activity_provenance`` are only reset for fresh external
        turns (depth 0); they are a semantic triple - description and
        provenance describe the activity *at* ts, so updating one without
        the others would make get_activity_summary() misleading.
        For interrupt-recursive turns all three are preserved so the
        inactivity watchdog can accumulate stuck-turn idle time and fire
        the 30-min timeout (#15654).  The depth-0 reset is still needed:
        a session idle for 29 min would otherwise trip the watchdog before
        the new turn makes its first API call (#9051).
        r   rE  zstarting new turn (cached)Ú_last_flushed_db_idxN)
r‰  r‡  rU   Ú_last_activity_tsÚ_last_activity_descÚUNKNOWNÚ_last_activity_provenancerá   r/  Ú_api_call_count)rµ   r-  r‡  s      r>   r   z)GatewayRunner._init_cached_agent_for_turnæ]  sm   € ð ˜aÒÐØAÐAÐAÐAÐAÐAå&*¤i¡k¤kˆEÔ#Ø(DˆEÔ%Ø.@Ô.HˆEÔ+õ �uÐ4Ñ5Ô5ð /Ø-.�Ô*Ø !ˆÔÐÐrM   r  c                 óX  — |�t          |d¦  «        sdS t          |dd¦  «        €dS 	 t          | dd¦  «        }|€dS |                     ¦   «          |j                             |¦  «        }|€dS |                     |¦  «        sdS |                     |¦  «        rdS t          |dd¦  «        }|                     t          |t          ¦  «        r|nd¦  «         t                               d|¦  «         dS # t          $ r'}t                               d||¦  «         Y d}~dS d}~ww xY w)uÉ  Fire on_session_end extraction before soft-evicting a live agent.

        Soft eviction (``_release_evicted_agent_soft``) deliberately keeps the
        session resumable and does NOT fire ``on_session_end`` â€” that hook is
        reserved for the true session boundary, tear-down done by
        ``_session_expiry_watcher`` when the session finally expires.

        But the watcher tears down whatever agent it finds in ``_agent_cache``
        at expiry time.  If cache pressure (the LRU cap) soft-evicts a
        finalizable session's agent BEFORE it expires, the watcher later finds
        no cached agent and ``on_session_end`` is silently skipped â€” memory
        providers never see the transcript (#11205, LRU-cap variant).

        We hold the live, fully-scoped agent right now, so commit its
        end-of-session memory extraction here using the agent's own memory
        manager (correct per-user/chat scoping, no reconstruction).  This uses
        ``commit_memory_session`` â€” extraction WITHOUT provider teardown â€” so
        the eviction stays soft and a resumed turn keeps working.

        Only fires for sessions the expiry watcher will eventually finalize
        (finite reset policy).  For ``mode == "none"`` sessions the watcher
        never runs, so there is no missed-boundary to compensate for and we
        skip the commit (the agent is simply released).  Best-effort: any
        failure is swallowed so eviction still proceeds.
        NÚcommit_memory_sessionri
  r›  r[  zlCommitted on_session_end extraction before soft-evicting finalizable session=%s (cache pressure, pre-expiry)z)Pre-evict memory commit failed for %s: %s)rá   rV   r9
  rÄ  rv   Úis_session_finalizabler  r6  rt   r½  r3   r4   r2   )r  rµ   r  r  r®  r(  rÄ  s          r>   Ú _commit_memory_before_soft_evictz.GatewayRunner._commit_memory_before_soft_evict^  sp  € ð4 ˆ=¥¨Ð/FÑ GÔ Gˆ=ØˆFÝ�5Ð+¨TÑ2Ô2Ð:ØˆFð	OÝ˜T ?°DÑ9Ô9ˆFØˆ~Ø�Ø×!Ò!Ñ#Ô#Ð#Ø”O×'Ò'¨Ñ,Ô,ˆEØˆ}Ø�ð
 ×0Ò0°Ñ7Ô7ð Ø�Ø×)Ò)¨%Ñ0Ô0ð Ø�Ý˜uÐ&9¸4Ñ@Ô@ˆHØ×'Ò'µJ¸xÍÑ4NÔ4NÐ(X¨¨ÐTXÑYÔYÐYÝ�LŠLðFØGJñô ð ð ð øõ ð 	Oð 	Oð 	OÝ�LŠLÐDÀcÈ2ÑNÔNÐNÐNÐNÐNÐNÐNÐNøøøøð	Oøøøs/   ©C8 ¾0C8 Á0C8 ÂC8 ÂAC8 Ã8
D)ÄD$Ä$D)c                 ó\   — |                       ||¦  «         |                      |¦  «         dS )aZ  Commit end-of-session memory (if warranted), then soft-release.

        Runs on the daemon eviction thread so the memory-provider call and the
        client teardown never block the caller's held cache lock. Order matters:
        commit uses the live agent's memory manager before ``release_clients``
        drops the message buffer.
        N)r8  r¦  )r  rµ   r  s      r>   Ú_commit_then_release_softz'GatewayRunner._commit_then_release_soft9^  s4   € ð 	×-Ò-¨e°SÑ9Ô9Ð9Ø×(Ò(¨Ñ/Ô/Ð/Ð/Ð/rM   c                 ó  — |€dS 	 t          |d¦  «        r|                     ¦   «          n|                      |¦  «         n# t          $ r Y nw xY wt          |d¦  «        rg |_        t          |d¦  «        r	d|_        dS dS )uÛ  Soft cleanup for cache-evicted agents â€” preserves session tool state.

        Called from _enforce_agent_cache_cap and _sweep_idle_cached_agents.
        Distinct from _cleanup_agent_resources (full teardown) because a
        cache-evicted session may resume at any time â€” its terminal
        sandbox, browser daemon, and tracked bg processes must outlive
        the Python AIAgent instance so the next agent built for the
        same task_id inherits them.
        NÚrelease_clientsr[  Ú_db_flush_scan_prefix)rá   r<  rd
  r2   r[  r=  )r  rµ   s     r>   r¦  z)GatewayRunner._release_evicted_agent_softD^  s¼   € ð ˆ=ØˆFð	Ý�uÐ/Ñ0Ô0ð 5Ø×%Ò%Ñ'Ô'Ð'Ð'ð ×-Ò-¨eÑ4Ô4Ð4øøÝð 	ð 	ð 	ØˆDð	øøøõ �5Ð-Ñ.Ô.ð 	)Ø&(ˆEÔ#õ �5Ð1Ñ2Ô2ð 	/Ø*.ˆEÔ'Ð'Ð'ð	/ð 	/s   †:A Á
AÁAc                 óò   — t          | dd¦  «        }|€cddlm} 	  |t          ¦   «         ¦  «        }n=# t          $ r0}t
                               d|¦  «          |i ¦  «        }Y d}~nd}~ww xY w|| _        |S )z÷Operator-configured agent-cache bounds, resolved once per process.

        Resolved lazily rather than in ``__init__`` so it also works for the
        ``__new__``-constructed runners used by tests and by the slash-command
        mixin.
        Ú_agent_cache_bounds_cacheNr   )Úresolve_agent_cache_boundsz)Agent cache bounds config read failed: %s)rV   Úgateway.agent_cache_pressurer@  rs   r2   r3   r4   r?  )r  Úboundsr@  rÄ  s       r>   Ú_agent_cache_boundsz!GatewayRunner._agent_cache_boundsi^  sª   € õ ˜Ð:¸DÑAÔAˆØˆ>ØOÐOÐOÐOÐOÐOð
8Ø3Ð3Õ4HÑ4JÔ4JÑKÔK��øÝð 8ð 8ð 8Ý—’ÐHÈ"ÑMÔMÐMð 4Ð3°BÑ7Ô7������øøøøð8øøøð .4ˆDÔ*Øˆs   ›3 ³
A-½&A(Á(A-c                 óJ   — |                       ¦   «         j        }|r|nt          S )u@   Effective LRU cap â€” the configured override, else the default.)rC  r
  Ú_AGENT_CACHE_MAX_SIZE©r  Ú
configureds     r>   Ú_agent_cache_capzGatewayRunner._agent_cache_cap‚^  s&   € à×-Ò-Ñ/Ô/Ô8ˆ
Ø'ÐBˆzˆzÕ-BÐBrM   c                 óJ   — |                       ¦   «         j        }|r|nt          S )uD   Effective idle TTL in seconds â€” configured override, else default.)rC  Úidle_ttl_secsÚ_AGENT_CACHE_IDLE_TTL_SECSrF  s     r>   Ú_agent_cache_idle_ttlz#GatewayRunner._agent_cache_idle_ttl‡^  s&   € à×-Ò-Ñ/Ô/Ô=ˆ
Ø'ÐGˆzˆzÕ-GÐGrM   c           
      ó`  ‡‡— ddl m}m}mŠ |                      ¦   «         }|j        sdS t          | dd¦  «        }t          | dd¦  «        }|r|€dS  |¦   «         }|�||j        k     rdS d„ |                      ¦   «         D ¦   «         Šdt          dt          d	t          fˆˆfd
„}|5  d„ |                     ¦   «         D ¦   «         } ||||j        |j        ¬¦  «        }	|	D ]\  }
}|                     |
d¦  «         Œ	 ddd¦  «         n# 1 swxY w Y   |	sqt          ˆfd„|D ¦   «         ¦  «        }t          ˆˆfd„|D ¦   «         ¦  «        }t                                d||j        t%          |¦  «        |||r|sdnd¦  «         dS t%          |	¦  «        }t                                d||j        |d                     d„ |	D ¦   «         ¦  «        ¦  «         	 t)          j        | j        |	fdd¬¦  «                             ¦   «          n%# t0          $ r |                      |	¦  «         Y nw xY w|S )uå  Shed cached transcripts once the gateway's own heap nears its budget.

        The LRU cap counts entries and the idle sweep counts seconds; neither
        knows that one cached agent pins a full ``_session_messages``
        transcript â€” tens of MB on a session with 100+ tool calls.  A gateway
        serving many chats therefore holds every warm transcript indefinitely:
        agents that took a turn within the TTL are never idle-swept, and the
        sweep additionally defers finalizable sessions until they expire.  RSS
        climbs until the cgroup throttles and SIGTERM can no longer flush
        inside systemd's stop timeout (#80764).

        This is the missing valve.  Above the configured anonymous-RSS budget
        it evicts LRU agents through the same soft path the cap enforcer uses,
        so the transcript is dropped and rebuilt from the persisted session on
        the next turn.  Three things are never touched: agents mid-turn (their
        clients and sandboxes are in use), the most recently used sessions
        (whose prompt cache is worth the most), and any session whose live
        transcript has not finished reaching disk.

        Returns the number of entries evicted (0 when memory is fine).
        r   )Úplan_pressure_evictionsÚread_anon_rss_mbÚ transcript_persistence_caught_upr  Nr  c                 óH   — h | ]\  }}|®|t           u¯t          |¦  «        ’Œ S r^   r(  r)  s      r>   rQ  zBGatewayRunner._sweep_agent_cache_under_pressure.<locals>.<setcomp>¶^  r*  rM   r  rµ   r-   c                 óZ   •— |�	|t           u rdS t          |¦  «        ‰v rdS  ‰|¦  «        S rl  r(  )r  rµ   r,  rP  s     €€r>   Ú_is_evictablezFGatewayRunner._sweep_agent_cache_under_pressure.<locals>._is_evictable¼^  s?   ø€ Øˆ} Õ)@Ð @Ð @Ø�uÝ�%‰yŒy˜KÐ'Ð'Ø�uØ3Ð3°EÑ:Ô:Ð:rM   c                 óZ   — g | ](\  }}|t          |t          ¦  «        r
|r|d          n|f‘Œ)S ©r   ©rt   r€  )rb   r  r®  s      r>   r  zCGatewayRunner._sweep_agent_cache_under_pressure.<locals>.<listcomp>Ä^  sM   € ð ð ð á�C˜ð ¥*¨UµEÑ":Ô":ÐO¸uÐO�e˜A”h�hÈ%ÐPðð ð rM   )Úis_evictableÚmax_evictionsÚprotect_recentc              3   óH   •K  — | ]\  }}|®t          |¦  «        ‰v ¯dV — Œd S ©Nr(   )rÍ   )rb   rK  r  r,  s      €r>   rd   zBGatewayRunner._sweep_agent_cache_under_pressure.<locals>.<genexpr>Ò^  s<   øè è € Ð\Ð\¡$ ! Q°Q°]ÅrÈ!ÁuÄuÐP[ÐG[ÐG[˜AÐG[ÐG[ÐG[ÐG[Ð\Ð\rM   c              3   óp   •K  — | ]0\  }}|�)|t           ur t          |¦  «        ‰v¯! ‰|¦  «        °,dV — Œ1d S r[  r(  )rb   rK  r  r,  rP  s      €€r>   rd   zBGatewayRunner._sweep_agent_cache_under_pressure.<locals>.<genexpr>Ó^  sj   øè è € ð ð á�A�qØ�=ØÕ4Ð4Ð4Ý�q‘E”E Ð,Ð,Ø8Ð8¸Ñ;Ô;ð -ð	 ð -Ð,Ð,Ð,ðð rM   zŽAgent cache pressure: anon RSS %dMB over budget %dMB but no evictable session (%d cached, %d mid-turn, %d blocked on un-flushed persistence)%su–    â€” transcripts are not reaching the session DB (session persistence disabled or failing?); the memory valve cannot shed sessions until they persist.u8    â€” memory will keep climbing until those turns finish.uW   Agent cache pressure: anon RSS %dMB over budget %dMB â€” evicting %d LRU session(s): %sr  c              3   ó    K  — | ]	\  }}|V — Œ
d S r^   rN  )rb   r  rK  s      r>   rd   zBGatewayRunner._sweep_agent_cache_under_pressure.<locals>.<genexpr>ï^  s&   è è € Ð-Ð-™f˜c 1�cÐ-Ð-Ð-Ð-Ð-Ð-rM   Tzagent-cache-pressurer  )rA  rN  rO  rP  rC  Úmemory_high_mbrV   rO  rw   r   rº   rñ  Úmax_evictions_per_passrY  rU  r¦  r3   rã   r7   rf   r¤  r¥  Ú_release_pressure_batchr§  r2   )r  rN  rO  rB  ræ  rº	  Úrss_mbrS  ÚorderedÚplanr  rK  Ú	_mid_turnÚ
_unflushedÚevicted_countr,  rP  s                  @@r>   r  z/GatewayRunner._sweep_agent_cache_under_pressureŒ^  s‚  øø€ ð,	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð ×)Ò)Ñ+Ô+ˆØÔ$ð 	Ø�1Ý˜˜~¨tÑ4Ô4ˆÝ˜Ð1°4Ñ8Ô8ˆØð 	˜˜ð �1à!Ð!Ñ#Ô#ˆØˆ>˜V fÔ&;Ò;Ð;Ø�1ð
ð 
à×1Ò1Ñ3Ô3ð
ñ 
ô 
ˆð	;�sð 	;­3ð 	;µ4ð 	;ð 	;ð 	;ð 	;ð 	;ð 	;ð 	;ð ð 	&ð 	&ðð à"(§,¢,¡.¤.ðñ ô ˆGð +Ð*ØØ*Ø$Ô;Ø%Ô4ð	ñ ô ˆDð ð &ð &‘��QØ—
’
˜3 Ñ%Ô%Ð%Ð%ð&ð	&ð 	&ð 	&ñ 	&ô 	&ð 	&ð 	&ð 	&ð 	&ð 	&ð 	&øøøð 	&ð 	&ð 	&ð 	&ð ð 	ÝÐ\Ð\Ð\Ð\¨'Ð\Ñ\Ô\Ñ\Ô\ˆIÝð ð ð ð ð à#ðñ ô ñ ô ˆJõ �NŠNð,ð ˜Ô-­s°7©|¬|¸YÈ
ð
 "ðTð +4ðTð Eð Eð Tñô ð ð �1å˜D™	œ	ˆÝ�Šð$à�FÔ)¨=Ø�IŠIÐ-Ð-¨Ð-Ñ-Ô-Ñ-Ô-ñ		
ô 	
ð 	
ð	/ÝÔØÔ3Ø�WØØ+ð	ñ ô ÷
 Še‰gŒgˆgˆgøÝð 	/ð 	/ð 	/Ø×(Ò(¨Ñ.Ô.Ð.Ð.Ð.ð	/øøøð
 Ðs%   Â'AD
Ä
DÄDÇ0H	 È	H+È*H+rc  c                 ó   — |rf|                      d¦  «        \  }}	 |                      ||¦  «         n3# t          $ r&}t                               d||¦  «         Y d}~nd}~ww xY w~|°f	 ddlm}  |dd¬¦  «         dS # t          $ r Y dS w xY w)u9  Release a pressure-evicted batch, then return the heap to the OS.

        Sequential on one daemon thread rather than a thread per agent: the
        batch is already capped, and the point of the pass is to reclaim
        memory, not to race N teardowns. The trailing ``malloc_trim`` is what
        turns "Python dropped the transcript" into "RSS actually fell" â€”
        without it glibc keeps the freed arenas and the cgroup never notices.

        The plan is drained (``pop`` + ``del``) rather than iterated so that
        no local reference pins the evicted agents when ``gc.collect`` +
        ``malloc_trim`` run â€” otherwise the trim frees almost nothing in this
        pass, the next tick re-reads a still-high RSS, and the valve
        over-evicts an extra batch of warm prompt caches every cycle.
        r   z"Pressure release failed for %s: %sN©Útrim_memoryTÚagent_cache_pressure)rí   r•  )rU  r:  r2   r3   r4   Úhermes_cli.mem_trimri  )r  rc  r  rµ   rÄ  ri  s         r>   r`  z%GatewayRunner._release_pressure_batchÿ^  sé   € ð ð 	ØŸš !™œ‰JˆC�ðLØ×.Ò.¨u°cÑ:Ô:Ð:Ð:øÝð Lð Lð LÝ—’ÐAÀ3ÈÑKÔKÐKÐKÐKÐKÐKÐKøøøøðLøøøàð ð 	ð	Ø7Ð7Ð7Ð7Ð7Ð7àˆK˜dÐ+AÐBÑBÔBÐBÐBÐBøÝð 	ð 	ð 	ØˆDˆDð	øøøs&   œ3 ³
A#½AÁA#Á*A? Á?
BÂBc           
      óÄ  — t          | dd¦  «        }|€dS t          |d¦  «        sdS d„ |                      ¦   «         D ¦   «         }|                      ¦   «         }t	          dt          |¦  «        |z
  ¦  «        }g }|dk    r�t          |                     ¦   «         ¦  «        }|d|…         D ]c}|                     |¦  «        }t          |t          ¦  «        r
|r|d         nd}	|	�t          |	¦  «        |v rŒL|                     ||	f¦  «         Œd|D ]\  }}
|                     |d¦  «         Œt          |¦  «        |z
  }|dk    r*t                               dt          |¦  «        ||¦  «         |D ]l\  }}	t                               d|t          |¦  «        ¦  «         |	�<t#          j        | j        |	|fdd	|dd
…         › �¬¦  «                             ¦   «          ŒmdS )uë  Evict oldest cached agents when cache exceeds the LRU cap.

        Must be called with _agent_cache_lock held.  Resource cleanup
        (memory provider shutdown, tool resource close) is scheduled
        on a daemon thread so the caller doesn't block on slow teardown
        while holding the cache lock.

        Agents currently in _running_agents are SKIPPED â€” their clients,
        terminal sandboxes, background processes, and child subagents
        are all in active use by the running turn.  Evicting them would
        tear down those resources mid-turn and crash the request.  If
        every candidate in the LRU order is active, we simply leave the
        cache over the cap; it will be re-checked on the next insert.
        r  Nr  c                 óH   — h | ]\  }}|®|t           u¯t          |¦  «        ’Œ S r^   r(  r)  s      r>   rQ  z9GatewayRunner._enforce_agent_cache_cap.<locals>.<setcomp>6_  r*  rM   r   uk   Agent cache over cap (%d > %d); %d excess slot(s) held by mid-turn agents â€” will re-check on next insert.z;Agent cache at cap; evicting LRU session=%s (cache_size=%d)Tzagent-cache-evict-r  r  )rV   rá   rO  rH  rC  r7   r½  rž  rv   rt   r€  rÍ   r”   rU  r3   rã   rz  r¤  r¥  r:  r§  )r  ræ  r,  ÚcapÚexcessÚ
evict_planÚordered_keysr  r®  rµ   rK  Úremaining_over_caps               r>   rª  z&GatewayRunner._enforce_agent_cache_cap_  s1  € õ ˜˜~¨tÑ4Ô4ˆØˆ>ØˆFõ �v˜}Ñ-Ô-ð 	ØˆFð

ð 
à×1Ò1Ñ3Ô3ð
ñ 
ô 
ˆð ×#Ò#Ñ%Ô%ˆÝ�Q�˜F™œ cÑ)Ñ*Ô*ˆØ"$ˆ
Ø�AŠ:ˆ:Ý §¢¡¤Ñ.Ô.ˆLØ# G V GÔ,ð 0ð 0�ØŸ
š
 3™œ�Ý$.¨uµeÑ$<Ô$<ÐPÀÐP˜˜aœ˜ÈD�ØÐ$­¨E©¬°kÐ)AÐ)AØØ×!Ò! 3¨ ,Ñ/Ô/Ð/Ð/à ð 	"ð 	"‰FˆC�Ø�JŠJ�s˜DÑ!Ô!Ð!Ð!å  ™[œ[¨3Ñ.ÐØ Ò!Ð!Ý�NŠNðDå�F‘”˜SÐ"4ñô ð ð %ð 	ð 	‰JˆC�Ý�KŠKØMØ•S˜‘[”[ñô ð ð Ð õ Ô ØÔ9Ø ˜ØØ8¨c°#°2°#¬hÐ8Ð8ð	ñ ô ÷
 ’%‘'”'�'øð#	ð 	rM   c                 ó€  — t          | dd¦  «        }t          | dd¦  «        }|�|€dS t          j        ¦   «         }|                      ¦   «         }g }d„ |                      ¦   «         D ¦   «         }|5  t	          |                     ¦   «         ¦  «        D ]õ\  }}t          |t          ¦  «        r
|r|d         nd}	|	€Œ)t          |	¦  «        |v rŒ;t          |	dd¦  «        }
|
€ŒO||
z
  |k    r�d}t          | dd¦  «        }	 |�.| 	                    ¦   «          |j
                             |¦  «        }n# t          $ r d}Y nw xY w|�-|�+|                     |¦  «        r|                     |¦  «        sŒÞ|                     ||	f¦  «         Œö|D ]\  }}|                     |d¦  «         Œ	 ddd¦  «         n# 1 swxY w Y   |D ]n\  }}	t"                               d||t          |	d|¦  «        z
  ¦  «         t'          j        | j        |	fd	d
|dd…         › �¬¦  «                             ¦   «          Œot/          |¦  «        S )uê  Evict cached agents whose AIAgent has been idle past the idle TTL.

        Safe to call from the session expiry watcher without holding the
        cache lock â€” acquires it internally.  Returns the number of entries
        evicted.  Resource cleanup is scheduled on daemon threads.

        Agents currently in _running_agents are SKIPPED for the same reason
        as _enforce_agent_cache_cap: tearing down an active turn's clients
        mid-flight would crash the request.
        r  Nr  r   c                 óH   — h | ]\  }}|®|t           u¯t          |¦  «        ’Œ S r^   r(  r)  s      r>   rQ  z:GatewayRunner._sweep_idle_cached_agents.<locals>.<setcomp>�_  r*  rM   r0  r›  z3Agent cache idle-TTL evict: session=%s (idle=%.0fs)Tzagent-cache-idle-r  r  )rV   rU   rL  rO  r½  rñ  rt   r€  rÍ   r9
  rÄ  rv   r2   r7  r  r”   rU  r3   rz  r¤  r¥  r¦  r§  r7   )r  ræ  rº	  rŒ  Úidle_ttlÚto_evictr,  r  r®  rµ   Úlast_activityr\  r  rK  s                 r>   r  z'GatewayRunner._sweep_idle_cached_agentso_  sö  € õ ˜˜~¨tÑ4Ô4ˆÝ˜Ð1°4Ñ8Ô8ˆØˆ>˜U˜]Ø�1ÝŒi‰kŒkˆØ×-Ò-Ñ/Ô/ˆØ "ˆð
ð 
à×1Ò1Ñ3Ô3ð
ñ 
ô 
ˆð
 ð 4	&ð 4	&Ý" 6§<¢<¡>¤>Ñ2Ô2ð 12ð 12‘
��UÝ$.¨uµeÑ$<Ô$<ÐPÀÐP˜˜aœ˜ÈD�Ø�=ØÝ�e‘9”9 Ð+Ð+ØÝ '¨Ð/BÀDÑ IÔ I�Ø Ð(ØØ˜-Ñ'¨8Ò3Ð3ð2 %)�MÝ$ T¨?¸DÑAÔA�Fð-Ø!Ð-Ø"×1Ò1Ñ3Ô3Ð3Ø,2¬O×,?Ò,?ÀÑ,DÔ,D˜MøøÝ$ð -ð -ð -Ø(,˜˜˜ð-øøøð &Ð1Ø"Ð.Ø"×9Ò9¸-ÑHÔHð /à &× :Ò :¸=Ñ IÔ Ið /ð !Ø—O’O S¨% LÑ1Ô1Ð1øØ"ð &ð &‘��QØ—
’
˜3 Ñ%Ô%Ð%Ð%ð&ðg4	&ð 4	&ð 4	&ñ 4	&ô 4	&ð 4	&ð 4	&ð 4	&ð 4	&ð 4	&ð 4	&øøøð 4	&ð 4	&ð 4	&ð 4	&ðj #ð 
	ð 
	‰JˆC�Ý�KŠKØEØ�S�7 5Ð*=¸sÑCÔCÑCñô ð õ ÔØÔ7Ø�XØØ3¨¨S¨b¨S¬Ð3Ð3ð	ñ ô ÷
 Še‰gŒgˆgˆgÝ�8‰}Œ}Ðs8   Á2BF5Ä 0D1Ä0F5Ä1E Ä=F5Ä?E Å A(F5Æ5F9Æ<F9c                 óL  — t          j        dd¦  «                             ¦   «         }|r|                     d¦  «        S t	          ¦   «         }|                     d¦  «        pi                      d¦  «        }|pd                     ¦   «         }|r|                     d¦  «        S dS )zÁReturn the proxy URL if proxy mode is configured, else None.

        Checks GATEWAY_PROXY_URL env var first (convenient for Docker),
        then ``gateway.proxy_url`` in config.yaml.
        ÚGATEWAY_PROXY_URLr®   r]  r9   Ú	proxy_urlN)r’   rÆ  rx   r  rs   rv   )r  rï  rœ  s      r>   Ú_get_proxy_urlzGatewayRunner._get_proxy_urlÌ_  s›   € õ ŒiÐ+¨RÑ0Ô0×6Ò6Ñ8Ô8ˆØð 	#Ø—:’:˜c‘?”?Ð"Ý"Ñ$Ô$ˆØ�wŠw�yÑ!Ô!Ð' R×,Ò,¨[Ñ9Ô9ˆØˆy�b×ÒÑ!Ô!ˆØð 	#Ø—:’:˜c‘?”?Ð"ØˆtrM   Úscfgrõ  z(tuple[Any, Optional[Callable[[], None]]]c                óð  — ddl m} d}|j        t          j        k    rt          |d¦  «        r||j        f	 dd„}t          |dd¦  «        }|s|d	k    rt          d
¦  «        ‚|r|j	        nd}d}	|j        t          j
        k    rd}d}	|j        t          j        k    r t          t          |dd¦  «        pd¦  «        nd}
 ||j        |j        ||	|
|j        pdt          |dd¦  «        pd¬¦  «        }||fS )uq  Build the shared ``StreamConsumerConfig`` and the optional
        Telegram pause-typing closure used by both agent-run paths.

        ``on_missing_cursor`` controls how platforms whose adapter sets
        ``SUPPORTS_MESSAGE_EDITING = False`` are handled â€” both semantics
        are preserved verbatim from the pre-refactor call sites:

        - ``"fallback"`` (proxy path): stream anyway with an empty cursor.
        - ``"raise"`` (in-process agent path): raise ``RuntimeError`` so
          the caller's ``except`` skips streaming entirely.

        Returns ``(consumer_cfg, pause_typing_before_finalize)``.
        r   )ÚStreamConsumerConfigNrO  r-   c                 ó0   — |                       |¦  «         d S r^   )rO  )r³  Ú_chat_ids     r>   rÝ  zRGatewayRunner._build_stream_consumer_config.<locals>._pause_typing_before_finalizeõ_  s   € ð ×.Ò.¨xÑ8Ô8Ð8Ð8Ð8rM   ÚSUPPORTS_MESSAGE_EDITINGTró  z(skip streaming for non-editable platformr®   FÚfresh_final_after_secondsr@  Úeditr´  )Úedit_intervalÚbuffer_thresholdÚcursorÚbuffer_onlyr‚  r”  r´  rŽ  )r–  r~  r�   rÄ  rÍ  rá   r2  rV   r¾  r†  ÚMATRIXri  r„  r…  r”  )r  r(  r|  r1  rõ  r~  rÝ  Ú_adapter_supports_editÚ_effective_cursorÚ_buffer_onlyÚ_fresh_final_secsrÜ  s               r>   r—  z+GatewayRunner._build_stream_consumer_configÜ_  sc  € ð* 	AÐ@Ð@Ð@Ð@Ð@à(,Ð%ØŒ?�hÔ/Ò/Ð/µG¸GÐE\Ñ4]Ô4]Ð/à Øœð9ð ð9ð 9ð 9ð 9õ ")¨Ð2LÈdÑ!SÔ!SÐØ%ð 	KÐ*;¸wÒ*FÐ*FÝÐIÑJÔJÐJØ+AÐI˜DœK˜KÀrÐð ˆØŒ?�hœoÒ-Ð-Ø "ÐØˆLð Œ¥(Ô"3Ò3Ð3õ •'˜$Ð ;¸SÑAÔAÐHÀSÑIÔIÐIàð 	ð
 -Ð,ØÔ,Ø!Ô2Ø$Ø$Ø&7Ø”nÐ.¨Ý˜f k°2Ñ6Ô6Ð<¸"ð
ñ 
ô 
ˆð Ð;Ð;Ð;rM   r‹  c	              ƒ   óœ  ‡ ‡‡K  — 	 ddl m}	m}
 n# t          $ r
 dg dg dœcY S w xY w‰                      ¦   «         }|sdg dg dœS 	 ddlm}m} 	  |d¦  «        pd                     ¦   «         }n2# |$ r* t          j
        dd¦  «                             ¦   «         }Y nw xY wn7# t          $ r* t          j
        dd¦  «                             ¦   «         }Y nw xY wd	t          fˆˆ ˆfd
„}g }|r|                     d|dœ¦  «         |D ]J}|                     d¦  «        }|                     d¦  «        }|dv r|r|                     ||dœ¦  «         ŒK|                     d|dœ¦  «         ddi}|rd|› �|d<   |r||d<   d|ddœ}d}t          t          ‰ dd¦  «        dd¦  «        }|€ddlm}  |¦   «         }t%          |j        ¦  «        }t)          ¦   «         }ddlm}  |||d¦  «        }|€|j        o
|j        dk    nt          |¦  «        }‰                      ||¦  «        }|r„	 ddlm} ‰                      |¦  «        } | r3‰                      ||| d ¬!¦  «        \  }!}" || |j        |!||"||¬"¦  «        }n2# t          $ r%}#t>                                d#|#¦  «         Y d}#~#nd}#~#ww xY wd}$|r&tC          j"        | #                    ¦   «         ¦  «        }$‰                      |¦  «        } | r4	 |  $                    |j        |¬$¦  «        ƒ d{V —† n# t          $ r Y nw xY wd}%tK          j%        ¦   «         }&	  |
dd%¬&¦  «        }' |	|'¬'¦  «        4 ƒd{V —†}(|( &                    |› d(�||¬)¦  «        4 ƒd{V —†	 })|)j'        d*k    rí|) (                    ¦   «         ƒ d{V —†}*t>           )                    d+|)j'        ||*dd,…         ¦  «         d-|)j'        › d.|*dd/…         › �g dg dœcddd¦  «        ƒd{V —† cddd¦  «        ƒd{V —† |r| *                    ¦   «          |$rS	 tC          j+        |$d0¬'¦  «        ƒ d{V —† S # tB          j,        tB          j-        f$ r |$ .                    ¦   «          Y S w xY wS d}+|)j/         0                    ¦   «         2 3 d{V —†}, |¦   «         sÈt>           1                    d1‰pd2‰pd¦  «         dg dg te          |¦  «        |d3d4œc cddd¦  «        ƒd{V —† cddd¦  «        ƒd{V —† |r| *                    ¦   «          |$rS	 tC          j+        |$d0¬'¦  «        ƒ d{V —† S # tB          j,        tB          j-        f$ r |$ .                    ¦   «          Y S w xY wS |, 3                    d5d6¬7¦  «        }-|+|-z  }+d8|+v rÿ|+ 4                    d8d9¦  «        \  }.}+|.                     ¦   «         }.|.sŒ4|. 5                    d:¦  «        r¶|.d;d…         }/|/                     ¦   «         d<k    rn—	 tm          j7        |/¦  «        }0|0                     d=g ¦  «        }1|1rP|1d                              d>i ¦  «        }2|2                     dd¦  «        }|r|%|z  }%|r| 8                    |¦  «         n# tl          j9        $ r Y nw xY wd8|+v °ÿte          |+¦  «        tt          k    rtw          d?¦  «        ‚�Œ!6 	 ddd¦  «        ƒd{V —† n# 1 ƒd{V —†swxY w Y   ddd¦  «        ƒd{V —† n# 1 ƒd{V —†swxY w Y   n¾# tB          j-        $ r ‚ t          $ r¢}3t>           <                    d@||3¦  «         |%szdA|3› �g dg dœcY d}3~3|r| *                    ¦   «          |$rS	 tC          j+        |$d0¬'¦  «        ƒ d{V —† S # tB          j,        tB          j-        f$ r |$ .                    ¦   «          Y S w xY wS Y d}3~3nd}3~3ww xY w|r| *                    ¦   «          |$rS	 tC          j+        |$d0¬'¦  «        ƒ d{V —† n¦# tB          j,        tB          j-        f$ r |$ .                    ¦   «          Y nuw xY wnp# |r| *                    ¦   «          |$rS	 tC          j+        |$d0¬'¦  «        ƒ d{V —† w # tB          j,        tB          j-        f$ r |$ .                    ¦   «          Y w w xY ww xY wtK          j%        ¦   «         |&z
  }4 |¦   «         s7t>           1                    dB‰pd2‰pd¦  «         dg dg te          |¦  «        |d3d4œS t>           1                    dC||pdddD…         |4te          |%¦  «        ¦  «         |%pdEd|dœdF|%dœgd9g te          |¦  «        ||duot          |%¦  «        d4œS )GaT  Forward the message to a remote Hermes API server instead of
        running a local AIAgent.

        When ``GATEWAY_PROXY_URL`` (or ``gateway.proxy_url`` in config.yaml)
        is set, the gateway becomes a thin relay: it handles platform I/O
        (encryption, threading, media) and delegates all agent work to the
        remote server via ``POST /v1/chat/completions`` with SSE streaming.

        This lets a Docker container handle Matrix E2EE while the actual
        agent runs on the host with full access to local files, memory,
        skills, and a unified session store.
        r   )ÚClientSessionÚClientTimeoutuE   âš ï¸� Proxy mode requires aiohttp. Install with: pip install aiohttprë  uH   âš ï¸� Proxy URL not configured (GATEWAY_PROXY_URL or gateway.proxy_url))ÚUnscopedSecretErrorrO  ÚGATEWAY_PROXY_KEYr®   r-   c                  ó<   •— ‰ �‰sdS ‰                      ‰‰ ¦  «        S r¹  rø  ©r¼  r  r+   s   €€€r>   r3  z>GatewayRunner._run_agent_via_proxy.<locals>._run_still_currentX`  ó)   ø€ ØÐ%¨[Ð%Ø�tØ×/Ò/°¸^ÑLÔLÐLrM   rß  rª  r¦  r4  >   r¬  r­  r¬  zContent-Typezapplication/jsonzBearer ÚAuthorizationzX-Hermes-Session-Idzhermes-agentT)r  r(  ÚstreamNrz   rî  rï  rR  r  rñ  r.  rô  )r1  r2  rz   r¯   rø  rù  rú  z+Proxy: could not set up stream consumer: %sr.  r  )rü  Ú	sock_readr  z/v1/chat/completions)r3  Úheadersr  zProxy error (%d) from %s: %sr¡  u   âš ï¸� Proxy error (z): rå  r&   uK   Discarding stale proxy stream for %s â€” generation %d is no longer currentr¿  F)rò  r(  rç  r»  r)  rN   r‡  rQ  rl  rï  r  r(   zdata: rá  z[DONE]r  ÚdeltazAProxy SSE stream exceeded max buffer size without a line boundaryz Proxy connection error to %s: %su   âš ï¸� Proxy connection error: uK   Discarding stale proxy result for %s â€” generation %d is no longer currentz>proxy response: url=%s session=%s time=%.1fs response=%d charsr�  z(No response from remote agent)r­  )=ÚaiohttprŽ  r�  r\  r{  r…  r�  rO  rx   r’   rÆ  r2   rº   r”   rv   rV   rÆ  rð  ru  r�   rs   rT  rS  rÓ  r”  rî	  r–  rò  r@  r—  r2  r3   r4   r  r”  r®
  r˜  rU   Úpostr5  rè   rã   rÊ  r  r,  r›  r  r4  Úiter_anyrz  r7   r  re   r!  r3  r4  rý  rí  Ú#_GATEWAY_PROXY_SSE_BUFFER_MAX_CHARSrj  rP   )5r  r$  r‹  rÙ  r(  rN   r+   r¼  r:  Ú_AioClientSessionr�  rz  r�  rO  Ú	proxy_keyr3  Úapi_messagesr§  r¦  r4  r˜  r  rþ  rÖ  rð  r?  rA  rS  r×  rØ  r0  rò  r³  rÜ  rÝ  rÞ  Ústream_taskÚfull_responseÚ_startÚ_timeoutrâ	  Úrespró  rù  rø  rè   r[  rî  Úobjr  r™  r¨  Ú_elapseds5   `     ``                                             r>   Ú_run_agent_via_proxyz"GatewayRunner._run_agent_via_proxy!`  s§  øøøè è € ð.	ØQÐQÐQÐQÐQÐQÐQÐQÐQøÝð 	ð 	ð 	à"iØØØð	ð ð ð ð ð	øøøð ×'Ò'Ñ)Ô)ˆ	Øð 	à"lØØØð	ð ð ð	CØJÐJÐJÐJÐJÐJÐJÐJðGØ'˜ZÐ(;Ñ<Ô<ÐBÀ×IÒIÑKÔK�	�	øØ&ð Gð Gð GÝœIÐ&9¸2Ñ>Ô>×DÒDÑFÔF�	�	�	ðGøøøøøåð 	Cð 	Cð 	CÝœ	Ð"5°rÑ:Ô:×@Ò@ÑBÔBˆIˆIˆIð	Cøøøð	M¥Dð 	Mð 	Mð 	Mð 	Mð 	Mð 	Mð 	Mð 	Mð  .0ˆàð 	OØ×Ò¨¸nÐ MÐ MÑNÔNÐNàð 	Hð 	HˆCØ—7’7˜6‘?”?ˆDØ—g’g˜iÑ(Ô(ˆGØÐ,Ð,Ð,°Ð,Ø×#Ò#¨T¸gÐ$FÐ$FÑGÔGÐGøà×Ò V¸Ð@Ð@ÑAÔAÐAð $2Ð3EÐ"FˆØð 	=Ø'<°Ð'<Ð'<ˆG�OÑ$Øð 	8Ø-7ˆGÐ)Ñ*ð $Ø$Øð
ð 
ˆð  ÐÝ�  h°Ñ5Ô5°{ÀDÑIÔIˆØˆ=Ø6Ð6Ð6Ð6Ð6Ð6Ø#�OÑ%Ô%ˆEå+¨F¬OÑ<Ô<ˆÝ*Ñ,Ô,ˆØBÐBÐBÐBÐBÐBØ1Ð1Ø˜ {ñ
ô 
ˆð
 Ð&ð ŒMÐ6˜eœo°Ò6øå�oÑ&Ô&ð 	ð 6:×5UÒ5UÐV\Ð^nÑ5oÔ5oÐàð 	UðUØIÐIÐIÐIÐIÐIØ×3Ò3°FÑ;Ô;�Øð à×:Ò:Ø" E¨8Ø.8ð ;ñ ô ñ A�MÐ#@ð (=Ð'<Ø (Ø &¤Ø,Ø!1Ø+HØ,<Ø*<ð(ñ (ô (Ð$øøõ ð Uð Uð UÝ—’ÐJÈGÑTÔTÐTÐTÐTÐTÐTÐTøøøøðUøøøð ˆØð 	FÝ!Ô-Ð.>×.BÒ.BÑ.DÔ.DÑEÔEˆKð ×+Ò+¨FÑ3Ô3ˆØð 	ðØ×*Ò*¨6¬>ÐDTÐ*ÑUÔUÐUÐUÐUÐUÐUÐUÐUÐUøÝð ð ð Ø�ðøøøð ˆÝ”‘”ˆðY	)Ø$�}¨1¸Ð=Ñ=Ô=ˆHØ(Ð(°Ð:Ñ:Ô:ð Að Að Að Að Að Að A¸gØ"Ÿ<š<Ø Ð6Ð6Ð6ØØ#ð (ñ ô ð @ð @ð @ð @ð @ð @ð @ð @ð Ø”{ cÒ)Ð)Ø+/¯9ª9©;¬;Ð%6Ð%6Ð%6Ð%6Ð%6Ð%6˜
ÝŸšØ:Ø œK¨°J¸tÀ¸tÔ4Dñô ð ð
 /hÀTÄ[Ð.gÐ.gÐU_Ð`dÐadÐ`dÔUeÐ.gÐ.gØ(*Ø)*Ø%'ð	 ð  ð@ð @ð @ð @ñ @ô @ð @ð @ð @ð @ð @ð @ð @ðAð Að Að Añ Aô Að Að Að Að Að Að Að Aðb  ð *Ø ×'Ò'Ñ)Ô)Ð)Øð )ð)Ý!Ô*¨;ÀÐDÑDÔDÐDÐDÐDÐDÐDÐDÐDÐDøÝÔ,­gÔ.DÐEð )ð )ð )Ø×&Ò&Ñ(Ô(Ð(Ð(Ð(ð)øøøð)ð  �FØ'+¤|×'<Ò'<Ñ'>Ô'>ð ,ð ,ð ,ð ,ð ,ð ,ð ,˜eØ1Ð1Ñ3Ô3ð Ý"ŸKšKØ mØ +Ð 2¨sØ .Ð 3°!ñô ð ð 35Ø,.Ø-.Ø)+Ý25°g±,´,Ø.8Ø6;ð$ð $ð ð ð7@ð @ð @ð @ñ @ô @ð @ð @ð @ð @ð @ð @ð @ðAð Að Að Añ Aô Að Að Að Að Að Að Að Aðb  ð *Ø ×'Ò'Ñ)Ô)Ð)Øð )ð)Ý!Ô*¨;ÀÐDÑDÔDÐDÐDÐDÐDÐDÐDÐDÐDøÝÔ,­gÔ.DÐEð )ð )ð )Ø×&Ò&Ñ(Ô(Ð(Ð(Ð(ð)øøøð)ð]  %Ÿ|š|¨G¸I˜|ÑFÔF˜Ø $™˜ð # f˜n˜nØ+1¯<ª<¸¸aÑ+@Ô+@™L˜D &Ø#'§:¢:¡<¤<˜DØ#'ð )Ø (Ø#Ÿš¨xÑ8Ô8ð )Ø'+¨A¨B¨B¤x Ø#'§:¢:¡<¤<°8Ò#;Ð#;Ø$)ð!)Ý*.¬*°TÑ*:Ô*: CØ.1¯gªg°iÀÑ.DÔ.D GØ'.ð %SØ07¸´
·²¸wÈÑ0KÔ0K¨Ø27·)²)¸IÀrÑ2JÔ2J¨Ø+2ð )SØ,9¸WÑ,D¨MØ/?ð -SØ0@×0IÒ0IÈ'Ñ0RÔ0RÐ0RøøÝ'+Ô';ð !)ð !)ð !)Ø$( Dð!)øøøð' # f˜n˜nõ* ˜v™;œ;Õ)LÒLÐLÝ",Ø cñ#ô #ð ñ MðS (?Ð'>ð)@ð @ð @ñ @ô @ð @ð @ð @ð @ð @ð @ð @ð @ð @ð @ð @ð @ð @ð @ð @ð @ð @ð @øøøð @ð @ð @ð @ðAð Að Añ Aô Að Að Að Að Að Að Að Að Að Að Að Að Að Að Að Að Að Að Aøøøð Að Að Að AøøõF Ô%ð 	ð 	ð 	ØÝð 	ð 	ð 	Ý�LŠLÐ;¸YÈÑJÔJÐJØ ð à&KÈÐ&KÐ&KØ "Ø!"Øð	ð ð ð ð ð ð ð  ð *Ø ×'Ò'Ñ)Ô)Ð)Øð )ð)Ý!Ô*¨;ÀÐDÑDÔDÐDÐDÐDÐDÐDÐDÐDÐDøÝÔ,­gÔ.DÐEð )ð )ð )Ø×&Ò&Ñ(Ô(Ð(Ð(Ð(ð)øøøð)ðð ð ð ð øøøøð	øøøð  ð *Ø ×'Ò'Ñ)Ô)Ð)Øð )ð)Ý!Ô*¨;ÀÐDÑDÔDÐDÐDÐDÐDÐDÐDÐDÐDøÝÔ,­gÔ.DÐEð )ð )ð )Ø×&Ò&Ñ(Ô(Ð(Ð(Ð(ð)øøøð)øð  ð *Ø ×'Ò'Ñ)Ô)Ð)Øð )ð)Ý!Ô*¨;ÀÐDÑDÔDÐDÐDÐDÐDÐDÐDÐDÐDøÝÔ,­gÔ.DÐEð )ð )ð )Ø×&Ò&Ñ(Ô(Ð(Ð(Ð(ð)øøøð)øøøõ ”9‘;”; Ñ'ˆØ!Ð!Ñ#Ô#ð 	Ý�KŠKØ]ØÐ"˜sØÐ# !ñô ð ð #%ØØØÝ"% g¡,¤,Ø(Ø&+ðð ð õ 	�ŠØLØ˜
Ð( b¨#¨2¨#Ô.°½#¸mÑ:LÔ:Lñ	
ô 	
ð 	
ð ,ÐPÐ/Pà¨GÐ4Ð4Ø$°Ð?Ð?ðð ØÝ! '™lœlØ$Ø"2¸$Ð">Ð"VÅ4ÈÑCVÔCVð
ð 
ð 	
sµ  ‡ �$£$ÁB! ÁA. Á-B! Á.,BÂB! ÂBÂB! Â!1CÃCÈ(AI9 É9
J(ÊJ#Ê#J(Ë-"L Ì
LÌLÌ6[6 Í"[$Í8A)[Ï![$Ï3[6 ÐP;Ð;/Q-Ñ,Q-Ñ1[ÒZ-ÒA[Ó[$Ó'[6 ÔT/Ô//U!Õ U!Õ%B[×.A<Y+Ù*[Ù+Y=	Ù:[Ù<Y=	Ù=1[Ú/[$Û
[	Û[$Û[	Û[$Û[6 Û$
[.Û.[6 Û1[.Û2[6 Û5`  Û6^1Ü'^,Ü6^1Ü7`  Ý]1Ý1/^#Þ"^#Þ'`  Þ,^1Þ1`  ß_* ß*/`à`à bà:aábá/b	âbâb	â	br¡  r´  ru  rt  rv  rÚ  c              ƒ   óf  K  — t          t          | dd¦  «        dd¦  «        s)|                      |||||||||	|
||||¬¦  «        ƒ d{V —†S |                      |¦  «        }t          |¦  «        5  |                      |||||||||	|
||||¬¦  «        ƒ d{V —†cddd¦  «         S # 1 swxY w Y   dS )uð  Profile-scoping wrapper around the agent run.

        When multiplexing is active, resolve the inbound source's profile and
        run the whole turn inside ``_profile_runtime_scope`` so config/skills/
        memory resolve to that profile's home AND credentials resolve from that
        profile's secret scope (never the process-global ``os.environ``). When
        multiplexing is off this is a transparent pass-through â€” zero behavior
        change for single-profile gateways.
        rz   Nr½  F)	r+   r¼  r¡  r:  r´  ru  rt  rv  rÚ  )rV   Ú_run_agent_innerrÿ  rº  )r  r$  r‹  rÙ  r(  rN   r+   r¼  r¡  r:  r´  ru  rt  rv  rÚ  r®  s                   r>   r“  zGatewayRunner._run_agent>a  si  è è € õ4 •w˜t X¨tÑ4Ô4Ð6JÈEÑRÔRð 		Ø×.Ò.Ø˜¨°&¸*Ø'¸Ø!1ÐDTØ-¸*Ø%9Ø'=Ø)ð /ñ ô ð ð ð ð ð ð ð ð ×<Ò<¸VÑDÔDˆÝ# LÑ1Ô1ð 		ð 		Ø×.Ò.Ø˜¨°&¸*Ø'¸Ø!1ÐDTØ-¸*Ø%9Ø'=Ø)ð /ñ ô ð ð ð ð ð ð ð		ð 		ð 		ð 		ñ 		ô 		ð 		ð 		ð 		ð 		ð 		ð 		øøøð 		ð 		ð 		ð 		ð 		ð 		s   Á0)B&Â&B*Â-B*c                 ó<  — t          | dd¦  «        }t          |dd¦  «        sdS t          |dd¦  «        }|sdS ddlm} 	  |||j        j        t          |dd¦  «        |j        t          |d	d¦  «        t          |d
d¦  «        ¬¦  «        }n9# t          $ r, t                               d|j        |j        d¬¦  «         Y dS w xY w|r|j	        S t           
                    d|j        j        |j        t          |d	d¦  «        t          |d
d¦  «        ¦  «         dS )u®  Resolve the profile name for an inbound source via configured routes.

        Returns ``None`` when multiplexing is off, no routes are configured, or
        no route matches. Callers (``build_source``,
        ``_resolve_profile_home_for_source``) treat ``None`` as "use the
        default/active profile". When ``gateway.profile_routes`` is configured,
        the most specific matching route wins (guild < channel < thread). See
        :mod:`gateway.profile_routing` for matching rules.

        Gated on ``gateway.multiplex_profiles``: routing stamps
        ``source.profile``, which selects the session-key namespace and batch
        keys â€” but the profile-scoped agent run only activates under
        multiplexing. Without this gate, a configured route with multiplexing
        off would namespace batch/session keys by profile while the agent
        still runs in ``agent:main``, splitting the two out of agreement.
        rz   Nr½  FÚprofile_routesr   )Úmatch_profile_router¦  r›  ré  )r�   r¦  r2  r›  ré  z@Profile route matching failed for %s/%s, falling back to defaultTrß   zONo profile route matched: platform=%s chat_id=%s thread_id=%s parent_chat_id=%s)rV   Úgateway.profile_routingr­  r�   r­   r2  r2   r3   rã   r  r4   )r  r(  rz   Úroutesr­  Úmatcheds         r>   Ú_profile_name_for_sourcez&GatewayRunner._profile_name_for_sourceoa  sh  € õ" ˜˜x¨Ñ.Ô.ˆÝ�vÐ3°UÑ;Ô;ð 	Ø�4Ý˜Ð!1°4Ñ8Ô8ˆØð 	Ø�4Ø?Ð?Ð?Ð?Ð?Ð?ð	Ø)Ð)ØØœÔ.Ý  ¨°TÑ:Ô:ØœÝ! &¨+°tÑ<Ô<Ý& vÐ/?ÀÑFÔFðñ ô ˆGˆGøõ ð 	ð 	ð 	Ý�NŠNØRØ” ¤¸$ð ñ ô ð ð �4�4ð	øøøð ð 	#Ø”?Ð"Ý�ŠØ]ØŒOÔ! 6¤>Ý�F˜K¨Ñ.Ô.µ¸Ð@PÐRVÑ0WÔ0Wñ	
ô 	
ð 	
ð
 ˆts   ÁAB Â2CÃCc                 ó,  — ddl m}m}m} ddlm} d}	 |j        pd                     ¦   «         }|r|}|s|                      |¦  «        }|r|}|s |¦   «         pd} ||¦  «        }|rQ ||¦  «        sFt           
                    d||j        j        |j        t          |dd¦  «        ¦  «          |¦   «         S |S # t          $ rM t           
                    d	|j        j        |j        t          |dd¦  «        |pd
d¬¦  «          |¦   «         cY S w xY w)uá  Resolve which profile's HERMES_HOME should serve this inbound source.

        Resolution order:
          1. ``source.profile`` â€” set by /p/<profile>/ URL prefix, per-credential
             adapter ownership, OR profile_routes matching at ``build_source`` time.
          2. ``_profile_name_for_source`` â€” re-run routing here as a defensive
             fallback for sources that bypass ``build_source``.
          3. The active profile (the multiplexer's own home).
        r   )r;  rÅ  Úprofile_exists)rx  Nr®   rJ  z\Profile %r does not exist for source %s/%s (guild_id=%s), falling back to global HERMES_HOMEr¦  zjFailed to resolve profile directory for source %s/%s (guild_id=%s), falling back to global HERMES_HOME: %sz(no profile)Trß   )r?  r;  rÅ  r³  r¶  rx  r  rx   r±  r3   rã   r�   r­   r2  rV   r2   )	r  r(  r;  rÅ  r³  rx  Úexplicit_profilerÖ   Úprofile_dirs	            r>   rÿ  z.GatewayRunner._resolve_profile_home_for_sourceŸa  s¯  € ð	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð
 	5Ð4Ð4Ð4Ð4Ð4ð  Ðð#	%Ø”NÐ( b×/Ò/Ñ1Ô1ˆDØð (Ø#'Ð Øð ,Ø×4Ò4°VÑ<Ô<�Øð ,Ø'+Ð$Øð >Ø.Ð.Ñ0Ô0Ð=°I�à)˜/¨$Ñ/Ô/ˆKàð 	)¨¨°tÑ(<Ô(<ð 	)Ý—’ð9à$Ø”OÔ)Ø”NÝ˜F J°Ñ5Ô5ñô ð ð '�Ñ(Ô(Ð(ØÐøÝð 	%ð 	%ð 	%å�NŠNð9à”Ô%Ø”Ý˜ 
¨DÑ1Ô1Ø Ð2 NØð ñ ô ð ð #�?Ñ$Ô$Ð$Ð$Ð$ð	%øøøs   ”B%B< Â:B< Â<ADÄDc              ƒ   óX  ‡ ‡‡‡‡Ç‡È‡É‡Ê‡Ë‡Ì‡Í‡Î‡Ï‡Ð‡Ñ‡Ò‡Ó‡Ô‡Õ‡Ö‡×‡Ø‡Ù‡Ú‡Û‡Ü‡Ý‡Þ‡ß‡à‡áK  — ‰                       ¦   «         r#‰                      |||‰|‰‰|	¬¦  «        ƒ d{V —†S ddlm} ddlŠÜdt
          fˆˆ ˆfd„}t          ¦   «         Šát          ‰j        ¦  «        ŠÛddl	m
} t           |‰á‰Û¦  «        ¦  «        }‰á                     d¦  «        pi }|                     d	¦  «        pd}‰á                     d
i ¦  «        }t          |t          ¦  «        si }ddlmŠÝ 	 ddlm}  ‰Ý‰á‰Ûdd¦  «        } ||rt'          |¦  «        nd¦  «         n# t(          $ r Y nw xY w	 ddlm}  ‰Ý‰á‰Ûdd¦  «        } |t          |¦  «        ¦  «         n# t(          $ r Y nw xY w ‰Ý‰á‰Ûd¦  «        }t-          j        d¦  «        }t          |t          ¦  «        r|ni }|                     d¦  «        pi }|                     ‰Û¦  «        pi }|                     d¦  «        pi }d|v p1t          |t          ¦  «        od|v pt          |t          ¦  «        o‰Û|v } |r| s|n|p|pd}! ‰Ý‰á‰Ûd¦  «        pd}"ddlmŠÙm}# g ŠÏ |#‰á‰Û¦  «        ŠÍddddœdt6          dt
          dt8          t:                   dz  dt
          dt6          f
ˆÛˆÝˆˆáfd„}$dddd œd!t6          d"t6          dz  d#t6          dz  d$t:          dt6          f
ˆÍˆÏˆÙfd%„ŠÎdd&lm}% |!d'vo‰j        |%j         k    }& ‰Ý‰á‰Ûd(d)¦  «        }'‰  !                    ‰¦  «        }(tE          |(d*d¦  «        sd}(|'d+k    rd}(|!d,k    o‰j        |%j         k    })|)r ‰Üj#        ¦   «         ndŠÚ |$d-d|%j$        h¬.¦  «        }*‰j        |%j         k    o|*d+k    }+ |$d/d|%j$        h¬.¦  «        },|,d+k    }-|&p|-}.|.r ‰Üj#        ¦   «         nd}/dg}0dg}1dg}2dg}3dg}4dg}5‰j        |%j%        k    r°‰ j&                             |%j%        ¦  «        }6tE          |6d0d¦  «        }7t          |7t          ¦  «        rktO          |6d1¦  «        r[|7 (                    ¦   «         D ]F\  }8}9t7          |9¦  «        t7          ‰j)        ¦  «        k    r|6 *                    |8¦  «        r|8|5d<    nŒGtW          j,        ¦   «         }:t           ‰Ý‰á‰Ûd2¦  «        ¦  «        ŠË‰Ër‰  !                    ‰¦  «        nd};|;�tE          t[          |;¦  «        d3d¦  «        nd}<|;�|<�|<t\          j/        u rdŠËd};g ŠÊdg}=d4}>ta          düi d5‰“d6|“d7|(“d8|'“d9|-“d:|!“d;|"“d<|&“d=|/“d>‰Ú“d?|1“d@|0“dA|3“dB|2“dC|=“dD|>“dE‰Ë“dF‰Ê“dG|“dH|“dI‰Ý“dJ‰á“dK|“d	|“dL|)“dM|+“dN|.“dO|4“dP|5“dQ|:“dR|“dS|“dT|
“dU|“dV‰“dW‰“dX|“dY|	“dZ|“d[|“d\|“Ž}?tc          ‰ |?¦  «        }@|@j2        |?_2        |@j3        |?_3        d}A‰j        |%j4        k    r�‰  !                    ‰¦  «        }B|B�y	 tE          |Bd]d¦  «        }Ctk          |C¦  «        rt           |C¦   «         ¦  «        }An-t          |Bj6        j7                             d^d¦  «        ¦  «        }An# t(          $ r d}AY nw xY wtq          ‰j        ‰j9        |	|A¬_¦  «        }D‰j        |%j%        k    rGtE          ‰d`d¦  «        r6tE          ‰dad¦  «        r%‰j9        st7          tE          ‰dad¦  «        ¦  «        nd}E|DrT|D‰j9        k    r‰  :                    ‰|	¦  «        n4‰  ;                    ‰j        ‰j)        |DtE          ‰dbd¦  «        |	¬c¦  «        nd}F|F€|Erdd|	i}Fty          |F‰j        ¬e¦  «        }F‰j        |%j=        |%j$        fv r	‰j9        r|	s|Er|	nd}GˆÚˆÜfdf„}H|F|?_>        |G|?_?        |@j@        }IdgŠØ‰Ø|?_A        dg}Jdg}KdgŠßdgŠà|J|?_B        |K|?_C        ‰ß|?_D        ‰à|?_E        tW          j,        ¦   «         }L‰ jF        }M|L|?_G        |M|?_H        |@jI        |?_I        |@jJ        |?_J        ‰  !                    ‰¦  «        }N‰j)        }O‰j        |%j=        k    r‰j9        r|	r|D|	dgœŠÕn`|DrT|D‰j9        k    r‰  :                    ‰|	¦  «        n4‰  ;                    ‰j        ‰j)        |DtE          ‰dbd¦  «        |	¬c¦  «        ndŠÕ‰Õ€|Erdd|	iŠÕ|N|?_K        |O|?_L        ‰Õ|?_M        |@jN        |?_N        ‰  !                    ‰¦  «        }P|duo3t7          tE          |dh|¦  «        ¦  «         O                    ¦   «         dik    }Q|P�µ|Qr³|P P                    ‰j)        ¦  «        r™	 ddjlQmR}R ddklSmT}S  |S¦   «         }T‰ jU        ptW          jV        ¦   «         }U |R|P‰j)        |T|U‰Õ¬l¦  «        }V|VjW        r|V‰àd<   |V X                    ¦   «          n2# t(          $ r%}Wt²           Z                    dm|W¦  «         Y d}W~Wnd}W~Www xY w|@j[        ŠÞd}X|.rtW          j\         |I¦   «         ¦  «        }Xd}Y|)rtW          j\         |H¦   «         ¦  «        }Yd}Zˆßfdn„}[tW          j\         |[¦   «         ¦  «        }ZˆØˆˆ ˆfdo„}\tW          j\         |\¦   «         ¦  «        }]tW          j]        ¦   «         ŠÑˆÑˆØˆ ˆˆˆàfdp„}^tW          j\         |^¦   «         ¦  «        }_t½          dqdr¦  «        }`|`dk    r|`ndŠÇ |$dsdd¬t¦  «        ŠÒ‰Òd+k    rdŠÇt¿          j_        ¦   «         ŠÔˆÇˆÊˆËˆÌˆÎˆÒˆÔˆÕˆØˆÛˆÝˆ ˆˆˆáfdu„}atW          j\         |a¦   «         ¦  «        }bddvœdwt6          dxt
          dt
          fdy„}c	 t½          dzd{¦  «        }d|ddk    r|dnd}et½          d|d}¦  «        }f|fdk    r|fnd}gd}hdd~l`ma}i |pd}j|i b                    |j¦  «        }k|j|?_c        |k|?_d        tË          j]        ¦   «         Š×tË          j]        ¦   «         }ltË          jf        ¦   «         }m‰ŠÖ‰Ö�ˆÖˆ ˆfd€„nd�„ }nˆ×ˆØˆÞfd‚„}o|e�DtË          jg        tÐ          ‰Ø|j|k|e‰×|l|mdƒ|nd„œ	d…|jdd†…         › �d¬‡¦  «         X                    ¦   «          tW          ji        ‰  j                    |o¦  «        ¦  «        ŠÌd}pdƒ}q|e�€´d}r	 tW          jk        ‰Ìh|q¬ˆ¦  «        ƒ d{V —†\  }s}t|sr‰Ì l                    ¦   «         }r�nw‰Ñ m                    ¦   «         �s`‰�r]‰  !                    ‰¦  «        }u‰Ød         }v|u�r=|v�r:tO          |ud‰¦  «        �r)|u n                    ‰¦  «        �r|ujo                             ‰¦  «        }w|wr|wjp        nd}x|w�rtE          |wdŠd¦  «        pg }y‰  q                    |w¦  «        r7‰  r                    |w|u‰|xpdd‹‰j9        r	dŒ‰j9        ind¬�¦  «        ƒ d{V —†\  }x}tn|xs|yrtç          |w¦  «        }xt²           t                    dŽ‰|_ u                    ¦   «         rd�nd�¦  «         |v v                    |x¦  «         ‰Ñ                     ¦   «          ‰àd         }z|z�|z w                    d‘¦  «         �Œ¯�nd}r	 tW          jk        ‰Ìh|q¬ˆ¦  «        ƒ d{V —†\  }s}t|sr‰Ì l                    ¦   «         }r�nß|l m                    ¦   «         rd}p�nÇ‰Ød         }{d’}||{rLtO          |{d“¦  «        r<	 |{ x                    ¦   «         }}|}                     d”d’¦  «        }|n# t(          $ r Y nw xY w|hsª|g�¨|||gk    r¢d}h‰  !                    ‰¦  «        }~|~r‰t'          |gd•z  ¦  «        pd–}t'          |e|gz
  d•z  ¦  «        pd–}€	 |~ y                    ‰j)        d—|› d˜|€› d™�‰Õ¬š¦  «        ƒ d{V —† n2# t(          $ r%}�t²           Z                    d›|�¦  «         Y d}�~�nd}�~�ww xY w|||ek    rFd}ptË          jg        tô          ‰Ø|j|k‰×|l|m|ndœœd�|jdd†…         › �d¬‡¦  «         X                    ¦   «          �nw‰Ñ m                    ¦   «         �s`‰�r]‰  !                    ‰¦  «        }u‰Ød         }v|u�r=|v�r:tO          |ud‰¦  «        �r)|u n                    ‰¦  «        �r|ujo                             ‰¦  «        }w|wr|wjp        nd}x|w�rtE          |wdŠd¦  «        pg }y‰  q                    |w¦  «        r7‰  r                    |w|u‰|xpdd‹‰j9        r	dŒ‰j9        ind¬�¦  «        ƒ d{V —†\  }x}tn|xs|yrtç          |w¦  «        }xt²           t                    dŽ‰|_ u                    ¦   «         rd�nd�¦  «         |v v                    |x¦  «         ‰Ñ                     ¦   «          ‰àd         }z|z�|z w                    d‘¦  «         �Œ|p�rª‰Ød         }‚i }ƒ|‚r6tO          |‚d“¦  «        r&	 |‚ x                    ¦   «         }ƒn# t(          $ r Y nw xY w|ƒ                     dždŸ¦  «        }„|ƒ                     d”d¦  «        }…|ƒ                     d ¦  «        }†|ƒ                     d¡d¦  «        }‡|ƒ                     d¢d¦  «        }ˆt²           {                    d£|…|e‰|„|‡|ˆ|†pd¤¦  «         |‚rtù          |‚tú          ¦  «         t'          |ed•z  ¦  «        pd–}‰d¥|‰› d¦�g}Š|†r$|Š ~                    d§|†› d¨|…d©›dª|‡› d«|ˆ› d¬�	¦  «         n#|Š ~                    d­|„› d®|…d©›d¯|‡› d«|ˆ› d°�	¦  «         |Š ~                    d±¦  «         d²                     |Š¦  «        |Jd         r|Jd                              d³g ¦  «        ng |‡|Kd         pg ddd´œ}r‰Ød         }‹|Jd         }Œ|Œr|Œ                     dµ¦  «        nd}�|‹�›tO          |‹d¶¦  «        r‹|�s‰�t          ¦   «         }Ž	 dd·l�m‚}�mƒ}� tE          |‹d¸d¦  «        pd}‘|‘r|‘|�vr |�|Ž|‘¦  «        }Žn# t(          $ r Y nw xY w|‹j„        |Žk    r0‰  …                    ‰|‹j„        ¦  «        s‰  †                    ‰¦  «         |Jd         }’‰  !                    ‰¦  «        }“‰àd         }z|z�Ñ|z ‡                    ¦   «          	 |z ˆ                    d¹¬ˆ¦  «        ƒ d{V —† n2# t(          $ r%}”t²           Z                    dº|”¦  «         Y d}”~”nd}”~”ww xY w|zju        s1|z w                    d»¦  «         |z ˆ                    d¼¬ˆ¦  «        ƒ d{V —† |zj‰        r.|“�,tE          |“d½d¦  «        }•tk          |•¦  «        r |•‰‰¦  «         d}–d}—|’�rP|“�rM‰�rJ�t          |“‰¦  «        }–‰  ‹                    ‰|“|–¦  «        }–|’                     d¾¦  «        r^|–s\|’                     d¿¦  «        rG|’                     d¿¦  «        }˜�t          |˜¦  «        rt²           t                    dÀ‰pdÁ|˜¦  «         n²|˜}—n¯|–r­|–jp        pd}™tE          |–dŠd¦  «        pg }š‰  q                    |–¦  «        rF‰  r                    |–|“‰|™dÂ‰j9        r	dŒ‰j9        ind¬�¦  «        ƒ d{V —†\  }—}t|—stç          |–¦  «        }—n|™ptç          |–¦  «        }—|—r#t²           Z                    dÃ|—ddÄ…         ¦  «         |’r@|—s>|–s<|’                     dÅ¦  «        }›|›r%|›}—t²           Z                    dÆ|—ddÄ…         ¦  «         |—r¹|— �                    ¦   «          Ž                    d«¦  «        r’|— �                    ¦   «          �                    dd–¦  «        }œ|œr"|œd         d–d…          O                    ¦   «         nd}�|�rB	 ddÇl�m‘}ž  |ž|�¦  «        rt²           t                    dÈ|�¦  «         d}–d}—n# t(          $ r Y nw xY w‰ j’        r8|–s|—r4t²           t                    dÉ‰pdÁ‰  “                    ¦   «         ¦  «         d}–d}—|–s|—�rnt²           Z                    dÊ|—ddÄ…         ¦  «         |“r:tO          |“dË¦  «        r*‰r(‰|“j”        v r|“j”        ‰          •                    ¦   «          |‰ j–        k    �rTt²           —                    dÌ|‰¦  «         ‰  !                    ‰¦  «        }“|“r|–r�t1          |“jo        ‰|–¦  «         n(|“r&tO          |“dÍ¦  «        r|“ ™                    ‰|—¦  «         |Jd         p|r|dÎœ	 |Xr|X š                    ¦   «          |Yr|Y š                    ¦   «          |_ š                    ¦   «          |b š                    ¦   «          |Zr³‰ßo	‰ßd         du}Ÿ|Ÿs3|Z š                    ¦   «          	 |Zƒ d{V —† n‡# tV          j›        $ r Y nvw xY w	 tW          jœ        |Zdƒ¬ˆ¦  «        ƒ d{V —† nT# tV          j�        tV          j›        f$ r6 |Z š                    ¦   «          	 |Zƒ d{V —† n# tV          j›        $ r Y nw xY wY nw xY w‰àd         } | �J| ju        sC|  w                    dÏ¦  «         	 |  ˆ                    d¼¬ˆ¦  «        ƒ d{V —† n# t(          $ r Y nw xY w|] š                    ¦   «          ‰r‰  ž                    ‰‰¬Ð¦  «         ‰ j’        r‰  Ÿ                    dÑ¦  «         |X|Y|_|]|bfD ]#}¡|¡r	 |¡ƒ d{V —† Œ# tV          j›        $ r Y Œw xY wŒ$S |’                     d¾¦  «        }¢|¢�sî‰ßd         }£|£r¡|ZrŸ	 tW          jœ        |Zdƒ¬ˆ¦  «        ƒ d{V —† n�# tV          j�        tV          j›        f$ r6 |Z š                    ¦   «          	 |Zƒ d{V —† n# tV          j›        $ r Y nw xY wY n1t(          $ r%}¤t²           Z                    dÒ|¤¦  «         Y d}¤~¤nd}¤~¤ww xY wt          |rt          ¦  «        r|rn|’pi }¥t          |¥                     dÓ¦  «        ¦  «        }¦|¥                     dÔd¦  «        }§ |c|£|§|¦¬v¦  «        }¨	 ddÕl m¡}©  |©|¥|§¦  «        }ªn# t(          $ r d}ªY nw xY w|ªrt²           t                    dÖ‰pdÁ¦  «         n©|§r§	 |¨rt²           t                    d×‰pdÁ¦  «         nt²           t                    dØ‰pdÁ¦  «         ‰  ¢                    |§‰|“‰Õ|	|¨|¥                     dµ¦  «         ¬Ù¦  «        ƒ d{V —† n2# t(          $ r%}¤t²           —                    dÚ|¤¦  «         Y d}¤~¤nd}¤~¤ww xY wtE          t[          |“¦  «        dÛd¦  «        �`|“ £                    ‰‰¬Ü¦  «        }«tk          |«¦  «        r9	  |«¦   «         }¬�tI          j¥        |¬¦  «        r|¬ƒ d{V —† n†# t(          $ r Y nzw xY wnu|“rstO          |“dÝ¦  «        rc|“j¦         §                    ‰d¦  «        }«tk          |«¦  «        r9	  |«¦   «         }¬�tI          j¥        |¬¦  «        r|¬ƒ d{V —† n# t(          $ r Y nw xY w|’                     d³|¦  «        }­‰}®|—}¯d}°d}±‰}²d}³|–��¡tE          |–d5d¦  «        p‰}®‰  ¨                    |–¦  «        �r‰  ©                    |¦  «        �sðt²           t                    dÞ‰pdÁ¦  «         |’|Xr|X š                    ¦   «          |Yr|Y š                    ¦   «          |_ š                    ¦   «          |b š                    ¦   «          |Zr³‰ßo	‰ßd         du}Ÿ|Ÿs3|Z š                    ¦   «          	 |Zƒ d{V —† n‡# tV          j›        $ r Y nvw xY w	 tW          jœ        |Zdƒ¬ˆ¦  «        ƒ d{V —† nT# tV          j�        tV          j›        f$ r6 |Z š                    ¦   «          	 |Zƒ d{V —† n# tV          j›        $ r Y nw xY wY nw xY w‰àd         } | �J| ju        sC|  w                    dÏ¦  «         	 |  ˆ                    d¼¬ˆ¦  «        ƒ d{V —† n# t(          $ r Y nw xY w|] š                    ¦   «          ‰r‰  ž                    ‰‰¬Ð¦  «         ‰ j’        r‰  Ÿ                    dÑ¦  «         |X|Y|_|]|bfD ]#}¡|¡r	 |¡ƒ d{V —† Œ# tV          j›        $ r Y Œw xY wŒ$S 	 ‰  ª                    |®¦  «        }²n/# t(          $ r" t²           Z                    dß‰pdÁd¬à¦  «         Y nw xY w‰  «                    |–|®|­|²¬á¦  «        ƒ d{V —†}¯|¯�€Ó|’|Xr|X š                    ¦   «          |Yr|Y š                    ¦   «          |_ š                    ¦   «          |b š                    ¦   «          |Zr³‰ßo	‰ßd         du}Ÿ|Ÿs3|Z š                    ¦   «          	 |Zƒ d{V —† n‡# tV          j›        $ r Y nvw xY w	 tW          jœ        |Zdƒ¬ˆ¦  «        ƒ d{V —† nT# tV          j�        tV          j›        f$ r6 |Z š                    ¦   «          	 |Zƒ d{V —† n# tV          j›        $ r Y nw xY wY nw xY w‰àd         } | �J| ju        sC|  w                    dÏ¦  «         	 |  ˆ                    d¼¬ˆ¦  «        ƒ d{V —† n# t(          $ r Y nw xY w|] š                    ¦   «          ‰r‰  ž                    ‰‰¬Ð¦  «         ‰ j’        r‰  Ÿ                    dÑ¦  «         |X|Y|_|]|bfD ]#}¡|¡r	 |¡ƒ d{V —† Œ# tV          j›        $ r Y Œw xY wŒ$S ‰  ¬                    |–¦  «        }°tE          |–dTd¦  «        }±tE          |–dâd¦  «        }³‰  !                    ‰¦  «        }´|´�Z‰rX‰�VtE          |´dãd¦  «        }µ|µ�CtE          |´däd¦  «        }¶tk          |¶¦  «        r# |¶‰‰¦  «        }·|·r|µ ­                    |·¦  «         ‰  !                    ‰¦  «        }¸|¸r4	 |¸ ®                    ‰j)        ‰Õ¬š¦  «        ƒ d{V —† n# t(          $ r Y nw xY w‰  ¯                    ‰|¦  «        ƒ d{V —† ‰  °                    |¯||­|®||²‰|d–z   |°|±|³¬å¦  «        ƒ d{V —†}¹�tc          |’|¹¦  «        |Xr|X š                    ¦   «          |Yr|Y š                    ¦   «          |_ š                    ¦   «          |b š                    ¦   «          |Zr³‰ßo	‰ßd         du}Ÿ|Ÿs3|Z š                    ¦   «          	 |Zƒ d{V —† n‡# tV          j›        $ r Y nvw xY w	 tW          jœ        |Zdƒ¬ˆ¦  «        ƒ d{V —† nT# tV          j�        tV          j›        f$ r6 |Z š                    ¦   «          	 |Zƒ d{V —† n# tV          j›        $ r Y nw xY wY nw xY w‰àd         } | �J| ju        sC|  w                    dÏ¦  «         	 |  ˆ                    d¼¬ˆ¦  «        ƒ d{V —† n# t(          $ r Y nw xY w|] š                    ¦   «          ‰r‰  ž                    ‰‰¬Ð¦  «         ‰ j’        r‰  Ÿ                    dÑ¦  «         |X|Y|_|]|bfD ]#}¡|¡r	 |¡ƒ d{V —† Œ# tV          j›        $ r Y Œw xY wŒ$S 	 |Xr|X š                    ¦   «          |Yr|Y š                    ¦   «          |_ š                    ¦   «          |b š                    ¦   «          |Zr³‰ßo	‰ßd         du}Ÿ|Ÿs3|Z š                    ¦   «          	 |Zƒ d{V —† n‡# tV          j›        $ r Y nvw xY w	 tW          jœ        |Zdƒ¬ˆ¦  «        ƒ d{V —† nT# tV          j�        tV          j›        f$ r6 |Z š                    ¦   «          	 |Zƒ d{V —† n# tV          j›        $ r Y nw xY wY nw xY w‰àd         } | �J| ju        sC|  w                    dÏ¦  «         	 |  ˆ                    d¼¬ˆ¦  «        ƒ d{V —† n# t(          $ r Y nw xY w|] š                    ¦   «          ‰r‰  ž                    ‰‰¬Ð¦  «         ‰ j’        r‰  Ÿ                    dÑ¦  «         |X|Y|_|]|bfD ]#}¡|¡r	 |¡ƒ d{V —† Œ# tV          j›        $ r Y Œw xY wŒ$�nÖ# |Xr|X š                    ¦   «          |Yr|Y š                    ¦   «          |_ š                    ¦   «          |b š                    ¦   «          |Zr³‰ßo	‰ßd         du}Ÿ|Ÿs3|Z š                    ¦   «          	 |Zƒ d{V —† n‡# tV          j›        $ r Y nvw xY w	 tW          jœ        |Zdƒ¬ˆ¦  «        ƒ d{V —† nT# tV          j�        tV          j›        f$ r6 |Z š                    ¦   «          	 |Zƒ d{V —† n# tV          j›        $ r Y nw xY wY nw xY w‰àd         } | �J| ju        sC|  w                    dÏ¦  «         	 |  ˆ                    d¼¬ˆ¦  «        ƒ d{V —† n# t(          $ r Y nw xY w|] š                    ¦   «          ‰r‰  ž                    ‰‰¬Ð¦  «         ‰ j’        r‰  Ÿ                    dÑ¦  «         |X|Y|_|]|bfD ]#}¡|¡r	 |¡ƒ d{V —† Œ# tV          j›        $ r Y Œw xY wŒ$w xY w‰ßd         }£t          |rt          ¦  «        �ró|r                     dµ¦  «        �sÝ|r                     dÔ¦  «        pd}º|º p|ºdæk    }»t          |r                     dÓ¦  «        ¦  «        }¦t          |£otE          |£dçd¦  «        ¦  «        }¼d}½|¼rG|»sEtE          |£dèd¦  «        }¾tk          |¾¦  «        r!	  |¾|º¦  «        du }½n# t(          $ r d}½Y nw xY w|½rd}¼t          |r                     dé¦  «        ¦  «        }¿ |c|£|º|¦¬v¦  «        }À|»s-|¿s+|Às|¼r't²           t                    dê‰pdÁ|À|¦|¼¦  «         d|rdë<   �nÑ|»�s6|¿�s3|½�r0|£��-|£j²        }ÁtE          |£dìd¦  «        }ÂtE          |£díd¦  «        rt²           t                    dî‰pdÁ¦  «         �n}|ÁrÅ|Ádïk    r¿|Â�½	 |Â ³                    ‰j)        |Á|ºd¬ð¦  «        ƒ d{V —†}ÃtE          |Ãdñd¦  «        r$d|rdë<   t²           t                    dò‰pdÁ|Á¦  «         n-t²           —                    dó‰pdÁtE          |Ãdôd¦  «        ¦  «         në# t(          $ r(}Ät²           —                    dõ‰pdÁ|Ä¦  «         Y d}Ä~Än¾d}Ä~Äww xY wt²           t                    dö‰pdÁ¦  «         n˜|»s–|¿r”|£�’|£j²        }Á|Ár‰	 |£j´         ³                    ‰j)        |Á|rdÔ         d¬ð¦  «        ƒ d{V —† d|rdë<   t²           t                    d÷|Á‰pdÁ¦  «         n5# t(          $ r(}Ät²           —                    dø‰pdÁ|Ä¦  «         Y d}Ä~Änd}Ä~Äww xY w‰ËrÁ|;�¿‰Êr½‰r»t          |rt          ¦  «        r¦|r                     dµ¦  «        s‘tO          |;dù¦  «        r��tk          ‰Ê¦  «        ŠÐ‰j)        ŠÉ|;ŠÈtW          j,        ¦   «         ŠÓdýˆÈˆÉˆÐˆÓfdú„}Å	 |; ¶                    ‰|Å‰¬Ü¦  «         n2# t(          $ r%}Æt²           Z                    dû|Æ¦  «         Y d}Æ~Ænd}Æ~Æww xY w|rS )þaÉ  
        Run the agent with the given message and context.
        
        Returns the full result dict from run_conversation, including:
          - "final_response": str (the text to send back)
          - "messages": list (full conversation including tool calls)
          - "api_calls": int
          - "completed": bool
        
        This is run in a thread pool to not block the event loop.
        Supports interruption via new messages.
        )r$  r‹  rÙ  r(  rN   r+   r¼  r:  Nr   r8  r-   c                  ó<   •— ‰ �‰sdS ‰                      ‰‰ ¦  «        S r¹  rø  r“  s   €€€r>   r3  z:GatewayRunner._run_agent_inner.<locals>._run_still_currentb  r”  rM   r'  rµ   r  rD  rR  )Úset_tool_preview_max_lenÚtool_preview_length)Úset_friendly_tool_labelsÚfriendly_tool_labelsTÚtool_progressÚHERMES_TOOL_PROGRESS_MODErE  Útool_progress_overridesr�  Útool_progress_groupingÚ
accumulate)Úchoose_status_phraseÚresolve_status_phrase_catalogF)rJ  rK  Úallow_genericrB  rJ  rK  rÃ  c                óB  •— |r7t          ‰	j        ¦  «        }d„ |D ¦   «         }||v rt          ‰
‰| ¦  «        sdS  ‰‰
‰| |¦  «        }t          |t          ¦  «        r0|                     ¦   «                              ¦   «         dk    r|rdndS t          |¦  «        rdndS )z8Return off|raw|generic for a gateway visibility surface.c                 ó,   — h | ]}t          |¦  «        ’ŒS rN  rO  )rb   Úitems     r>   rQ  zPGatewayRunner._run_agent_inner.<locals>._display_surface_mode.<locals>.<setcomp>Qb  s0   € ð !ð !ð !àõ ,¨DÑ1Ô1ð!ð !ð !rM   r  Úgenericrx  )rƒ   r�   rH  rt   rw   rx   ry   rº   )rB  rJ  rK  rÃ  rU  rV  r­   r?  rS  r(  rA  s          €€€€r>   Ú_display_surface_modez=GatewayRunner._run_agent_inner.<locals>._display_surface_modeGb  sÏ   ø€ ð -ð 
!Ý#:¸6¼?Ñ#KÔ#KÐ ð!ð !à =ð!ñ !ô !�ð
 %¨Ð5Ð5Ý:¸;ÈÐV]Ñ^Ô^ð 6ð !˜5Ø+Ð+¨K¸ÀwÐPWÑXÔXˆEÝ˜%¥Ñ%Ô%ð =¨%¯+ª+©-¬-×*=Ò*=Ñ*?Ô*?À9Ò*LÐ*LØ$1Ð<�y�y°uÐ<Ý  ™KœKÐ2�5�5¨UÐ2rM   )r?  r  r¸  rd  r?  r  r¸  c                óœ   •— 	  ‰| |||‰‰¬¦  «        S # t           $ r-}t                               d|¦  «         | dv rdndcY d }~S d }~ww xY w)N)r?  r  r¸  rÈ  Úcatalogz*generic status phrase selection failed: %s>   r5  Úwaitingr;  Úlong_runningzstill on itzone sec)r2   r3   r4   )rd  r?  r  r¸  Ú_phrase_errÚ_generic_status_catalogÚ_generic_status_recentrÁ  s        €€€r>   Ú_generic_status_phrasez>GatewayRunner._run_agent_inner.<locals>._generic_status_phrase_b  s”   ø€ ðrØ+Ð+ØØ'Ø#ØØ1Ø3ðñ ô ð øõ ð rð rð rÝ—’ÐIÈ;ÑWÔWÐWØ(,Ð0bÐ(bÐ(b�}�}ÐhqÐqÐqÐqÐqÐqÐqøøøøðrøøøs   ƒ ”
Až"AÁ AÁAr	  >   Úlogr  Úlive_statusr  Úsupports_status_textr  rÑ  Úinterim_assistant_messages)rJ  rK  r¾  r´  Úvoice_mixer_activeÚcleanup_progressÚdelete_messager%   r(  r3  r1  r2  r=  r;  r�  r>  r8  r6  rD  r?  rA  rE  r9  r:  r{  r|  r$  r¨  rS  rA  r  r¬  r•  r«  r®  r¯  r²  rÙ  r‹  r´  rN   r+   r¼  r¡  r:  ru  rt  rv  Ú_effective_reply_in_threadr8  r7  rT  rV  r´  rÏ  r5
  r…   c               “   óT  •K  — ‰€dS ddl m}  ddlm} t          dz  }|                     dd¬¦  «          | |dz  d	d
d¬¦  «        }|                      |d¦  «        ¦  «         t          j        dt          ‰¦  «        › �¦  «        }| 
                    t          j        ¦  «         d|_        |                     |¦  «         	 	 	 |                     d‰                     ¦   «         ¦  «         nq# ‰j        $ r t#          j        d¦  «        ƒ d{V —† Y nKt&          $ r?}t(                               d|¦  «         t#          j        d¦  «        ƒ d{V —† Y d}~nd}~ww xY wŒœ# t"          j        $ r Y nw xY w	 	 	 |                     d‰                     ¦   «         ¦  «         n# ‰j        $ r Y nt&          $ r Y nw xY wŒF|                     |¦  «         	 |                     ¦   «          |                     ¦   «          dS # t&          $ r Y dS w xY w# 	 	 |                     d‰                     ¦   «         ¦  «         n# ‰j        $ r Y nt&          $ r Y nw xY wŒF|                     |¦  «         	 |                     ¦   «          |                     ¦   «          w # t&          $ r Y w w xY wxY w)uH  Drain log_queue and append tool-call lines to tool_calls.log.

            Only active when ``display.tool_progress`` is ``log``. Uses a
            RotatingFileHandler (5MB Ã— 3 backups) so the audit log can't grow
            unbounded, and the shared RedactingFormatter so secrets never land
            on disk.
            Nr   )ÚRotatingFileHandler©ÚRedactingFormatterr  Trñ  ztool_calls.logi  P r)   rQ  )ÚmaxBytesÚbackupCountrR  z%(message)szhermes.tool_calls.Fr)  rŒ  zwrite_tool_log error: %sr(   )Úlogging.handlersrÚ  ró   rÜ  rl  rõ  ÚsetFormatterrS  rT  rÍ   ÚsetLevelÚINFOÚ	propagateÚ
addHandlerrz  rÎ  rš  r  r–  r2   r3   rP   r›  ÚremoveHandlerÚflushrk
  )rÚ  rÜ  r  Úfile_handlerÚtool_loggerr¨  r6  r™  s         €€r>   Úwrite_tool_logz6GatewayRunner._run_agent_inner.<locals>.write_tool_logac  s�  øè è € ð Ð Ø�Ø<Ð<Ð<Ð<Ð<Ð<à7Ð7Ð7Ð7Ð7Ð7å" VÑ+ˆGØ�MŠM $°ˆMÑ6Ô6Ð6Ø.Ð.ØÐ*Ñ*Ø(ØØ ð	ñ ô ˆLð ×%Ò%Ð&8Ð&8¸Ñ&GÔ&GÑHÔHÐHÝ!Ô+Ð,PÅÀIÁÄÐ,PÐ,PÑQÔQˆKØ× Ò ¥¤Ñ.Ô.Ð.Ø$)ˆKÔ!Ø×"Ò" <Ñ0Ô0Ð0ðð/ð/Ø#×(Ò(¨¨y×/CÒ/CÑ/EÔ/EÑFÔFÐFÐFøØ œ;ð 1ð 1ð 1Ý%œm¨CÑ0Ô0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ð0Ý$ð /ð /ð /ÝŸšÐ%?ÀÑCÔCÐCÝ%œm¨AÑ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.Ð.Ð.Ð.Ð.Ð.øøøøð/øøøð/øõ Ô)ð ð ð Ø�ðøøøØððØ#×(Ò(¨¨y×/CÒ/CÑ/EÔ/EÑFÔFÐFÐFøØ œ;ð ð ð Ø˜Ý$ð ð ð Ø˜ðøøøðð ×)Ò)¨,Ñ7Ô7Ð7ðØ ×&Ò&Ñ(Ô(Ð(Ø ×&Ò&Ñ(Ô(Ð(Ð(Ð(øÝ ð ð ð Ø�D�DðøøøøððØ#×(Ò(¨¨y×/CÒ/CÑ/EÔ/EÑFÔFÐFÐFøØ œ;ð ð ð Ø˜Ý$ð ð ð Ø˜ðøøøðð ×)Ò)¨,Ñ7Ô7Ð7ðØ ×&Ò&Ñ(Ô(Ð(Ø ×&Ò&Ñ(Ô(Ð(Ð(øÝ ð ð ð Ø�DðøøøøøøsØ   ÃE" Ã(C0 Ã/E" Ã0$EÄE" Ä	EÄ5EÅE" ÅEÅE" Å"E4Å1H Å3E4Å4H Å:(F# Æ#
F;Æ/	F;Æ:F;Ç(G? Ç?
HÈHÈJ'È(H<È;J'È<
IÉJ'É	IÉJ'ÉIÉJ'É.(JÊJ'Ê
J$Ê!J'Ê#J$Ê$J')r›  r5
  r­   r  )ÚStreamingTTSConsumer)Ú_load_tts_config)r1  r2  Ú
tts_configrØ   r¯   z+Could not set up streaming TTS consumer: %sc               “   óº   •K  — t          d¦  «        D ]G} ‰d         �#‰d                              ¦   «         ƒ d{V —†  dS t          j        d¦  «        ƒ d{V —† ŒHdS )z8Wait for the stream consumer to be created, then run it.r  r   Nr¦  )r  r®
  r  r–  )rK  rP  s    €r>   Ú_start_stream_consumerz>GatewayRunner._run_agent_inner.<locals>._start_stream_consumer$d  s†   øè è € å˜3‘Z”Zð *ð *�Ø)¨!Ô,Ð8Ø0°Ô3×7Ò7Ñ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9Ð9Ø�F�FÝ”m DÑ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ð)ð	*ð *rM   c               “   ó^  •K  — ‰ d         €"t          j        d¦  «        ƒ d {V —† ‰ d         ®"‰sd S ‰�6‰                     ‰‰¦  «        s t                               d‰pd‰¦  «         d S ‰ d         ‰                     ‰¦  «        j        _        ‰j        r‰ 	                    d¦  «         d S d S )Nr   r¦  uL   Skipping stale agent promotion for %s â€” generation %s is no longer currentr®   r	  )
r  r–  r”  r3   rz  r/   rJ  rµ   r*  r	  )r:  r¼  r  r+   s   €€€€r>   Útrack_agentz3GatewayRunner._run_agent_inner.<locals>.track_agent0d  sæ   øè è € à˜q”/Ð)Ý”m DÑ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)ð ˜q”/Ð)àð Ø�ð
 Ð)°$×2NÒ2NØ˜^ñ3ô 3Ð)õ —’ØbØÐ% 2Ø"ñô ð ð
 �Ø:FÀq¼/ˆD×Ò Ñ,Ô,Ô1Ô7ØŒ~ð 8Ø×+Ò+¨JÑ7Ô7Ð7Ð7Ð7ð8ð 8rM   c            	   “   óX  •K  — ‰sd S 	 t          j        d¦  «        ƒ d {V —† 	 ‰
                     ‰¦  «        } | sŒ4t          | d¦  «        �r|                      ‰¦  «        �r‰	d         }|rû| j                             ‰¦  «        }d }|�y|j        pd}t          |dd ¦  «        pg }‰
 	                    |¦  «        r5‰
 
                    || ‰|d‰j        r	d‰j        ind ¬	¦  «        ƒ d {V —†\  }}n|s|rt          |¦  «        }t                               d
¦  «         |                     |¦  «         ‰                     ¦   «          ‰d         }|�|                     d¦  «         d S nA# t           j        $ r ‚ t&          $ r%}t                               d|¦  «         Y d }~nd }~ww xY w�Œ£)NTgš™™™™™É?Úhas_pending_interruptr   r®   rì  zVoice-interruptr›  ©rÅ	  r¯   z3Interrupt detected from adapter, signaling agent...úbarge-inz,monitor_for_interrupt error (will retry): %s)r  r–  r@  rá   rò  r<  rv   rè   rV   rÆ	  rÇ	  r›  rð  r3   r4   r$  r•   Úabortr›  r2   )r³  rµ   Ú_peek_eventÚpending_textr
  rK  Ú_sttsÚ_mon_errÚ_interrupt_detectedr:  r  r+   r(  r“  s           €€€€€€r>   Úmonitor_for_interruptz=GatewayRunner._run_agent_inner.<locals>.monitor_for_interruptQd  sL  øè è € Øð Ø�ð8[Ý”m CÑ(Ô(Ð(Ð(Ð(Ð(Ð(Ð(Ð(ð6[ð  $×7Ò7¸Ñ?Ô?�HØ#ð !Ø õ
 ˜xÐ)@ÑAÔAñ ("Àh×FdÒFdÐepÑFqÔFqñ ("Ø ,¨Q¤˜Ø ð &"ð +3Ô*D×*HÒ*HÈÑ*UÔ*U˜KØ+/˜LØ*Ð6Ø/:Ô/?Ð/EÀ2 õ /6°kÀ<ÐQUÑ.VÔ.VÐ.\ÐZ\ Ø#'×#BÒ#BÀ;Ñ#OÔ#Oð 
!YØ<@×<cÒ<cØ(3Ø(0Ø(.Ø(4Ø4EØTZÔTdÐ1n°+¸vÔ?OÐ1PÐ1PÐjnð =dñ =&ô =&ð 7&ð 7&ð 7&ð 7&ð 7&ð 7&¡O L°!°!ð *6ð !Y¸+ð !YÝ3KÈKÑ3XÔ3X LÝ"ŸLšLÐ)^Ñ_Ô_Ð_Ø!ŸOšO¨LÑ9Ô9Ð9Ø/×3Ò3Ñ5Ô5Ð5à$AÀ!Ô$D˜EØ$Ð0Ø %§¢¨JÑ 7Ô 7Ð 7Ø!˜EøøÝÔ-ð ð ð ØÝ ð [ð [ð [Ý—L’LÐ!OÐQYÑZÔZÐZÐZÐZÐZÐZÐZøøøøð[øøøño8[s   ¤E) ¼D*E) Å)F'ÆF"Æ"F'r  é´   Úlong_running_notifications)rJ  rÃ  c               “   ó–  •K  — ‰€d S ‰                      ‰¦  «        } | sd S d }	 t          j        ‰¦  «        ƒ d {V —† 	 ‰}n# t          $ r d }Y nw xY w‰                     ‰‰d         |¦  «        sd S t          t          j        ¦   «         ‰z
  dz  ¦  «        }‰d         }d}t           ‰‰‰dd¦  «        ¦  «        }|rÉt          |d¦  «        r¹	 | 	                    ¦   «         }g }|r'| 
                    d|d         › d	|d
         › �¦  «         |                     d¦  «        p|                     d¦  «        }	|	r"| 
                    t          |	¦  «        ¦  «         |rdd                     |¦  «        z   }n# t          $ r Y nw xY w‰dk    r ‰d¦  «        nd|› d|› �}
	 d }|rX	 |                      ‰j        ||
¦  «        ƒ d {V —†}n4# t          $ r'}t"                               d|¦  «         d }Y d }~nd }~ww xY w|rt'          |dd¦  «        s„|                      ‰j        |
t+          ‰‰j        ¬¦  «        ¬¦  «        ƒ d {V —†}t'          |dd¦  «        r<t'          |dd ¦  «        r+t          |j        ¦  «        }‰r‰ 
                    |¦  «         n2# t          $ r%}t"                               d|¦  «         Y d }~nd }~ww xY w�Œ§)NTr   rø  r®   ræ	  r>  ré	  rç	  r]  r  rè	  r@  r2
  r  rÇ  r5  u   â�³ Working â€” z minzHeartbeat edit failed: %sr/  Fr…   r.  rj  z#Long-running notification error: %s)r@  r  r–  Ú	NameErrorrZ
  rh  rU   rº   rá   r>  r”   rv   rw   rf   r2   r^  r2  r3   r4   rV   r0  r´   r�   rj  )Ú_notify_adapterÚ_heartbeat_msg_idÚ	_exec_refÚ_elapsed_minsÚ
_agent_refÚ_status_detailÚ_want_iteration_detailrm  r
  r-  Ú_heartbeat_textÚ_notify_resÚ_eeÚ_neÚ_NOTIFY_INTERVALr|  r{  Ú_executor_taskrÐ  Ú_long_running_modeÚ_notify_startrã  r:  r?  rS  r  r+   r(  rA  s                 €€€€€€€€€€€€€€€r>   Ú_notify_long_runningz<GatewayRunner._run_agent_inner.<locals>._notify_long_running¡d  s  øè è € ØÐ'Ø�Ø"×6Ò6°vÑ>Ô>ˆOØ"ð Ø�ð 04ÐðLMÝ”mÐ$4Ñ5Ô5Ð5Ð5Ð5Ð5Ð5Ð5Ð5ð%Ø .�I�IøÝ ð %ð %ð %Ø $�I�I�Ið%øøøà×BÒBØ ¨a¤°)ñô ð ð �EÝ #¥T¤Y¡[¤[°=Ñ%@ÀRÑ$GÑ HÔ H�ð
 *¨!œ_�
Ø!#�Ý)-Ø+Ð+Ø#Ø$Ø)Øñ	ô ñ*ô *Ð&ð ð ¥'¨*Ð6LÑ"MÔ"Mð ðØ'×<Ò<Ñ>Ô>˜Ø!#˜Ø1ð Ø"ŸMšMØ Z¨RÐ0@Ô-AÐ ZÐ ZÀBÐGWÔDXÐ ZÐ Zñô ð ð #%§&¢&¨Ñ"8Ô"8Ð"X¸B¿FºFÐCWÑ<XÔ<X˜Ø"ð 8Ø"ŸMšM­#¨g©,¬,Ñ7Ô7Ð7Ø!ð IØ-4°t·y²yÀÑ7HÔ7HÑ-H˜NøøÝ$ð ð ð Ø˜ðøøøð *¨YÒ6Ð6ð +Ð*¨8Ñ4Ô4Ð4àO¨MÐOÐO¸~ÐOÐOð  ð
MØ"&�KØ(ð 	/ð/Ø0?×0LÒ0LØ &¤Ø 1Ø /ñ1ô 1ð +ð +ð +ð +ð +ð +˜K˜Køõ
  )ð /ð /ð /Ý"ŸLšLÐ)DÀcÑJÔJÐJØ*.˜K˜K˜K˜K˜K˜Køøøøð/øøøð (ð K­G°KÀÈEÑ,RÔ,Rð KØ,;×,@Ò,@Ø"œNØ+Ý%AÐBYÐdjÔdsÐ%tÑ%tÔ%tð -Añ -ô -ð 'ð 'ð 'ð 'ð 'ð '˜õ
 # ;°	¸5ÑAÔAð KÅgØ'¨°tñGô Gð Kõ 14°KÔ4JÑ0KÔ0KÐ-Ø0ð KØ 0× 7Ò 7Ð8IÑ JÔ JÐ JøøÝ ð Mð Mð MÝ—L’LÐ!FÈÑLÔLÐLÐLÐLÐLÐLÐLøøøøðMøøøñWLMsg   ¿A ÁAÁAÃB'E9 Å9
FÆFÆ#J Æ("G Ç
J Ç
G<ÇG7Ç2J Ç7G<Ç<BJ Ê
KÊ!KËK)Ú	previewedÚ
final_textr  c                óN  — | €dS t          | dd¦  «        rCt          | dd¦  «        }t          |¦  «        r!	  ||¦  «        du rdS n# t          $ r Y nw xY wdS |rJt          | dd¦  «        }t          |¦  «        r*	 t           ||¦  «        ¦  «        S # t          $ r Y dS w xY wdS )z>Return True only when the actual final reply reached the user.NFÚfinal_response_sentÚdelivered_final_matchesTÚhas_delivered_text)rV   r/  r2   rº   )Úconsumerr  r  Úmatcherr  s        r>   Ú _stream_confirmed_final_deliveryzHGatewayRunner._run_agent_inner.<locals>._stream_confirmed_final_deliveryýd  s  € ð ÐØ�uÝ�xÐ!6¸Ñ>Ô>ð õ " (Ð,EÀtÑLÔL�Ý˜GÑ$Ô$ð ðØ"˜7 :Ñ.Ô.°%Ð7Ð7Ø#( 5ð 8øå$ð ð ð Ø˜ðøøøà�tØð %Ý%,¨XÐ7KÈTÑ%RÔ%RÐ"ÝÐ.Ñ/Ô/ð %ð%Ý#Ð$6Ð$6°zÑ$BÔ$BÑCÔCÐCøÝ$ð %ð %ð %Ø$˜u˜uð%øøøà�5s#   ·A Á
AÁAÁ<B Â
B"Â!B"r  r  r  i„  r*  r®   c                  ó0   •— ‰                      ‰‰ ¦  «        S r^   rø  )Ú_turn_run_generationr  r+   s   €€€r>   rò   z0GatewayRunner._run_agent_inner.<locals>.<lambda>He  s   ø€ ˜×5Ò5°kÐCWÑXÔX€ rM   c                  ó   — dS r¹  rN  rN  rM   r>   rò   z0GatewayRunner._run_agent_inner.<locals>.<lambda>Je  s   € ˜d€ rM   c                  ó  •— 	  ‰¦   «         ‰                      ¦   «          ‰r‰d         nd } | �d| _        t          ¦   «         | _        S S # ‰                      ¦   «          ‰r‰d         nd } | �d| _        t          ¦   «         | _        w xY w)Nr   r®   )r•   rÀ  Ú	frozensetrÁ  )Ú_finished_agentÚ_turn_worker_doner:  r!  s    €€€r>   Ú _run_sync_with_timeout_lifecyclezHGatewayRunner._run_agent_inner.<locals>._run_sync_with_timeout_lifecycleMe  s«   ø€ ðUØ#˜8™:œ:à%×)Ò)Ñ+Ô+Ð+ð :FÐ&O l°1¤o oÈ4�OØ&Ð2ØHJ˜ÔEÝIRÉÌ˜ÔFÐFð 3øð &×)Ò)Ñ+Ô+Ð+ð :FÐ&O l°1¤o oÈ4�OØ&Ð2ØHJ˜ÔEÝIRÉÌ˜ÔFÐTÐTÐTÐTs   ƒ	A
 Á
>Br&   )	r:  r'  r/  rÓ  r2  r3  r4  r<  r&  zgateway-turn-watchdog-rÌ   )r  rF  rÖ   r  r  rò  rì  zVoice-backup-interruptr›  ró  zABackup interrupt detected for session %s (monitor task state: %s)r  r	  rô  r@  r>  r?  rø  r(   u   âš ï¸� No activity for zB min. If the agent does not respond soon, it will be timed out in z- min. You can continue waiting or use /reset.r.  z!Inactivity warning send error: %srA  rú  r@  r¼  rè	  rç	  r  zaAgent idle for %.0fs (timeout %.0fs) in session %s | last_activity=%s | iteration=%s/%s | tool=%srô  u   â�±ï¸� Agent inactive for u(    min â€” no tool calls or API responses.z!The agent appears stuck on tool `z` (r¥  z!s since last activity, iteration r]  z).zLast activity: rê	  zs ago, iteration z6). The agent may have been waiting on an API response.z¢To increase the limit, set agent.gateway_timeout in config.yaml (value in seconds, 0 = no limit) and restart the gateway.
Try again, or use /reset to start fresh.r  r(  )rò  r(  rç  r»  r)  rÚ  rÚ  r  )Ú_AGGREGATOR_PROVIDERSÚnormalize_model_for_providerr  g      $@z%streaming TTS wait_complete error: %sz"streaming TTS finalisation timeoutr¥  Ú"_mark_streaming_tts_completed_turnrè  r€  z5Ignoring control interrupt message for session %s: %sr¿  zVoice-drainz9Processing queued message after agent completion: '%s...'r&  Úpending_steerz0Delivering leftover /steer as next turn: '%s...'r—  uZ   Discarding command '/%s' from pending queue â€” commands must not be passed as agent inputz=Discarding pending follow-up for session %s during gateway %sz#Processing pending message: '%s...'r˜  u^   Interrupt recursion depth %d reached for session %s â€” queueing message instead of recursing.Úqueue_message)rò  r(  r  râ  r	  z5Stream consumer wait before queued message failed: %sr‡  rò  rV  zZQueued follow-up for session %s: suppressing intentional silence marker before continuing.zlQueued follow-up for session %s: final text delivery confirmed; delivering explicit media before continuing.zoQueued follow-up for session %s: final stream delivery not confirmed; sending first response before continuing.)r(  r1  r¯   r:  r  r  z7Failed to send first response before queued message: %srU  r>  r@  uN   Discarding stale goal continuation for session %s â€” goal is no longer activez:Queued follow-up session-key resolution failed; reusing %srß   rþ  rÚ  Ú_streaming_tts_completed_turnsÚ_streaming_tts_turn_key)r$  r‹  rÙ  r(  rN   r+   r¼  r¡  r:  r´  rÚ  rX  Úfinal_content_deliveredr  rˆ  zSuppressing normal final send for session %s: final delivery already confirmed (streamed=%s previewed=%s content_delivered=%s).rd  r1  Ú_turn_split_deliveryz¸Stale streamed finalize detected for session %s on a multi-message split; skipping the in-place reconciliation edit and delivering the complete response via normal final send (#78541).Ú__no_edit__)r2  rj  r4  rm  r/  ziReconciled stale streamed finalize for session %s: edited message %s with the complete response (#71643).zoStale-finalize reconciliation edit failed for session %s (%s); sending complete response via normal final send.rP   znStale-finalize reconciliation edit failed for session %s: %s; sending complete response via normal final send.z†Stale streamed finalize detected for session %s with no editable message; delivering complete response via normal final send (#71643).zPEdited streamed message %s for session %s to include plugin-transformed content.z2Failed to edit streamed message for session %s: %sr=  c                  ó|   •— dˆˆˆfd„} 	 t           | ¦   «         ‰t          d¬¦  «         d S # t          $ r Y d S w xY w)Nr-   c               “   óp   •K  — ‰D ]/} 	 ‰                      ‰| ¦  «        ƒ d {V —† Œ # t          $ r Y Œ,w xY wd S r^   )r×  r2   )Ú_midÚ_adapter_snapshotÚ_chat_id_snapshotÚ_ids_snapshots    €€€r>   Ú_delete_allzRGatewayRunner._run_agent_inner.<locals>._cleanup_temp_bubbles.<locals>._delete_all°h  s‡   øè è € Ø -ð !ð !˜ð!Ø"3×"BÒ"BØ 1°4ñ#ô #ð ð ð ð ð ð ð ð øõ  )ð !ð !ð !Ø ˜Dð!øøøð!ð !s   ‰&¦
3²3z$Temp bubble cleanup scheduling errorr¬  rŽ  )r   r3   r2   )r1  r.  r/  r0  Ú_loop_snapshots    €€€€r>   Ú_cleanup_temp_bubblesz=GatewayRunner._run_agent_inner.<locals>._cleanup_temp_bubbles¯h  s†   ø€ ð!ð !ð !ð !ð !ð !ð !ð !ðÝ,Ø#˜™œ ~Ý%Ø$Jðñ ô ð ð ð øõ
 !ð ð ð Ø�D�Dðøøøs   ‹ - ­
;º;z-Post-delivery cleanup registration failed: %srN  rŽ  )·r{  r¨  r	  r¨  r™  rº   rs   ru  r�   r-  r(  r  rv   rt   ru   rT  rS  r4  r¸  rh  r2   rº  r’   rÆ  Úgateway.status_phrasesrÁ  rÂ  rw   r•   r   rÆ  rÄ  rÓ  r@  rV   ÚQueuer–  r±  r°  rá   rñ  r2  rÕ  r  r!
  rÎ   rG  r×  rp  r  r\  rµ  rÅ  r/  rz   rÁ  r@  r›  rî	  r<
  r´   ÚFEISHUrn  r�  r©  r:  rÉ  rÂ  rP  r“  r¸  r¾  r¼  rÁ  rÅ  rá  râ  rã  rç  ry   rÙ  Úgateway.streaming_tts_consumerrê  rð  rë  r“  Úget_event_looprö  r§  r3   r4   r!  r”  r¹  r„  rU   r-  r+  Úsnapshot_running_idsr¿  r/  r¤  rº  r¥  rE  r  rc
  rB  r·  r8  rò  r<  rè   rÆ	  rÇ	  rð  rz  r  r$  rõ  r>  r0  r;  rP   r   r9  r”   rf   r™  Úhermes_cli.model_normalizer!  r"  r  rá  rû  rÊ  Úwait_completeÚsuppress_whole_filer%  r%	  rI  rx   r!  re   r`  r˜  r*  r	  r˜  r4  Ú_MAX_INTERRUPT_DEPTHrã   rw  r%  r  r›  r  r,  rÌ
  r	  r•  rW  r"  rU  re  Úisawaitabler@  rU  r*	  r4	  rA  r   ru  rü  r˜  r�  r“  rü  rj  r^  r1  r½  r=  )âr  r$  r‹  rÙ  r(  rN   r+   r¼  r¡  r:  r´  ru  rt  rv  rÚ  r¨  r3  r(  r  Úagent_cfg_localr  Údisplay_configr¸  Ú_tplrº  Ú_ftlÚ_resolved_tpÚ_env_tpÚ_display_cfgÚ_platforms_cfgÚ_platform_cfgÚ_legacy_tp_overridesÚ_tool_progress_configuredr;  r�  rÂ  rÈ  rÄ  r>  r2  r1  r¬  Úinterim_assistant_messages_moder•  Ú_thinking_moder=  r«  r8  r?  rD  rE  rA  r®  r¯  Ú_vaÚ_vtcÚ_gidÚ_tcr²  Ú_cleanup_adapterÚ_cleanup_deleter9  r:  Úturn_ctxÚturn_runnerÚ_progress_reply_in_threadÚ_slack_adapter_for_progressÚ_mode_fnÚ_progress_thread_idÚ_relay_prospective_thread_idrn  r�  ré  r©  rÉ  rÂ  r¾  r¼  rá  râ  r4  Ú_is_voice_inputrê  rë  Ú_tts_cfgr“  Ú_stts_consumerÚ	_stts_errÚprogress_taskÚlog_taskr¡  rî  rð  Útracking_taskrû  Úinterrupt_monitorÚ_NOTIFY_INTERVAL_RAWr  Ú_notify_taskr  Ú_agent_timeout_rawÚ_agent_timeoutÚ_agent_warning_rawÚ_agent_warningÚ_warning_firedr+  Ú_turn_task_idÚ_turn_process_baselineÚ_turn_timeout_firedÚ_turn_cleanup_lockÚ_turn_is_currentr   Ú_inactivity_timeoutÚ_POLL_INTERVALrJ  r  rK  Ú_backup_adapterÚ_backup_agentÚ	_bp_eventÚ_bp_textÚ_bp_media_urlsrø  r  Ú
_idle_secsÚ_actÚ_warn_adapterÚ_elapsed_warnÚ_remaining_minsÚ	_warn_errÚ_timed_out_agentÚ	_activityÚ
_last_descÚ	_secs_agoÚ	_cur_toolÚ_iter_nÚ	_iter_maxÚ_timeout_minsÚ_diag_linesr  Ú_result_for_fbÚ_run_failedÚ
_cfg_modelr!  r"  Ú_agent_providerr·  r1  Ú_stts_done_errÚ
_mark_turnr 	  r5  r€  r§  r
  Ú_leftover_steerÚ_pending_partsÚ_pending_cmd_wordÚ_rc_pendingÚ_has_stream_consumerÚ_stts_finallyrÝ   Úwas_interruptedrW  r¨  Ú_delivery_resultÚ
_previewedÚfirst_responseÚ_already_streamedrW  r  Ú_bg_cbÚ
_bg_resultÚupdated_historyÚnext_sourceÚnext_messageÚnext_message_idÚnext_channel_promptÚnext_session_keyÚnext_message_typeÚ_clear_adapterÚ_completed_turnsÚ
_prior_keyÚ_pkÚ_followup_adapterrø  Ú_finalÚ_is_empty_sentinelÚ_content_deliveredÚ_stale_finalizedÚ_matcherÚ_transformedÚ	_streamedÚ
_sc_msg_idÚ_sc_adapterÚ_reconcile_resÚ	_edit_errr3  Ú_rper  r.  r/  r|  r{  r  rÎ  rÐ  rÏ  r0  rú  r  r2  r  rã  r  r  r:  rÁ  r6  r?  r™  rS  r!  rP  r“  rA  sâ   `   ` ``                                                                                                                                                                                               @@@@@@@@@@@@@@@@@@@@@@@@@@@r>   rª  zGatewayRunner._run_agent_inner×a  sqC  øøøøøøøøøøøøøøøøøøøøøøøøøøøøøøøè è € ð< ×ÒÑ Ô ð 
	Ø×2Ò2ØØ-ØØØ%Ø'Ø-Ø!1ð 3ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	&Ð%Ð%Ð%Ð%Ð%Øˆˆˆð	M¥Dð 	Mð 	Mð 	Mð 	Mð 	Mð 	Mð 	Mð 	Mõ
 +Ñ,Ô,ˆÝ+¨F¬OÑ<Ô<ˆà?Ð?Ð?Ð?Ð?Ð?Ý!Ð"5Ð"5°kÀ<Ñ"PÔ"PÑQÔQÐØ%Ÿ/š/¨'Ñ2Ô2Ð8°bˆØ+×/Ò/Ð0CÑDÔDÐLÈÐà$Ÿš¨°BÑ7Ô7ˆÝ˜.­$Ñ/Ô/ð 	 ØˆNð
 	CÐBÐBÐBÐBÐBð	Ø>Ð>Ð>Ð>Ð>Ð>Ø*Ð*¨;¸ÐF[Ð]^Ñ_Ô_ˆDØ$Ð$°$Ð%=¥S¨¡Y¤Y Y¸AÑ>Ô>Ð>Ð>øÝð 	ð 	ð 	ØˆDð	øøøð	Ø>Ð>Ð>Ð>Ð>Ð>Ø*Ð*¨;¸ÐF\Ð^bÑcÔcˆDØ$Ð$¥T¨$¡Z¤ZÑ0Ô0Ð0Ð0øÝð 	ð 	ð 	ØˆDð	øøøð /Ð.¨{¸LÈ/ÑZÔZˆÝ”)Ð7Ñ8Ô8ˆÝ)3°NÅDÑ)IÔ)IÐQ�~�~ÈrˆØ%×)Ò)¨+Ñ6Ô6Ð<¸"ˆØ&×*Ò*¨<Ñ8Ô8Ð>¸BˆØ+×/Ò/Ð0IÑJÔJÐPÈbÐà˜|Ð+ð å˜=­$Ñ/Ô/ð 5Ø# }Ð4ðõ Ð/µÑ6Ô6ð 9Ø Ð$8Ð8ð 	"ð ð4Ø8ð4ˆGˆGàÐ2 'Ð2¨Uð 	ð 4Ð3°KÀÐOgÑhÔhÐxÐlxÐØ^Ð^Ð^Ð^Ð^Ð^Ð^Ð^Ø,.ÐØ"?Ð"?ÀÈ\Ñ"ZÔ"ZÐð
 "Ø=AØ"'ð	3ð 	3ð 	3Ýð	3õ ð	3õ ,/­s¬8°d©?ð		3õ
  ð	3õ ð	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð0 JNÐeiÐw{ð 	rð 	rð 	r­ð 	r½CÀ$¹Jð 	rÕX[Ð^bÑXbð 	rÕqtð 	rõ  ADð 	rð 	rð 	rð 	rð 	rð 	rð 	rð 	rð 	,Ð+Ð+Ð+Ð+Ð+Ø -°^Ð CÐ kÈÌÐ[cÔ[kÒHkÐð 4Ð3Ø˜ }°fñ
ô 
Ðð  $×7Ò7¸Ñ?Ô?ÐÝÐ+Ð-CÀUÑKÔKð 	(Ø#'Ð Ø Ò%Ð%Ø#'Ð ð )¨EÒ1ÐY°f´oÈÔIYÒ6YÐØ;KÐ*U¨+¨%¬+©-¬-¨-ÐQUˆ	ð +@Ð*?Ø(ØØ+3Ô+>Ð*?ð+
ñ +
ô +
Ð'ð ŒO˜xÔ/Ò/ð 9Ø/°5Ò8ð 	+ð /Ð.ØØØ+3Ô+>Ð*?ð
ñ 
ô 
ˆð
 +¨eÒ3ÐØ4ÐIÐ8IÐð +?ÐH˜˜œ™œ˜ÀDˆØ�Fˆ	Ø!˜FÐØ�sˆð $) 'Ðð "˜7ÐØ15°ÐØŒ?˜hÔ.Ò.Ð.Ø”-×#Ò# HÔ$4Ñ5Ô5ˆCõ ˜3Ð 6¸Ñ=Ô=ˆDÝ˜$¥Ñ%Ô%ð ­'°#Ð7KÑ*LÔ*Lð Ø!%§¢¡¤ð ð ‘I�D˜#Ý˜3‘x”x¥3 v¤~Ñ#6Ô#6Ò6Ð6¸3×;QÒ;QÐRVÑ;WÔ;WÐ6Ø.2Ð(¨Ñ+Ø˜øÝ!Ô2Ñ4Ô4ˆõ !Ø#Ð# K°Ð?QÑRÔRñ
ô 
Ðð @QÐZ˜4×3Ò3°FÑ;Ô;Ð;ÐVZÐð VfÐUq�'¥$Ð'7Ñ"8Ô"8Ð:JÈDÑQÔQÐQÐw{ˆØÐ'ØÐ#ØÕ"5Ô"DÐDÐDð !&ÐØ#ÐØ&(Ðð !&˜wÐØ!%Ðåð *
ð *
ð *
Ø�6ð*
à1Ð1ð*
ð "6Ð!5ð*
ð 0Ð/ð	*
ð
 0Ð/ð*
ð (˜-ð*
ð 0Ð/ð*
ð #8Ð"7ð*
ð *˜>ð*
ð  �ið*
ð 0Ð/ð*
ð  �ið*
ð %<Ð$;ð*
ð &˜ð*
ð "6Ð!5ð*
ð  $:Ð#9ð!*
ð" 0Ð/ð#*
ð$ .Ð-ð%*
ð& �Gð'*
ð( �Gð)*
ð* %<Ð$;ð+*
ð, $˜ð-*
ð. .Ð-ð/*
ð0 0Ð/ð1*
ð2 .Ð-ð3*
ð4 0RÐ/Qð5*
ð6 "6Ð!5ð7*
ð8 .Ð-ð9*
ð: .Ð-ð;*
ð< ,˜Oð=*
ð> �Gð?*
ð@ *˜>ðA*
ðB *˜>ðC*
ðD "�zðE*
ðF $˜ðG*
ðH *˜>ðI*
ðJ .Ð-ðK*
ðL .Ð-ðM*
ðN "�zðO*
ðP "6Ð!5ðQ*
ðR $:Ð#9ðS*
ˆõV !  xÑ0Ô0ˆð &1Ô%BˆÔ"Ø&1Ô&DˆÔ#ð$ %)Ð!ØŒ?˜hœnÒ,Ð,Ø*.×*BÒ*BÀ6Ñ*JÔ*JÐ'Ø*Ð6ð5õ  'Ø3Ø4Øñ ô  �Hõ
   Ñ)Ô)ð Ý48¸¸¹¼Ñ4DÔ4DÐ1Ð1å48Ø7Ô>ÔD×HÒHØ 1°4ñô ñ5ô 5Ð1øøõ
 !ð 5ð 5ð 5Ø04Ð-Ð-Ð-ð5øøøå9ØŒO˜VÔ-Ð/?Ø5ð
ñ 
ô 
Ðð Œ (Ô"2Ò2Ð2Ý˜Ð >ÀÑFÔFð 3å˜Ð 7¸Ñ>Ô>ð 3ð Ô$ð 3õ •˜Ð 7¸Ñ>Ô>Ñ?Ô?Ð?ð
 ð 	%ð$ !ð
+à" fÔ&6Ò6Ð6ð ×,Ò,¨VÐ5EÑFÔFÐFà×1Ò1Ø”Ø”Ø#Ý! &¨+°tÑ<Ô<Ø$4ð 2ñ ô ð ð '+ð 	ð Ð%Ð*FÐ%ð #8Ð9IÐ!JÐÝ9Ð:LÐW]ÔWfÐgÑgÔgÐð ” H¤O°XÔ5HÐ#IÐIÐIØÔ$ð Jà$ð Jð ,ð	 Jð Ðð ð 	ð5	ð 5	ð 5	ð 5	ð 5	ð 5	ðt '9ˆÔ#Ø&8ˆÔ#Ø!,Ô!CÐð �vˆØ ,ˆÔØ˜ˆØ�vˆØ"& Ðð
 04¨fÐ%Ø!.ˆÔØ ,ˆÔØ*@ˆÔ'Ø1NˆÔ.õ !Ô1Ñ3Ô3ˆØ”Zˆ
ð #1ˆÔØ(ˆÔØ'2Ô'FˆÔ$ð
 )4Ô(HˆÔ%ð ×2Ò2°6Ñ:Ô:ˆØ œ.ˆØŒ?˜hœoÒ-Ð-°&Ô2BÐ-ÐGWÐ-ð 1Ø'7ðAð AÐ#Ð#ð %ð
'/à&¨&Ô*:Ò:Ð:ð ×0Ò0°Ð9IÑJÔJÐJà×5Ò5Ø”OØ”NØ'Ý% f¨k¸4Ñ@Ô@Ø(8ð 6ñ ô ð ð +/ð $ð 'Ð.Ð3OÐ.ð
 *Ð+;ð+Ð'ð $3ˆÔ Ø#2ˆÔ Ø+BˆÔ(Ø)4Ô)JˆÔ&ð ×0Ò0°Ñ8Ô8ˆà Ð$ð UÝ•G˜L¨'°<Ñ@Ô@ÑAÔA×GÒGÑIÔIÈWÒTð 	ð
 Ð%Øð &à×7Ò7¸¼ÑGÔGð &ðWØOÐOÐOÐOÐOÐOØ;Ð;Ð;Ð;Ð;Ð;Ø+Ð+Ñ-Ô-�Ø $Ô 2Ð NµgÔ6LÑ6NÔ6N�Ø!5Ð!5Ø)Ø"œNØ'Ø&Ø4ð"ñ "ô "�ð "Ô(ð +Ø7EÐ1°!Ñ4Ø"×(Ò(Ñ*Ô*Ð*øøõ ð Wð Wð WÝ—’ÐJÈIÑVÔVÐVÐVÐVÐVÐVÐVøøøøðWøøøð Ô'ˆð ˆØð 	JÝ#Ô/Ð0FÐ0FÑ0HÔ0HÑIÔIˆMð ˆØð 	=ÝÔ*¨>¨>Ñ+;Ô+;Ñ<Ô<ˆHð ˆð	*ð 	*ð 	*ð 	*ð 	*õ Ô)Ð*@Ð*@Ñ*BÔ*BÑCÔCˆð	8ð 	8ð 	8ð 	8ð 	8ð 	8ð 	8ð 	8õ.  Ô+¨K¨K©M¬MÑ:Ô:ˆõ &œm™oœoÐð<	[ð <	[ð <	[ð <	[ð <	[ð <	[ð <	[ð <	[ð <	[ð <	[õ| $Ô/Ð0EÐ0EÑ0GÔ0GÑHÔHÐõ  *Ð*HÈ#ÑNÔNÐØ3GÈ!Ò3KÐ3KÐ/Ð/ÐQUÐØ2Ð2Ø(ØØð
ñ 
ô 
Ðð
  Ò&Ð&Ø#ÐÝœ	™œˆðX	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mð X	Mõt Ô*Ð+?Ð+?Ñ+AÔ+AÑBÔBˆð $ð	#	ð #	ð #	åð#	õ ð	#	õ
 ð#	ð #	ð #	ð #	ðJh	õ ",Ð,BÀDÑ!IÔ!IÐØ3EÈÒ3IÐ3IÐ/Ð/ÈtˆNÝ!+Ð,JÈCÑ!PÔ!PÐØ3EÈÒ3IÐ3IÐ/Ð/ÈtˆNØ"ˆNð @Ð?Ð?Ð?Ð?Ð?à&Ð,¨"ˆMØ%5×%JÒ%JÈ=Ñ%YÔ%YÐ"Ø'4ˆHÔ$Ø(>ˆHÔ%Ý )¤Ñ 1Ô 1ÐÝ"+¤/Ñ"3Ô"3ÐÝ!*¤Ñ!1Ô!1Ðð $2Ð ð (Ð3ð YÐXÐXÐXÐXÐXÐXà"�lð ðUð Uð Uð Uð Uð Uð Uð* Ð)ÝÔ Ý9à(4Ø#0Ø,BØ#1Ø'8Ø)<Ø(:Ø),Ø,<ð
ð 
ð G°-ÀÀÀÔ2DÐFÐFØðñ ô ÷ ’%‘'”'�'Ý$Ô2Ø×2Ò2Ð3SÑTÔTñô ˆNð #(ÐØ ˆNàÑ%ð  �ð)8Ý$+¤LØ'Ð(°.ð%ñ %ô %ð ð ð ð ð ð ‘G�D˜!ð ð Ø#1×#8Ò#8Ñ#:Ô#:˜Ùð /×5Ò5Ñ7Ô7ñ  8¸Kñ  8Ø*.×*BÒ*BÀ6Ñ*JÔ*J˜Ø(4°Q¬˜Ø+ñ 8°ñ 8Ý$+¨OÐ=TÑ$UÔ$Uñ8à$3×$IÒ$IÈ+Ñ$VÔ$Vñ8ð )8Ô(I×(MÒ(MÈkÑ(ZÔ(Z˜IØ9BÐ'L y¤~ ~È˜HØ(Ð4Ý18¸ÀLÐRVÑ1WÔ1WÐ1]Ð[] Ø#'×#BÒ#BÀ9Ñ#MÔ#Mð 
!SØ8<×8_Ò8_Ø(1Ø(7Ø(.Ø(0¨°BØ4LØTZÔTdÐ1n°+¸vÔ?OÐ1PÐ1PÐjnð 9`ñ 9&ô 9&ð 3&ð 3&ð 3&ð 3&ð 3&ð 3&¡K H¨a¨að *2ð !S°nð !SÝ/GÈ	Ñ/RÔ/R HÝ"ŸKšKð!;à +Ø*;×*@Ò*@Ñ*BÔ*BÐ Q  È	ñ	ô ð ð *×3Ò3°HÑ=Ô=Ð=Ø/×3Ò3Ñ5Ô5Ð5à$AÀ!Ô$D˜EØ$Ð0Ø %§¢¨JÑ 7Ô 7Ð 7ñS)8ñ ðR  �ð_8Ý$+¤LØ'Ð(°.ð%ñ %ô %ð ð ð ð ð ð ‘G�D˜!ð ð 	ð $2×#8Ò#8Ñ#:Ô#:˜ÙØ*×1Ò1Ñ3Ô3ð Ø.2Ð+Ùà!-¨a¤�JØ!$�JØ!ð !¥g¨jÐ:PÑ&QÔ&Qð !ð!Ø#-×#BÒ#BÑ#DÔ#D˜DØ)-¯ªÐ2JÈCÑ)PÔ)P˜J˜JøÝ(ð !ð !ð !Ø ˜Dð!øøøð +ð ]¨~Ð/IØ *¨nÒ <Ð <Ø)-˜Ø(,×(@Ò(@ÀÑ(HÔ(H˜Ø(ð ]Ý,/°À"Ñ0DÑ,EÔ,EÐ,JÈ˜MÝ.1°>ÀNÑ3RÐWYÑ2YÑ.ZÔ.ZÐ._Ð^_˜Oð
]Ø&3×&8Ò&8Ø$*¤Nð%O¸mð %Oð %Oà7Fð%Oð %Oð %Oð .Eð '9ñ '"ô '"ð !"ð !"ð !"ð !"ð !"ð !"ð !"ð !"øõ $-ð ]ð ]ð ]Ý &§¢Ð-PÐR[Ñ \Ô \Ð \Ð \Ð \Ð \Ð \Ð \øøøøð]øøøà! ^Ò3Ð3Ø.2Ð+Ý!Ô(Ý#Bà0<Ø+8Ø4JØ/@Ø1DØ0BØ4Dð$ð $ð "M¸ÀcÀrÀcÔ8JÐ!LÐ!LØ#'ðñ ô ÷  š%™'œ'˜'Ùà.×5Ò5Ñ7Ô7ñ  8¸Kñ  8Ø*.×*BÒ*BÀ6Ñ*JÔ*J˜Ø(4°Q¬˜Ø+ñ 8°ñ 8Ý$+¨OÐ=TÑ$UÔ$Uñ8à$3×$IÒ$IÈ+Ñ$VÔ$Vñ8ð )8Ô(I×(MÒ(MÈkÑ(ZÔ(Z˜IØ9BÐ'L y¤~ ~È˜HØ(Ð4Ý18¸ÀLÐRVÑ1WÔ1WÐ1]Ð[] Ø#'×#BÒ#BÀ9Ñ#MÔ#Mð 
!SØ8<×8_Ò8_Ø(1Ø(7Ø(.Ø(0¨°BØ4LØTZÔTdÐ1n°+¸vÔ?OÐ1PÐ1PÐjnð 9`ñ 9&ô 9&ð 3&ð 3&ð 3&ð 3&ð 3&ð 3&¡K H¨a¨að *2ð !S°nð !SÝ/GÈ	Ñ/RÔ/R HÝ"ŸKšKð!;à +Ø*;×*@Ò*@Ñ*BÔ*BÐ Q  È	ñ	ô ð ð *×3Ò3°HÑ=Ô=Ð=Ø/×3Ò3Ñ5Ô5Ð5à$AÀ!Ô$D˜EØ$Ð0Ø %§¢¨JÑ 7Ô 7Ð 7ñ_8ðB #ñ =à#/°¤?Ð Ø�	Ø#ð ­Ð0@ÐBXÑ(YÔ(Yð ðØ$4×$IÒ$IÑ$KÔ$K˜	˜	øÝ$ð ð ð Ø˜ðøøøð 'Ÿ]š]Ð+?ÀÑKÔK�
Ø%ŸMšMÐ*BÀAÑFÔF�	Ø%ŸMšM¨.Ñ9Ô9�	Ø#Ÿ-š-Ð(8¸!Ñ<Ô<�Ø%ŸMšMÐ*:¸AÑ>Ô>�	å—’ðEà˜~¨{Ø ¨ØÐ' ñô ð ð $ð XÝ*Ð+;Õ=VÑWÔWÐWå # N°bÑ$8Ñ 9Ô 9Ð >¸Q�ð)°ð )ð )ð )ð�ð ð Ø×&Ò&ð=¸Ið =ð =Ø%ÐBð=ð =à%,ð=ð =à/8ð=ð =ð =ñô ð ð ð  ×&Ò&ðN¨*ð Nð N¸	ÐNð Nð NØ%,ðNð NØ/8ðNð Nð Nñô ð ð
 ×"Ò"ð?ñô ð ð '+§i¢i°Ñ&<Ô&<ØHUÐVWÔHXÐ ` ¨aÔ 0× 4Ò 4°ZÀÑ DÔ DÐ DÐ^`Ø!(Ø)¨!œ_Ð2°Ø&'Ø"ðð �ð" " !”_ˆFØ*¨1Ô-ˆNØ:HÐS˜.×,Ò,¨XÑ6Ô6Ð6ÈeˆKØÐ!¥g¨f°gÑ&>Ô&>Ð!À{Ð!Þ3Ñ5Ô5�
ð	ðð ð ð ð ð ð ð õ '.¨f°jÀ"Ñ&EÔ&EÐ&KÈ�OØ&ð _¨?ÐBWÐ+WÐ+WØ%AÐ%AÀ*ÈoÑ%^Ô%^˜
øøÝ ð ð ð Ø�Dðøøøà”< :Ò-Ð-°d×6WÒ6WÐXcÐekÔeqÑ6rÔ6rÐ-ð ×,Ò,¨[Ñ9Ô9Ð9ð # 1Ô%ˆFØ×.Ò.¨vÑ6Ô6ˆGð 2°!Ô4ˆEØÐ Ø—’‘”�ðZØ×-Ò-°dÐ-Ñ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ð;øÝ ð Zð Zð ZÝ—L’LÐ!HÈ.ÑYÔYÐYÐYÐYÐYÐYÐYøøøøðZøøøà”zð ;ð —K’KÐ DÑEÔEÐEØ×-Ò-°cÐ-Ñ:Ô:Ð:Ð:Ð:Ð:Ð:Ð:Ð:ØÔ,ð @°Ð1DÝ!(¨Ð2VÐX\Ñ!]Ô!]�JÝ 
Ñ+Ô+ð @Ø"˜
 ;°Ñ?Ô?Ð?ð !ˆMØˆGØñ *p˜'ñ *p kñ *pÞ 6°wÀÑ LÔ L�ð !%× :Ò :¸;ÈÐQ^Ñ _Ô _�Ø—:’:˜mÑ,Ô,ð !p°]ð !pÀvÇzÂzÐReÑGfÔGfð !pØ(.¯
ª
Ð3FÑ(GÔ(GÐ%Þ4Ð5FÑGÔGð 4ÝŸšØSØ'Ð.¨3Ø-ñô ð ð ð #4˜˜Ø"ð pð %2Ô$6Ð$<¸"�MÝ")¨-¸ÀtÑ"LÔ"LÐ"RÐPR�KØ×6Ò6°}ÑEÔEð [Ø+/×+RÒ+RØ)Ø#Ø"Ø)Ø(5ØHNÔHXÐ%b k°6Ô3CÐ%DÐ%DÐ^bð ,Sñ ,ô ,ð &ð &ð &ð &ð &ð &™
˜ ð  'ð NÝ&>¸}Ñ&MÔ&M˜Gøà"/Ð"ZÕ3KÈMÑ3ZÔ3Z˜Øð pÝŸšÐ%`ÐbiÐjmÐkmÐjmÔbnÑoÔoÐoð ð c˜gð c¨mð cØ"(§*¢*¨_Ñ"=Ô"=�Ø"ð cØ-�GÝ—L’LÐ!SÐU\Ð]`Ð^`Ð]`ÔUaÑbÔbÐbð ð ˜7Ÿ=š=™?œ?×5Ò5°cÑ:Ô:ð Ø!(§¢¡¤×!6Ò!6°t¸QÑ!?Ô!?�ØESÐ$[ N°1Ô$5°a°b°bÔ$9×$?Ò$?Ñ$AÔ$AÐ$AÐY[Ð!Ø$ð ðØVÐVÐVÐVÐVÐVØ&˜;Ð'8Ñ9Ô9ð +Ý"ŸKšKð!Mà 1ñô ð ð
 -1˜MØ&*˜GøøÝ$ð ð ð Ø˜ðøøøð Œ~ð  =ð °Gð Ý—’ØSØÐ& 3Ø×-Ò-Ñ/Ô/ñô ð ð
 !%�Ø�àð [Y ñ [YÝ—’ÐBÀGÈCÈRÈCÄLÑQÔQÐQð
 ð B�w wÐ0BÑCÔCð BÈð BÐXcÐgnÔgÐXÐXØÔ,¨[Ô9×?Ò?ÑAÔAÐAð $ tÔ'@Ò@Ñ@Ý—N’NðAà(¨+ñô ð ð
 #×6Ò6°vÑ>Ô>�GØð D =ð DÞ3°GÔ4MÈ{Ð\iÑjÔjÐjÐjØ ð D¥W¨W°oÑ%FÔ%Fð DØ×-Ò-¨k¸7ÑCÔCÐCØ(¨Ô+Ð`À(ÐX_Ð/`Ð/`Ð`ðP ð 'Ø×$Ò$Ñ&Ô&Ð&Øð "Ø—’Ñ!Ô!Ð!Ø×$Ò$Ñ&Ô&Ð&Ø×ÒÑ!Ô!Ð!ð ð !ð +ð >Ø.¨qÔ1¸Ð=ð %ð ,ð !Ø×&Ò&Ñ(Ô(Ð(ðØ)Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ð)øÝ"Ô1ð ð ð Ø˜ðøøøð!Ý%Ô.¨{ÀCÐHÑHÔHÐHÐHÐHÐHÐHÐHÐHÐHøÝ#Ô0µ'Ô2HÐIð !ð !ð !Ø#×*Ò*Ñ,Ô,Ð,ð!Ø"-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-øÝ&Ô5ð !ð !ð !Ø ˜Dð!øøøøøð	!øøøð :¸!Ô<ˆMØÐ(°Ô1CÐ(Ø×#Ò# IÑ.Ô.Ð.ðØ'×5Ò5¸cÐ5ÑBÔBÐBÐBÐBÐBÐBÐBÐBÐBøÝ ð ð ð Ø�Dðøøøð × Ò Ñ"Ô"Ð"Øð ð ×1Ò1Ø°ð 2ñ ô ð ð Œ~ð 8Ø×+Ò+¨JÑ7Ô7Ð7ð '¨Ð2CÀ]ÐT`Ðað ð �Øð ðØ"˜
˜
˜
˜
˜
˜
˜
˜
øÝ"Ô1ð ð ð Ø˜ðøøøðððG #)§*¢*¨]Ñ";Ô";�Ø&ñ [%ð 1°Ô3�CØð 
e˜{ð 
eð	eÝ")Ô"2°;ÈÐ"LÑ"LÔ"LÐLÐLÐLÐLÐLÐLÐLÐLøÝ 'Ô 4µgÔ6LÐMð %ð %ð %Ø'×.Ò.Ñ0Ô0Ð0ð%Ø&1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1øÝ#*Ô#9ð %ð %ð %Ø $ ð%øøøøøå(ð eð eð eÝ"ŸLšLÐ)`ÐbcÑdÔdÐdÐdÐdÐdÐdÐdøøøøðeøøøõ 4>¸hÍÑ3MÔ3MÐ'a x xÐTZÐT`Ð^`Ð$Ý!%Ð&6×&:Ò&:Ð;OÑ&PÔ&PÑ!QÔ!Q�JØ%5×%9Ò%9Ð:JÈBÑ%OÔ%O�NØ(HÐ(HØØ&Ø",ð)ñ )ô )Ð%ð5Ø`Ð`Ð`Ð`Ð`Ð`Ø/RÐ/RØ,¨nñ0ô 0Ð,Ð,øõ %ð 5ð 5ð 5Ø/4Ð,Ð,Ð,ð5øøøà+ð iÝŸšØxØ'Ð.¨3ñô ð ð ð (ð iðiØ0ð 	"Ý &§¢ð %SØ$/Ð$6°3ñ!"ô !"ð !"ð !"õ
 !'§¢ð %VØ$/Ð$6°3ñ!"ô !"ð !"ð #'×"EÒ"EØ .Ø'-Ø(/Ø)@Ø1AØ7HØ2B×2FÒ2FÀxÑ2PÔ2PÐ.Pð #Fñ #ô #ð ð ð ð ð ð ð ð øõ  )ð ið ið iÝ"ŸNšNÐ+dÐfgÑhÔhÐhÐhÐhÐhÐhÐhøøøøðiøøøõ �t G™}œ}Ð.JÈDÑQÔQÐ]Ø!(×!CÒ!CØ'Ø'5ð "Dñ "ô "˜õ $ FÑ+Ô+ð %ð%Ø-3¨V©X¬X 
Þ#*Ô#6°zÑ#BÔ#Bð !5Ø*4Ð$4Ð$4Ð$4Ð$4Ð$4Ð$4Ð$4øøÝ#,ð %ð %ð %Ø $ ð%øøøð%ð !ð %¥W¨WÐ6PÑ%QÔ%Qð %Ø!(Ô!A×!EÒ!EÀkÐSWÑ!XÔ!X˜Ý# FÑ+Ô+ð %ð%Ø-3¨V©X¬X 
Þ#*Ô#6°zÑ#BÔ#Bð !5Ø*4Ð$4Ð$4Ð$4Ð$4Ð$4Ð$4Ð$4øøÝ#,ð %ð %ð %Ø $ ð%øøøð #)§*¢*¨Z¸Ñ"AÔ"A�Ø$�Ø&�Ø"&�Ø&*Ð#Ø#.Ð ð %)Ð!Ø Ñ,Ý")¨-¸À4Ñ"HÔ"HÐ"RÈF�KØ×7Ò7¸ÑFÔFñ &Èt×OrÒOrÐs}ÑO~ÔO~ñ &ÝŸšØlØ'Ð.¨3ñô ð ð  &ðh ð 'Ø×$Ò$Ñ&Ô&Ð&Øð "Ø—’Ñ!Ô!Ð!Ø×$Ò$Ñ&Ô&Ð&Ø×ÒÑ!Ô!Ð!ð ð !ð +ð >Ø.¨qÔ1¸Ð=ð %ð ,ð !Ø×&Ò&Ñ(Ô(Ð(ðØ)Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ð)øÝ"Ô1ð ð ð Ø˜ðøøøð!Ý%Ô.¨{ÀCÐHÑHÔHÐHÐHÐHÐHÐHÐHÐHÐHøÝ#Ô0µ'Ô2HÐIð !ð !ð !Ø#×*Ò*Ñ,Ô,Ð,ð!Ø"-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-øÝ&Ô5ð !ð !ð !Ø ˜Dð!øøøøøð	!øøøð :¸!Ô<ˆMØÐ(°Ô1CÐ(Ø×#Ò# IÑ.Ô.Ð.ðØ'×5Ò5¸cÐ5ÑBÔBÐBÐBÐBÐBÐBÐBÐBÐBøÝ ð ð ð Ø�Dðøøøð × Ò Ñ"Ô"Ð"Øð ð ×1Ò1Ø°ð 2ñ ô ð ð Œ~ð 8Ø×+Ò+¨JÑ7Ô7Ð7ð '¨Ð2CÀ]ÐT`Ðað ð �Øð ðØ"˜
˜
˜
˜
˜
˜
˜
˜
øÝ"Ô1ð ð ð Ø˜ðøøøðððWØ+/×+GÒ+GÈÑ+TÔ+TÐ(Ð(øÝ$ð ð ð ÝŸšØXØ'Ð.¨3Ø%)ð %ñ ô ð ð ð ðøøøð *.×)ZÒ)ZØ+Ø*Ø /Ø$4ð	 *[ñ *ô *ð $ð $ð $ð $ð $ð $�Lð $Ñ+Ø%ð~ ð 'Ø×$Ò$Ñ&Ô&Ð&Øð "Ø—’Ñ!Ô!Ð!Ø×$Ò$Ñ&Ô&Ð&Ø×ÒÑ!Ô!Ð!ð ð !ð +ð >Ø.¨qÔ1¸Ð=ð %ð ,ð !Ø×&Ò&Ñ(Ô(Ð(ðØ)Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ð)øÝ"Ô1ð ð ð Ø˜ðøøøð!Ý%Ô.¨{ÀCÐHÑHÔHÐHÐHÐHÐHÐHÐHÐHÐHøÝ#Ô0µ'Ô2HÐIð !ð !ð !Ø#×*Ò*Ñ,Ô,Ð,ð!Ø"-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-øÝ&Ô5ð !ð !ð !Ø ˜Dð!øøøøøð	!øøøð :¸!Ô<ˆMØÐ(°Ô1CÐ(Ø×#Ò# IÑ.Ô.Ð.ðØ'×5Ò5¸cÐ5ÑBÔBÐBÐBÐBÐBÐBÐBÐBÐBøÝ ð ð ð Ø�Dðøøøð × Ò Ñ"Ô"Ð"Øð ð ×1Ò1Ø°ð 2ñ ô ð ð Œ~ð 8Ø×+Ò+¨JÑ7Ô7Ð7ð '¨Ð2CÀ]ÐT`Ðað ð �Øð ðØ"˜
˜
˜
˜
˜
˜
˜
˜
øÝ"Ô1ð ð ð Ø˜ðøøøðððw '+×&BÒ&BÀ=Ñ&QÔ&Q�OÝ*1°-ÐAQÐSWÑ*XÔ*XÐ'Ý(/°¸~ÈtÑ(TÔ(TÐ%ð
 "&×!9Ò!9¸&Ñ!AÔ!A�Ø!Ð-°+Ð-À.ÐB\Ý'.¨~Ð?_ÐaeÑ'fÔ'fÐ$Ø'Ð3Ý%,¨^Ð=VÐX\Ñ%]Ô%]˜
Ý# JÑ/Ô/ð >Ø", *¨[¸.Ñ"IÔ"I˜CØ"ð >Ø 0× 8Ò 8¸Ñ =Ô =Ð =ð
 %)×$<Ò$<¸VÑ$DÔ$DÐ!Ø$ð ðØ/×;Ò;Ø"œNØ%<ð <ñ ô ð ð ð ð ð ð ð ð øõ %ð ð ð Ø˜ðøøøð" ×=Ò=¸kÈ:ÑVÔVÐVÐVÐVÐVÐVÐVÐVà(,¯ªØ(Ø#1Ø+Ø&Ø)Ø 0Ø#1Ø%5¸Ñ%9Ø%4Ø#6Ø!2ð )8ñ )ô )ð #ð #ð #ð #ð #ð #�ö @ÀÈÑXÔXð ð 'Ø×$Ò$Ñ&Ô&Ð&Øð "Ø—’Ñ!Ô!Ð!Ø×$Ò$Ñ&Ô&Ð&Ø×ÒÑ!Ô!Ð!ð ð !ð +ð >Ø.¨qÔ1¸Ð=ð %ð ,ð !Ø×&Ò&Ñ(Ô(Ð(ðØ)Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ð)øÝ"Ô1ð ð ð Ø˜ðøøøð!Ý%Ô.¨{ÀCÐHÑHÔHÐHÐHÐHÐHÐHÐHÐHÐHøÝ#Ô0µ'Ô2HÐIð !ð !ð !Ø#×*Ò*Ñ,Ô,Ð,ð!Ø"-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-øÝ&Ô5ð !ð !ð !Ø ˜Dð!øøøøøð	!øøøð :¸!Ô<ˆMØÐ(°Ô1CÐ(Ø×#Ò# IÑ.Ô.Ð.ðØ'×5Ò5¸cÐ5ÑBÔBÐBÐBÐBÐBÐBÐBÐBÐBøÝ ð ð ð Ø�Dðøøøð × Ò Ñ"Ô"Ð"Øð ð ×1Ò1Ø°ð 2ñ ô ð ð Œ~ð 8Ø×+Ò+¨JÑ7Ô7Ð7ð '¨Ð2CÀ]ÐT`Ðað ð �Øð ðØ"˜
˜
˜
˜
˜
˜
˜
˜
øÝ"Ô1ð ð ð Ø˜ðøøøðððw[Yð| ð 'Ø×$Ò$Ñ&Ô&Ð&Øð "Ø—’Ñ!Ô!Ð!Ø×$Ò$Ñ&Ô&Ð&Ø×ÒÑ!Ô!Ð!ð ð !ð +ð >Ø.¨qÔ1¸Ð=ð %ð ,ð !Ø×&Ò&Ñ(Ô(Ð(ðØ)Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ð)øÝ"Ô1ð ð ð Ø˜ðøøøð!Ý%Ô.¨{ÀCÐHÑHÔHÐHÐHÐHÐHÐHÐHÐHÐHøÝ#Ô0µ'Ô2HÐIð !ð !ð !Ø#×*Ò*Ñ,Ô,Ð,ð!Ø"-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-øÝ&Ô5ð !ð !ð !Ø ˜Dð!øøøøøð	!øøøð :¸!Ô<ˆMØÐ(°Ô1CÐ(Ø×#Ò# IÑ.Ô.Ð.ðØ'×5Ò5¸cÐ5ÑBÔBÐBÐBÐBÐBÐBÐBÐBÐBøÝ ð ð ð Ø�Dðøøøð × Ò Ñ"Ô"Ð"Øð ð ×1Ò1Ø°ð 2ñ ô ð ð Œ~ð 8Ø×+Ò+¨JÑ7Ô7Ð7ð '¨Ð2CÀ]ÐT`Ðað ð �Øð ðØ"˜
˜
˜
˜
˜
˜
˜
˜
øÝ"Ô1ð ð ð Ø˜ðøøøðñøð{ ð 'Ø×$Ò$Ñ&Ô&Ð&Øð "Ø—’Ñ!Ô!Ð!Ø×$Ò$Ñ&Ô&Ð&Ø×ÒÑ!Ô!Ð!ð ð !ð +ð >Ø.¨qÔ1¸Ð=ð %ð ,ð !Ø×&Ò&Ñ(Ô(Ð(ðØ)Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ð)øÝ"Ô1ð ð ð Ø˜ðøøøð!Ý%Ô.¨{ÀCÐHÑHÔHÐHÐHÐHÐHÐHÐHÐHÐHøÝ#Ô0µ'Ô2HÐIð !ð !ð !Ø#×*Ò*Ñ,Ô,Ð,ð!Ø"-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ð-øÝ&Ô5ð !ð !ð !Ø ˜Dð!øøøøøð	!øøøð :¸!Ô<ˆMØÐ(°Ô1CÐ(Ø×#Ò# IÑ.Ô.Ð.ðØ'×5Ò5¸cÐ5ÑBÔBÐBÐBÐBÐBÐBÐBÐBÐBøÝ ð ð ð Ø�Dðøøøð × Ò Ñ"Ô"Ð"Øð ð ×1Ò1Ø°ð 2ñ ô ð ð Œ~ð 8Ø×+Ò+¨JÑ7Ô7Ð7ð '¨Ð2CÀ]ÐT`Ðað ð �Øð ðØ"˜
˜
˜
˜
˜
˜
˜
˜
øÝ"Ô1ð ð ð Ø˜ðøøøððøøøð( % QÔ'ˆÝ�h¥Ñ%Ô%ñ @	¨h¯lªl¸8Ñ.DÔ.Dñ @	Ø—\’\Ð"2Ñ3Ô3Ð9°rˆFØ%+ Ð!B¨v¸Ò/BÐõ
 ˜hŸlšlÐ+?Ñ@Ô@ÑAÔAˆJÝ!%ØÐF� Ð%>ÀÑFÔFñ"ô "Ðð  %ÐØ!ð /Ð*<ð /Ý" 3Ð(AÀ4ÑHÔH�Ý˜HÑ%Ô%ð 1ð1Ø+3¨8°FÑ+;Ô+;¸uÐ+DÐ(Ð(øÝ$ð 1ð 1ð 1Ø+0Ð(Ð(Ð(ð1øøøà#ð /Ø).Ð&õ   §¢Ð-CÑ DÔ DÑEÔEˆLð 9Ð8ØØØ$ðñ ô ˆIð
 &ð P¨lð PÀ	ð PÐM_ð PÝ—’ð VØÐ& 3ØØØ&ñô ð ð ,0�˜Ñ(Ñ(Ø'ñ G°ñ GÐAQñ GÐVYÑVeð !œ^�
Ý% c¨9°dÑ;Ô;�Ý˜3Ð 6¸Ñ>Ô>ð "Ý—K’Kð SØ#Ð* sñô ð ñ ð  ð  J°-Ò$?Ð$?ÀKÐD[ðØ/:×/GÒ/GØ$*¤NØ'1Ø$*Ø%)ð	 0Hñ 0ô 0ð *ð *ð *ð *ð *ð *˜õ # >°9¸dÑCÔCð Ø7;˜H ^Ñ4Ý"ŸKšKð !LØ +Ð 2¨s°Jñô ð ð õ
 #ŸNšNð !RØ +Ð 2¨sÝ '¨¸ÀÑ FÔ Fñô ð øøõ
 %ð ð ð ÝŸšð MØ'Ð.¨3°	ñô ð ð ð ð ð ð øøøøðøøøõ —K’Kð aØ#Ð* sñô ð ð ð (ð ¨Lð ¸S¸_ð !œ^�
Øð ðØ!œk×6Ò6Ø$*¤NØ'1Ø$,Ð-=Ô$>Ø%)ð	 7ñ ô ð ð ð ð ð ð ð ð 48˜ Ñ0ÝŸšØnØ&¨Ð(:°sñô ð ð øõ %ð ð ð ÝŸšØPØ'Ð.¨3°	ñô ð ð ð ð ð ð øøøøðøøøð ð'	Tà Ð,Ø ð -àð -õ ˜8¥TÑ*Ô*ð -ð —L’L Ñ*Ô*ð	 -õ
 Ð(Ð*KÑLÔLð -ö !Ð!1Ñ2Ô2ˆMØ &¤ÐØ 0ÐÝ$Ô5Ñ7Ô7ˆNðð ð ð ð ð ð ð ð ð$TØ ×@Ò@ØØ)Ø-ð Añ ô ð ð øõ
 ð Tð Tð TÝ—’ÐLÈdÑSÔSÐSÐSÐSÐSÐSÐSøøøøðTøøøð ˆsu  Ä0E Å
EÅEÅ,F Æ
FÆF×9A%Y ÙY.Ù-Y.ä6A%f æ
gæ&gçgì$MBY ù-*z úBY ú
z%ú"BY ú$z%ú%ABY û7*|" ü!BY ü"
}ü,}ýBY ý}ýG%BY ÁD7AE ÁEBY ÁE
AEÁEBY ÁEAEÁEF7BY ÁL-AL? ÁL>BY ÁL?
AMÁM	BY ÁMAMÁMA9BY ÁOAO# ÁO"BY ÁO#
APÁO-APÁPBY ÁPAPÁPJBY ÁZ0A[ Á[BY Á[
A[Á[BY Á[A[Á[D3BY Áb Ab	Áb	AbÁbAbÁbAb<Áb</AdÁc,Ac5Ác4AdÁc5AdÁdAdÁdAdÁdAdÁdAdÁd7AeÁe
Ae!Áe Ae!Áf9AgÁgAgÁgAgÁg$BY Ág>Ah ÁhBY Áh/AjÁiAiÁiAjÁiAi&Ái#AjÁi%Ai&Ái&AjÁi)BY Ái+	AjÁi4AjÁjBY ÁjAjÁjA$BY Ák>Al ÁlBY ÁlAl ÁlBY ÁlAl Ál %BY ÁmA3An: Án9BY Án:
Ao)ÁoAo$ÁoBY Áo$Ao)Áo)ABY Áp1'Aq ÁqBY Áq
Aq&Áq#BY Áq%Aq&Áq&A BY Ár''As ÁsBY Ás
AsÁsBY ÁsAsÁsBBY ÁwAw#Áw#Aw5Áw4Aw5Áw9AxÁx/Ay'ÁyAyÁyAy'ÁyAy!ÁyAy'Áy Ay!Áy!Ay'Áy&Ay'ÁzAz.Áz.
Az;Áz:Az;Á|A|Á|A|.Á|-A|.Á|4A}
 Á}	BY Á}
)A}6Á}3BY Á}5A}6Á}6&BY Â@B@Â@B@0Â@/B@0Â@4BAÂA/BB"ÂBBB
ÂB	BB"ÂB
BBÂBBB"ÂBBBÂBBB"ÂB!BB"ÂCBC)ÂC)
BC6ÂC5BC6ÂEBEÂEBE)ÂE(BE)ÂE.B?BY ÂH."BI ÂIBY ÂI
BIÂIBY ÂIBIÂIABY ÂL/BL8ÂL8BM
ÂM	BM
ÂMBM+ÂM+/BN<ÂNBN$ÂN#BN<ÂN$BN6ÂN3BN<ÂN5BN6ÂN6BN<ÂN;BN<ÂO&BPÂP
BPÂPBPÂQ(BQ1ÂQ1BRÂRBRÂTBT ÂTBTÂTBTÂT!BT> ÂT>/BVÂU.BU7ÂU6BVÂU7BV	ÂVBVÂVBV	ÂV	BVÂVBVÂV9BW ÂW
BW#ÂW"BW#ÂX;BYÂYBYÂYBYÂYA9B`/Â[B[Â[B`/Â[B[1Â[.B`/Â[0B[1Â[1B`/Â[5B\Â\B`/Â\/B]#Â]B]Â]
B]#Â]B]	Â]B]#Â]B]	Â]B]#Â] B`/Â]"B]#Â]#)B`/Â^B^*Â^)B`/Â^*
B^7Â^4B`/Â^6B^7Â^7AB`/Â`B`Â`B`/Â`B`*	Â`'B`/Â`)B`*	Â`*B`/Âc/Bc= Âc=BdÂdBdÂgBBi Âi
Bj
Âi"BjÂjBj
Âj;ABl Âl
Bm ÂlBl;Âl;Bm Ân;Bo Âo
BpÂoBo>Âo>Bpr^   rŽ  )r%   rT  )rB	  ©r®   rŠ  )rÝ   rP  r-   N)r¥  )rå  )rÖ  rr  )NNFTr"  )r¥  rá  râ  )NNNF)	NNr   NNNNNN(»  rÏ   r©  rª  r«  r%  rw   Ú__annotations__r&  r€  r'  ri  r  r(  r)  r   rh  r*  rº   r+  r,  r-  r.  r/  r0  r1  r[  r2  r  rU  r3  r4  r
   rÄ  r5  r   r6  rk  r7  r8  r9  r:  rl  Ú_turn_lease_tokensr;  r£  r¤  r¥  r¦  r¨  r©  r«  r<  r=  r>  r?  r@  rA  rF  r/   rA   rK  r   r€  rO  rQ  rR  rS  rT  rU  rV  rW  r»  r  rÎ  r~  rå  rl  rë  rè  r¹  r÷  rÿ  r  r  r   r  r  r  r  r&  r-  r0  Úpropertyr2  r4  r6  r8  rA  rE  r  rH  rK  rÕ  rO  rR  rT  rV  rY  r]  rÏ  rf  rj  ru   r�  r˜  rÐ  r’  rG  r˜  r£  r•  r§  rº  r¼  rÀ  r¾  r¿  rÈ  rÏ  r×  rã  rñ  rø  rÿ  r	  r	  r	  r	  r	  r	  r	  r%	  r'	  Ústaticmethodr*	  r.	  r4	  r	  r=	  r?	  rA	  rF	  r¶  rL	  rN	  r�  r‚  r]	  rŒ  r„  rg	  r�  rm	  r‘  rs	  r…  r†  rˆ  r‰  rŠ  r‹  r‰	  rŒ  r½  r�  r£  r¢  rœ	  r 	  r¤	  rª	  r±	  r¸	  r³	  rÁ	  rr  rÂ	  rÊ	  r
  r-
  r0
  rH
  rV
  rZ
  re
  ÚFuturer_
  rS
  rd
  rx
  rr
  r•   ru
  r{
  r}
  r¤
  r»
  r½
  rÇ
  rñ
  rÏ
  rÑ
  rÖ
  rÛ
  rÙ
  rî
  rû
  rý
  r  ÚAbstractEventLoopr  r	  r  r  r§  rè  rç  r«  r±  rð  r¬  r1  r5  r7  rM  r­  r§  r¢  r°  rX  r_  ra  r¨  r¢  r¤  r©  r·  rÇ  rÊ  r	   rÂ  rÍ  rÁ  rÕ  r›  r   r¡  r¨  r˜  r¡  r/  rY  r)  r,  r_  rK  rA  rF  rB  rC  rD  rE  rG  rü  r#  r$  rü  r   rî  rÅ  r  rX  r8
  r  r%  r:
  r"  rz  rD  ró  rb  rg  r  r  rt  ry  r  r„  r†  r‚  r”  rš  r'  r¨  r¸  r½  r³  rÊ  r¢  rž  rÆ  rŸ  r   r"  r%  r$  r?  rG  rJ  rO  r×  rØ  r   rZ  r_  rb  rm  rÒ  r�  r|  rÍ  rˆ  r‰  r‹  r‘  r˜  r¤  r¸  r   rõ  rÄ  rÂ  rî	  r<
  rØ  ru  Ú_APPROVAL_TIMEOUT_SECONDSrÍ  rÅ  ÚWHATSAPPr  rˆ  ÚEMAILÚSMSÚDINGTALKr6  ÚWECOMÚWECOM_CALLBACKr  r  r  rt  Ú_UPDATE_ALLOWED_PLATFORMSr¨  rß  r§  r©  rª  r\  rs  r|  rc
  r%  r&  r'  r  rŽ  rÂ  rÄ  rÅ  rÆ	  r  r\  r^  rÇ	  rf  r˜  Úobjectrs  rx  r„  r†  r²  rt  r=  r«  r°  r­  Úclassmethodr²  rÃ  rš  r™  rr  rs  rÛ  rš  rá  rÌ
  r&  r�  r  rê  r!  rò  r”  r’  rs  r�  r‘  r·  r�  rt  r  rû  r   r8  r:  r¦  rC  rH  rL  r  r`  rª  r  r{  r—  r¨  r“  r±  rÿ  rª  rN  rM   r>   r
  r
  ä  s<@  € € € € € € ðð ð (Ð�cÐ'Ð'Ñ'Ø&€O�SÐ&Ð&Ñ&Ø$IÐ˜EÐIÐIÑIØ)SÐ ÐSÐSÑSØ $€J�˜”Ð$Ð$Ñ$Ø€IˆtÐÐÑØ#(Ð˜DÐ(Ð(Ñ(Ø$Ð˜Ð$Ð$Ñ$Ø"'Ð˜4Ð'Ð'Ñ'Ø#Ð�tÐ#Ð#Ñ#Ø!&Ð˜$Ð&Ð&Ñ&Ø-2Ð$ dÐ2Ð2Ñ2Ø7;Ð˜X mÔ4Ð;Ð;Ñ;Ø)-€J�˜œÔ&Ð-Ð-Ñ-Ø,0€M�8˜GœLÔ)Ð0Ð0Ñ0ØSWÐ˜x¨¨S°$°xÀÄÐ7MÔ2NÐ-NÔ(OÔPÐWÐWÑWØ'+Ð�x ”}Ð+Ð+Ñ+Ø).Ð  $Ð.Ð.Ñ.ð +Ð*Ð+<Ñ=Ô=€OØ-Ð-Ð.BÑCÔCÐØ1Ð1Ð2JÑKÔKÐØ'Ð'¨Ñ7Ô7€LØ4Ð4Ñ6Ô6ÐØ2Ð2Ð3LÑMÔMÐØ3Ð3Ð4NÑOÔOÐØ';Ð';Ø*ñ(ô (Ð$ð $8Ð#7Ð8VÑ#WÔ#WÐ Ø&:Ð&:Ø)ñ'ô 'Ð#ð 0Ð/Ð0FÑGÔGÐØ)Ð)Ð*:Ñ;Ô;€NØ"6Ð"6Ð7TÑ"UÔ"UÐØ,Ð,Ð-@ÑAÔAÐØ-AÐ-AØ0ñ.ô .Ð*ð 2Ð1Ð2JÑKÔKÐØ+Ð+Ð,>Ñ?Ô?ÐØ-Ð-Ð.BÑCÔCÐØ1Ð1Ð2JÑKÔKÐð˜t C¨Ð$7Ô8ð ð ð ð ð¨#ð °.ð ð ð ð ð)¨sð )°xÀÔ7Oð )ð )ð )ð )ðB¨sð B°tð Bð Bð Bð Bð

 d¨5¤kð 
ð 
ð 
ð 
ð 6:Ð˜( >Ô2Ð9Ð9Ñ9Ø.2Ð˜h sœmÐ2Ð2Ñ2Ø-1Ð˜X cœ]Ð1Ð1Ñ1Ø!$Ð˜Ð$Ð$Ñ$Ø;?Ð˜XÐ&7Ô8Ð?Ð?Ñ?Ø-2Ð$ dÐ2Ð2Ñ2Ø8<Ð˜X nÔ5Ð<Ð<Ñ<ñ~8ð ~8˜x¨Ô6ð ~8ð ~8ð ~8ð ~8ñBð ð ð ñ>-
ð -
ð -
ð -
ðf $ð ð ð ð ð $Ð&?Ñ?Ðð- 8ð -°cð -¸cð -ð -ð -ð -ð 4¨¨S¨¤>ð ð ð ð ñ4@ð @ð @ð @ð,¸sð ,Èdð ,ÐW[ð ,ð ,ð ,ð ,ð+¸cð +ÈDð +ÐUYð +ð +ð +ð +ñ$*ð *ð *ð *ðXØ" 3œðØ27ðà	ðð ð ð ñ:ð ð ð ð< >Bð2ð 2ð 2Ø-5°c¬]ð2à	ð2ð 2ð 2ð 2ðh8°%ð 8ð 8ð 8ð 8ñ6ð 6¸uð 6ð 6ð 6ð 6ð$ :?ð$
ð $
ð $
Ø26ð$
à	ð$
ð $
ð $
ð $
ðL<ÐPTð <ð <ð <ð <ð  ð" Tð "ð "ð "ñ „Xð"ð ð'¨$ð 'ð 'ð 'ñ „Xð'ð ð!˜X cœ]ð !ð !ð !ñ „Xð!ð ð˜8 Cœ=ð ð ð ñ „Xðð
¨mð 
Àð 
ð 
ð 
ð 
ð<°=ð ÀTð ð ð ð ð2 #, )¨R°¨IÑ"6Ô"6Ðð7°Mð 7Àdð 7ð 7ð 7ð 7ð	¨mð 	Àð 	ð 	ð 	ð 	ð +/Ð'ð¸=ð ÈTð ð ð ð ð(
°Cð 
ð 
ð 
ð 
ð
°#ð 
ð 
ð 
ð 
ð
°ð 
À8ÈCÄ=ð 
ð 
ð 
ð 
ð
àð
ð 
ð	
ð 
ð 
ð 
ð&àðð
 ðð 
ðð ð ð ð44àð4ð 
�#Œð4ð 4ð 4ð 4ðl@àð@ð 
ð@ð @ð @ð @ð> +/Ø%)Ø&*ðf%ð f%ð f%ð ˜Ô'ðf%ð ˜c”]ð	f%ð
 ˜d”^ðf%ð 
ˆs�DˆyÔ	ðf%ð f%ð f%ð f%ðP-°sð -À3ð -ÐX\ð -Ðaeð -ð -ð -ð -ð^.Y¸ð .YÀSð .YÈTð .Yð .Yð .Yð .Yð`O°°S¸#°X´ð OÀ4ð Oð Oð Oð Oð #Ð9Lð #ÐQUð #ð #ð #ð #ð8Ð7Jð Ètð ð ð ð ðBN"Ø*ðN"à	ðN"ð N"ð N"ð N"ð`XÐ>Qð XÐVZð Xð Xð Xð Xðt#¨#ð #°$ð #ð #ð #ð #ð
) cð )ð )ð )ð )ð
 Cð 
ð 
ð 
ð 
ð¨ð ð ð ð ð( sð ð ð ð ð°ð ¸ð ð ð ð ð.¸ð ð ð ð ð8/°Uð /ð /ð /ð /ð=¨Eð =ð =ð =ð =ðB"
¨4ð "
ð "
ð "
ð "
ñH,Zð ,Zð ,Zð ,Zð\
¨ð 
ð 
ð 
ð 
ñ5ð 5ð 5ð 5ð"1ð 1ð 1ñ7Uð 7U°Uð 7UÀdð 7Uð 7Uð 7Uð 7UðrD cð Dð Dð Dð DðL sð Lð Lð Lð LðW¨Tð Wð Wð Wð Wð"5¨ð 5¸Nð 5ÐUXð 5Ð]að 5ð 5ð 5ð 5ðàðð ðð   Ô/ð	ð
 
�.Ô	!ðð ð ð ð> @Dð ð ð ¨ð ¸ð Èð ð ð ð ð ðU°3ð U¸4ð Uð Uð Uñ „\ðUð¸Sð È3ð ÐSVð ð ð ð ð6	¸ð 	Àð 	ð 	ð 	ð 	ñ
ð 
°H¸S´Mð 
ÐW_Ð`cÔWdð 
Ðptð 
ð 
ð 
ð 
ñð ð ð ñ@0ð 0ð 0ð 0ñ(/ð /ð /ð /ñ0*ð *°Uð *ÀTð *ð *ð *ð *ðH )-Ø$(Ø'+ðð ð àðð ! œð	ð
 ˜S”Mðð   ”}ðð 
ðð ð ð ð0 ACð $
ð $
ð $
¸#ð $
Àtð $
ð $
ð $
ð $
ðL°4ð ð ð ð ð4 ð D¨¨c°3¨h¬Ô$8ð ð ð ñ „\ððB ð@¨3ð @ð @ð @ñ „\ð@ð& '+Ø#'Ø#'ð#
ð #
ð #
àð#
ð ð#
ð
 ˜d”^ð#
ð ˜C”=ð#
ð ˜C”=ð#
ð 
ð#
ð #
ð #
ð #
ðT $(Ø#'ðEð Eð EàðEð ðEð
 ˜C”=ðEð ˜C”=ðEð 
ðEð Eð Eð Eð8 ñ4ð 4 cð 4°4¸$±;ð 4ð 4ð 4ñ „\ð4ð  ðF°ð F¸¸cÀ4¸iÔ8Hð Fð Fð Fñ „\ðFð8 +/Ø%)Øð2ð 2ð 2ð ˜Ô'ð2ð ˜c”]ð	2ð
 ð2ð 
�‰ð2ð 2ð 2ð 2ð:
àð
ð # 4œ.ð
ð 
ð	
ð 
ð 
ð 
ð" Ø%)ñ)ð )ð ˜c”]ð)ð 
�#Œð	)ð )ð )ð )ð@ ñ	
ð 
àð
ð ð	
ð
 
ð
ð 
ð 
ð 
ð* ð  d¡
ð ð ð ñ „\ðð$ ð
 $ð 
ð 
ð 
ñ „\ð
ð ð
 3ð 
ð 
ð 
ñ „\ð
ð ðA #ð Að Að Añ „\ðAð. ð¨ð ð ð ñ „\ðð$ ð¨eð ð ð ñ „\ðð, ð°ð ð ð ñ „\ðð6 ð	 Dð 	ð 	ð 	ñ „\ð	ð ð $¨¡+ð ð ð ñ „\ðð$-$¨°©ð -$ð -$ð -$ð -$ð^ ð!$¨cð !$¸$À¹+ð !$È$ð !$ð !$ð !$ñ „\ð!$ðF
¨$¨s°C¨x¬.ð 
ð 
ð 
ð 
ð¨h°s¬mð ð ð ð ðH¸ð HÀÈ#Äð Hð Hð Hð Hðàðð ðð 
ˆs�H˜S”MÐ!Ô	"ð	ð ð ð ð: ð#°3ð #¸4ð #ð #ð #ñ „\ð#ðJ4ÀCð 4ÈDð 4ð 4ð 4ð 4ðl ðQÈð Qð Qð Qñ „\ðQð !Ðð%8¸3ð %8À|ð %8ÐX\ð %8ð %8ð %8ð %8ðN#/°Lð #/ÀSð #/ð #/ð #/ð #/ðJx¸|ð xÐZ]ð xÐbfð xð xð xð xðt9#°%ð 9#¸EÀ$ÀsÈCÀxÄ.ÐRVÐBVÔ<Wð 9#ð 9#ð 9#ð 9#ðv^°ð ^¸ð ^ð ^ð ^ð ^ñ Eð Eð Eð EðNF¸TÀ#ÀsÀ(¼^ð FÐPTð Fð Fð Fð FðPà˜c”]ðð ðð   ”}ð	ð
 
ðð ð ð ð@ Ðð$.à”ð$.ð ð$.ð
 ð$.ð 
ð$.ð $.ð $.ð $.ðN -/ð&ð &ð &Øð&Ø&)ð&à	ð&ð &ð &ð &ðP9¨cð 9°dð 9ð 9ð 9ð 9ðv ÐØ0ÐðÀSð ÈTð ð ð ð ð6/¨cð /ð /ð /ð /ðb¸ð Àð ð ð ð ñ*yð yð yð yñv]Sð ]Sð ]Sð ]Sð~F¸ð Fð Fð Fð FðP 38ÈUð 'ð 'ð '¨4ð 'Àdð 'ÐW[ð 'ð 'ð 'ð 'ð\ %˜9ØFÐFÐFñô Ðð?à$ð?ð ð?ð ð	?ð
 
ð?ð ?ð ?ð ?ð<°,ð À4ð ð ð ð ð °Cð ð ð ð ñ48`ð 8`ð 8`ð 8`ðt ñð ð ñ „\ðði°cð ið ið ið iñVLð LÀ#ð Lð Lð Lð Lð\
 tð 
ð 
ð 
ð 
ð 26Ø'+ñð àÐ-Ô.ðð ˜8Ô$ðð 
ð	ð ð ð ð4^°Ô0Ið ^Èdð ^ð ^ð ^ð ^ñ,Yð Yð Yð Yð$	À3ð 	ð 	ð 	ð 	ð°°s¸C°x´ð ñ ð ð ð(R˜Tð Rñ Rð Rð Rñh  !Ðñ  #Ðá?CÉaÐZ^ñ \ð \ñ \ð \ð \ñ|0*ð 0*¨uð 0*¸tð 0*ñ 0*ð 0*ð 0*ñdK>¨$¨s°C¨x¬.ð K>¸Tð K>ñ K>ð K>ð K>ñZ{'ð {'°cð {'ñ {'ð {'ð {'ðz?°ð ?ñ ?ð ?ð ?ñð ð ð*>°sð >¸xÈ¼~ð >ñ >ð >ð >ñ"v¸5ð vÀSð vñ vð vð vñp'ð '°Uð 'ñ 'ð 'ð 'ð0 cð ñ ð ð ñ
ñ 
ð 
ð 
ñ0Q'ñ Q'ð Q'ð Q'ñfñ ð ð ð@¨ð ñ ð ð ñ ñ ð ð ð Ø!&Ø %ñ^ð ^ñ ^ð ñ^ð ñ	^ð
 ð^ð 
ð^ñ ^ð ^ð ^ñ@*ñ *ð *ð *ðV¸ð Vñ Vð Vð Vñp@Øñ@Ù/5ñ@Ø@DÀUÈCÀZÔ@Pð@à	ð@ñ @ð @ð @ðD7à$ñ7ð ð7ð ð	7ð
 
ð7ñ 7ð 7ð 7ñ,`<Øð`<Ø+3ð`<à	ð`<ñ `<ð `<ð `<ñD9Øð9Ø+3ð9Ø>Qð9à	ð9ñ 9ð 9ð 9ñ2ØðØ+3ðà	Ð&Ð'¨°4¬Ð8Ô	9ðñ ð ð ñ
àð
ð ð
ð %ð	
ð
 
ð
ñ 
ð 
ð 
ñF¸#ð ñ ð ð ñ8ð ð ñ$ð $ð $ð ð'Øð'Ø%(ð'à	�%Œð'ñ 'ð 'ñ „\ð'ð ðB¨(ð B¸Sð BÀXÈeÄ_ð Bñ Bð Bñ „\ñBð* ð.X°ð .X¸À#¼ð .Xñ .Xð .Xñ „\ñ.Xð`AàðAð ðAð 
Ð%Ô	&ð	Añ Að Añ AðL '+ñ$ð $àñ$ð ˜s”mð$ð 
�3˜ œ x°¤}Ð5°tÐ;Ô	<ð	$ñ $ð $ñ $ñV(G¸cð (GÀdð (Gñ (Gð (Gñ (GñTTá#ñTð ðTð 
‘,Ô	ð	Tñ Tð Tñ TñH Qñ,áIñ	)ð )Ñ�t˜C ˜H”~ð ñ ñ ðI
Ø!ñI
Ø7:ðI
ñ I
ð I
ñ I
ðV
°ð 
ñ 
ð 
ñ 
ð<¨|ñ Èð ñ ð ñ ð$°ñ $Èð $ñ $ð $ñ $ð
9¨lñ 9Àsð 9ñ 9ð 9ñ 9ð7¨\ñ 7Àcð 7ñ 7ð 7ñ 7ð&&=¨|ñ &=Èð &=ñ &=ð &=ñ &=ðP/F¨|ñ /FÈð /Fñ /Fð /Fñ /Fðb{¨lñ {Àsð {ñ {ð {ñ {ð*hB¨<ð hB¸HÀS¼Mð hBñ hBð hBñ hBðT/¨>ñ Àcð Èdð ñ ð ñ ð$UÀCð UÈDð Uñ Uð Uñ Uð* &*ñVð Vð Vð ðVð ñ	Vð
 �d˜3 ˜8”nÔ%ðVð ˜c”]ðVð 
�#ŒðVñ Vð Vñ Vð| &*ñ
ð 
ð 
ð ð
ð ñ	
ð
 �d˜3 ˜8”nÔ%ð
ð ˜c”]ð
ð 
�#Œð
ñ 
ð 
ñ 
ð0
¸#ð 
ñ 
ð 
ñ 
ð¸sð ÀtÈCÄyð ñ ð ñ ð°ð Àð ñ ð ñ ð* ðÑ%6ð ñ ð ñ „Xñðàðð ðð 
ð	ñ ð ñ ð.)°nð )Èð )ñ )ð )ñ )ðV°cð ñ ð ñ ñs9È#ñ s9Ð_bð s9ñ s9ð s9ñ s9ðj?+°ð +À3ð +ñ +ð +ñ +ð(v  cð v ñ v ð v ñ v ðv(DØ#ñ(DØ47ð(Dà	�#Œð(Dñ (Dð (Dñ (Dð`%¨}ñ %Àsð %Ètð %ñ %ð %ñ %ðTO°,ð OÀ4ð Oñ Oð Oñ Oðr6°|ð 6Èð 6ñ 6ð 6ñ 6ð<!Q°\ð !Qñ !Qð !Qñ !QðL¨Sð ñ ð ñ ñ*Wñ Wð Wñ Wñ,?ñ ?ð ?ñ ?ñ('°3ð 'Àð 'ÐQTð 'ÐY]ð 'ñ 'ð 'ñ 'ñ '°Sð '¸Tð 'ñ 'ð 'ñ 'ñ
2Lñ 2Lð 2Lñ 2Lðl°Sñ À3ð È4ð ñ ð ñ ð&)ÀSñ )ÐSVð )Ð[_ð )ñ )ð )ñ )ñVMGð ðMGð ñ	MGð
 ðMGð 
ðMGñ MGð MGñ MGðb ð˜\ð ¨h°s¬mð ñ ð ñ „\ñð7X°lð 7XÀsð 7Xñ 7Xð 7Xñ 7Xðr%°|ð %Èð %ñ %ð %ñ %ð.M°Sð M¸Tð Mñ Mð Mñ Mñ'°sñ 'ÀSñ 'ÐVYð 'Ð^bð 'ñ 'ð 'ñ 'ñRM,ØñM,Ø&)ñM,Ø7:ðM,ñ M,ð M,ñ M,ðh #ñJð JàñJð ñJð ñ	Jð
 ðJð 
ðJñ Jð Jñ JðXH¨dð Hñ Hð Hñ HðY¨\ñ YÀð YÈð Yñ Yð Yñ Yð@ 59ñsIñ sIàðsIð ñsIð
 " $ s¨C x¤.Ô1ðsIð 
ðsIñ sIð sIñ sIðt .2Ø*.Ø',Ø"ñ%
ñ %
àð%
ð ñ%
ð
 ˜4  S œ>Ô*ñ%
ð # 3œ-ñ%
ð !%ñ%
ð ð%
ð 
ð%
ñ %
ð %
ñ %
ðX +/Ø*.Ø+/ññ àðñ  ñð ñ	ð
 # 3œ-ñð ˜T #œYÔ'ñð ˜d 3œiÔ(ðð 
ðñ ð ñ ð@ +/Ø*.Ø+/ñLñ LàðLñ  ñLð ñ	Lð
 # 3œ-ñLð ˜T #œYÔ'ñLð ˜d 3œiÔ(ðLð 
ðLñ Lð Lñ Lðh
¸]ð 
Ètð 
ñ 
ð 
ñ 
ð8'U¸-ð 'UÈDð 'Uñ 'Uð 'Uñ 'UðRU¸]ð UÈtð Uñ Uð Uñ Uñ$	°Cð 	¸Cð 	ñ 	ð 	ñ 	ð
°=ð 
ÀTð 
ñ 
ð 
ñ 
ð
°]ð 
Àtð 
ñ 
ð 
ñ 
ð-Ø#ð-à	‘%˜˜S˜”/Ô	"ð-ñ -ð -ñ -ð^Ø#ðà	‘%˜˜S˜”/Ô	"ðñ ð ñ ñ6°Cð ¸Cð ñ ð ñ ð& 15ñUlð UlàðUlð ñUlð ñ	Ulð
 ™U 3¨ 8œ_Ô-ðUlð 
ðUlñ Ulð Ulñ Ulðn26àð26ð ñ26ð ð	26ð
 
ð26ñ 26ð 26ñ 26ðhSdàðSdð ñSdð ð	Sdð
 
ðSdñ Sdð Sdñ Sdðj¸=ð ÈTð ñ ð ñ ð.#6àð#6ð ñ#6ð ð	#6ð
 
ð#6ñ #6ð #6ñ #6ñJ ,1Ñ(ð¸Mð Èdð ñ ð ñ ð&
¨3ð 
ñ 
ð 
ñ 
ð,"
À-ð "
ÐTWð "
ñ "
ð "
ñ "
ðJ, Àð , ÐRUð , ñ , ð , ñ , ð\4¸<ñ 4ÐY\ð 4Ðadð 4ñ 4ð 4ñ 4ðxi;¨|ð i;Àð i;ñ i;ð i;ñ i;ðzn
ð ñn
ð ñ	n
ð
 ñn
ð ðn
ñ 
ˆsÑ$ dÐ*Ô	+ðn
ñ n
ð n
ñ n
ð`Bð ñBð ñ	Bð
 ñBð ðBð 
�#ŒðBñ Bð Bñ BðH 4¨¨S¨¤>ð ñ ð ñ ð  .2ññ ð & cœ]ðð 
�$�s˜C�x”.Ô	!ð	ñ ð ñ ð4 $(Ø-1Ø!%ñ"ð "ð "à˜8Ô$ð"ð ˜#”ð"ð ˜C”=ñ	"ð ˜C”=ñ"ð & cœ]ð"ð ˜#”ð"ð 
�$�s˜C�x”.Ô	!ð"ñ "ð "ñ "ðH ð $(Ø!%ñð ð Ø˜8Ô$ðà˜#”ðð ˜C”=ñð
 ˜C”=ðð ˜#”ðð 
ðñ ð ñ „\ñð> ð. |ð .¸À¼ð .ñ .ð .ñ „\ñ.ñ !$Ñð !* 	ØÕ˜8�>¨8Õ+<Ø�˜�Ø�˜� hÕ&7Ø�˜�¨Õ)@À(Å/ÐS[ÕSgÐiqÕiwð  zBõ  zHð	+ñ !ô !ÑñXñ Xð Xñ Xð  #Ø!$Øñ	|Kñ |Kàñ|Kð ð|Kð ð	|Kð
 
ð|Kñ |Kð |Kñ |Kð|u°ð uñ uð uñ uðnM0°(¸5ÀÀcÈ8ÐTWÌ=ÐAXÔ;YÔ2Zð M0ñ M0ð M0ñ M0ðd GKñQð Qñ Qð ˜s 5¨¨c°8¸C´=Ð)@Ô#AÔBÔCðQð 
ˆU�3˜˜X cœ]Ð*Ô+Ô	,ð	Qñ Qð Qñ Qðf#
©ð #
¸4ð #
ñ #
ð #
ñ #
ñJ#¨ð #°$ð #ñ #ð #ñ #ñ
	
ð 	
ñ 	
ð™zÕ1ÕDð ñ ð ñ ñ&*ñ *ð *ñ *ð, +/Ø%)Ø&*Ø"&Ø#ñGð Gð Gð ˜Ô'ðGð ˜c”]ð	Gð
 ˜d”^ñGð ˜3”-ðGð ˜Œ}ðGð 
ðGñ Gð Gñ GñREàñEð ˜#”YðEð 
ð	Eñ Eð Eñ EñNJ1àñJ1ð ˜#”YðJ1ð 
ˆs�D˜”Iˆ~Ô	ð	J1ñ J1ð J1ñ J1ðX°4¸´9ð ñ ð ñ ð $(ñ5ñ 5ð ˜C”=ð5ð 
ˆs�T‰z˜4 œ9Ð$Ô	%ð	5ñ 5ð 5ñ 5ðJ Ù'ñ'Vð 'Vñ 'Vð
 ˜#”Yñ'Vð ð'Vð 
ð'Vñ 'Vð 'Vñ 'Vñb ñ+ð +ñ +ð
 ñ+ð ð+ð 
ˆs�D˜”Iˆ~Ô	ð+ñ +ð +ñ +ñZL
¨tð L
ñ L
ð L
ñ L
ñ\oØñoØ$(ðoà	�$Œðoñ oð oñ oðb ñ¨4ð °H¸UÀ3ÈÉVÐCSÔ=TÔ4Uð ñ ð ñ „\ññ(3À3ð 3È3ð 3ñ 3ð 3ñ 3ñj@^Øñ@^Ø$(ð@^à	�$Œð@^ñ @^ð @^ñ @^ñD3°Dð 3¸Tð 3ñ 3ð 3ñ 3ñ*0*ð 0*¸ð 0*Èð 0*ñ 0*ð 0*ñ 0*ñd|>°$ð |>¸4ð |>ñ |>ð |>ñ |>ð| Ññ)Ñ ð ñ ñ ñ0"Ñð PRÑ  U¨3°°d±
¨?Ô%;¸TÀ#ÀsÀ(¼^Ð%KÔ LÐQÑQÑQáðE°4¸¸S¸´>ð Eñ Eð Eñ „[ñEñ ð<°T¸#¸s¸(´^ð <ñ <ð <ñ „[ñ<ñ: ð(¸¸t¹ð (Èð (ñ (ð (ñ „[ñ(ðT ð #'Ø"Ø"&Ø#(ñG>ð G>ØñG>àñG>ð ñG>ð ñ	G>ð
 ˜4‘KñG>ð �t‘ñG>ð ˜4‘ZñG>ð !ðG>ð 
ðG>ñ G>ð G>ñ „\ñG>ðR<
¸Sð <
ÀTð <
ñ <
ð <
ñ <
ð|%Øð%Ø'*ð%Ø<@ð%à	ð%ñ %ð %ñ %ð<
¸Cð 
ÀDð 
ñ 
ð 
ñ 
ð.¸3ñ .È$ð .ÐSWð .ñ .ð .ñ .ðM¸ñ MÈ#ð MÐRVð Mñ Mð Mñ Mð )-ñ	7ð 7ð 7àñ7ð ! œð	7ð
 
ð7ñ 7ð 7ñ 7ðr¨sñ ÀCð ÈDð ñ ð ñ ð:ØñØ03ñØEHðà	ðñ ð ñ ð:3
°Sð 3
ÀSð 3
ÈTð 3
ñ 3
ð 3
ñ 3
ðj*À#ð *È$ð *ñ *ð *ñ *ðX)¸ð )Àð )ñ )ð )ñ )ð UWð 
ð 
ð 
¸cð 
Ècð 
Ð[^ð 
ñ 
ð 
ñ 
ð/°3ñ /ÀCð /ÈDð /ñ /ð /ñ /ðàðð ñð ˜$‘Jð	ð
 
ðñ ð ñ ñ. '+ñR2ð R2ð R2àðR2ð ñR2ð
 ñR2ð !ñR2ð  $ðR2ð 
ðR2ñ R2ð R2ñ R2ðhIØðIØ,4°S¬MðIà	ðIñ Ið Iñ IðVR¸3ñ RÀtÈCÄyð RÐUYð Rñ Rð Rñ Rð@¸sð @ÀtÈCÄyð @ñ @ð @ñ @ð0¸ð 0ÐUXð 0Ð]eÐfiÔ]jð 0ñ 0ð 0ñ 0ñ<Ø#'ðØ6>¸s´mðà	ðñ ð ñ ð2 ñLK°4ð LK¸Cð LKñ LKð LKñ „\ñLKð\E¨sð E°tð Eñ Eð Eñ EðN ð"¨3ñ "Àð "Èð "ñ "ð "ñ „\ñ"ð65O°cñ 5OÀð 5OÈð 5Oñ 5Oð 5Oñ 5Oðn	0¨sñ 	0¸ð 	0Àð 	0ñ 	0ð 	0ñ 	0ð#/°ð #/¸ð #/ñ #/ð #/ñ #/ñJð ñ ð2C #ð Cñ Cð Cñ Cð
H uð Hñ Hð Hñ Hð
q°3ð qñ qð qñ qñf¨D°¬Kð ¸Dð ñ ð ñ ñ:Qñ Qð Qñ QðfW¨3ð Wñ Wð Wñ Wðz ¨¤ð ñ ð ñ ð C<áñC<ð ðC<ð ñ	C<ð ðC<ñ 
4ðC<ñ C<ð C<ñ C<ðX  Ø(,Ø*.ñY
ñ Y
àñY
ð ñY
ð �d˜3 ˜8”nÔ%ð	Y
ñ
  ðY
ð ðY
ð ñY
ð ! œñY
ð # 3œ-ðY
ð 
ˆc�3ˆhŒðY
ñ Y
ð Y
ñ Y
ðH	  Ø(,Ø !Ø*.Ø(,Ø%)Ø.2Ø26Ø&*ñ/ñ /àñ/ð ñ/ð �d˜3 ˜8”nÔ%ð	/ð
 ð/ð ð/ð ñ/ð ! œñ/ð ñ/ð # 3œ-ñ/ð ! œñ/ð ˜T”Nñ/ð ' sœmñ/ð !)¨¤ñ/ð ˜s”mð/ð  
ˆc�3ˆhŒð!/ñ /ð /ñ /ðb.¨}ð .ÀÈ#Äð .ñ .ð .ñ .ð`6%°}ð 6%Éð 6%ñ 6%ð 6%ñ 6%ð~  Ø(,Ø !Ø*.Ø(,Ø%)Ø.2Ø26Ø&*ñsñ sàñsð ñsð �d˜3 ˜8”nÔ%ð	sð
 ðsð ðsð ñsð ! œñsð ñsð # 3œ-ñsð ! œñsð ˜T”Nñsð ' sœmñsð !)¨¤ñsð ˜s”mðsð  
ˆc�3ˆhŒð!sñ sð sñ sð sð srM   r
  ç      à?)r<  Ú
stop_eventc                óì  — ddl m}m}  |¦   «         }|                      ¦   «         sÍ	 |                     ¦   «         rZt          |dd¦  «        sIt          |dd¦  «        r8 |¦   «         s|                      |¦  «         Œk|                     |d¦  «         dS n2# t          $ r%}t           
                    d|¦  «         Y d}~nd}~ww xY w|                      |¦  «         |                      ¦   «         ¯ËdS dS )u�  Poll for the planned-stop marker and trigger graceful shutdown.

    On Windows, ``asyncio.add_signal_handler`` raises NotImplementedError
    for SIGTERM/SIGINT, so the standard signal-driven shutdown path
    never runs when ``hermes gateway stop`` signals the gateway. The
    consequence is that the drain loop is skipped â€” in-flight agent
    sessions are killed mid-turn and ``resume_pending`` is never set,
    so the next gateway boot has no idea those sessions need to be
    auto-resumed (issue #33778, v0.13.0 session-resume feature broken
    on native Windows).

    This watcher runs on every platform (cheap, defensive) and bridges
    the gap on Windows by translating a filesystem marker into the
    same shutdown-handler invocation a real SIGTERM would have produced
    on POSIX. The CLI's ``hermes_cli.gateway_windows.stop()`` writes
    the marker via ``write_planned_stop_marker(pid)`` and then waits
    for the gateway PID to exit; this watcher is what makes that
    exit happen cleanly.

    On POSIX this is a no-op safety net â€” the signal handler always
    races us to consuming the marker file because it fires synchronously
    from the kernel's signal delivery.

    Args:
        stop_event: cleared by start_gateway() during normal shutdown
            to tell the watcher to exit.
        runner: the GatewayRunner instance; we check ``_running`` and
            ``_draining`` to avoid triggering shutdown if the gateway
            is already in one of those states.
        loop: the asyncio event loop the shutdown handler must run on.
        shutdown_handler: same callable that's wired to SIGTERM â€”
            tolerates a ``None`` signal argument (planned stop case)
            and consumes the marker via
            ``consume_planned_stop_marker_for_self()``.
        poll_interval: seconds between marker checks. 0.5s gives a
            responsive shutdown without burning CPU.
    r   )Ú_get_planned_stop_marker_pathÚ planned_stop_marker_targets_selfr*  Fr’  Nz#Planned-stop watcher tick error: %s)r;	  rÂ  rÃ  r8  r˜   rV   rB  Úcall_soon_threadsafer2   r3   r4   )	rÀ  r	  rØ   Úshutdown_handlerr<  rÂ  rÃ  r  rÄ  s	            r>   Ú_run_planned_stop_watcherrÆ  Íh  s^  € ðZð ð ð ð ð ð ð ð 0Ð/Ñ1Ô1€KØ×ÒÑ!Ô!ð $'ð"	Dà×"Ò"Ñ$Ô$ðå ¨°UÑ;Ô;ðõ ˜F J°Ñ6Ô6ðð, 8Ð7Ñ9Ô9ð Ø—O’O MÑ2Ô2Ð2Øð
 ×)Ò)Ð*:¸DÑAÔAÐAà�øøÝð 	Dð 	Dð 	DÝ�LŠLÐ>ÀÑCÔCÐCÐCÐCÐCÐCÐCøøøøð	Døøøà�Š˜Ñ&Ô&Ð&ðI ×ÒÑ!Ô!ð $'ð $'ð $'ð $'ð $'s   ¨AB Á>B Â
CÂ!CÃCrø  r		  c           	      óÀ  — ddl m}m}m}m}m} ddlm}	 d}
d}d}d}d}d}d|fd|fd	|fd
|fd|ff}t           	                    d|¦  «         d}|  
                    ¦   «         �sà|dz  }||z  dk    rw|ru	 ddlm} |�9t           ||¦  «        |t          d¬¦  «        }|�|                     d¬¦  «         n2# t          $ r%}t                               d|¦  «         Y d}~nd}~ww xY w||
z  dk    rf|D ]c\  }}	  |d¬¦  «        }|rt           	                    d||¦  «         Œ1# t          $ r&}t                               d||¦  «         Y d}~Œ\d}~ww xY w||z  dk    r_	  |	¦   «         \  }}|rt           	                    d||¦  «         n2# t          $ r%}t                               d|¦  «         Y d}~nd}~ww xY w||z  dk    rÝ	 ddlm}  |t'          d¦  «        d„ ¬¦  «         n2# t          $ r%}t                               d|¦  «         Y d}~nd}~ww xY w	 ddlm}  |¦   «          n2# t          $ r%}t                               d |¦  «         Y d}~nd}~ww xY w	 dd!lm}  |¦   «          n2# t          $ r%}t                               d"|¦  «         Y d}~nd}~ww xY w||z  dk    �r	 dd#lm} dd$lm}  |¦   «                              d%¦  «        pi }|                     d&d'¦  «        r’ |¦   «         } 	 |                      t'          |                     d(d)¦  «        ¦  «        t;          |                     d*d¦  «        ¦  «        ¬+¦  «         |                      ¦   «          n# |                      ¦   «          w xY wn2# t          $ r%}t                               d,|¦  «         Y d}~nd}~ww xY w||z  dk    rY	 dd-lm }!  |!d.¬/¦  «         nE# t          $ r8}"t                               d0tC          |"¦  «        j"        |"¦  «         Y d}"~"nd}"~"ww xY w|  #                    |¬¦  «         |  
                    ¦   «         �¯àt           	                    d1¦  «         dS )2uÕ  Background thread for gateway-only periodic chores (NOT cron).

    Split out of the historical ``_start_cron_ticker`` so the cron *trigger*
    can live behind the ``CronScheduler`` provider (built-in or external) while
    these gateway-specific chores keep running independently of which provider
    fires cron. An external scale-to-zero provider has no 60s loop at all, but
    this housekeeping still wants its hourly cadence â€” so it owns its own loop.

    Refreshes the channel directory every 5 minutes and prunes the
    image/audio/video/document/screenshot caches + expired ``hermes debug
    share`` pastes once per hour, and polls the curator hourly (its inner
    gate enforces the real weekly cadence).
    r   )Úcleanup_audio_cacheÚcleanup_document_cacheÚcleanup_image_cacheÚcleanup_screenshot_cacheÚcleanup_video_cache)Ú_sweep_expired_pastesrø  r²  r(   ÚImageÚDocumentÚAudioÚVideoÚ
Screenshotz+Gateway housekeeping started (interval=%ds)ri  Nz*Channel directory refresh scheduling errorr¬  r  r  z#Channel directory refresh error: %sr  )Úmax_age_hoursz*%s cache cleanup: removed %d stale file(s)z%s cache cleanup error: %sz4Paste sweep: deleted %d expired paste(s), %d pendingzPaste sweep error: %s)Úmaybe_run_curatorrK	  c                 ó8   — t                                d| ¦  «        S )Nzcurator: %srh  )r§  s    r>   rò   z-_start_gateway_housekeeping.<locals>.<lambda>ƒi  s   € ­6¯;ª;°}ÀcÑ+JÔ+J€ rM   )Úidle_for_secondsÚ
on_summaryzCurator tick error: %s)Úmaybe_pull_skillszSync pull tick error: %s)Úmaybe_pull_org_skillszOrg sync pull tick error: %src  )rj  r“  rk  Frl  r)   rm  rn  zAuto-archive tick error: %srh  zmessaging gateway housekeepingr  z/gateway housekeeping memory trim failed: %s: %szGateway housekeeping stopped)$r	  rÈ  rÉ  rÊ  rË  rÌ  Úhermes_cli.debugrÍ  r3   rz  r8  r¥  rj  r   r·  r2   r4   Úagent.curatorrÔ  ri  Útools.skills_sync_clientrØ  rÙ  r˜  rd  r°  rj  rv   r±  rh  rk
  rk  ri  rÎ   rÏ   rB  )#rÀ  r°  rØ   r		  rÈ  rÉ  rÊ  rË  rÌ  rÍ  ÚIMAGE_CACHE_EVERYÚCHANNEL_DIR_EVERYÚPASTE_SWEEP_EVERYÚCURATOR_EVERYÚAUTO_ARCHIVE_EVERYÚMEMORY_TRIM_EVERYÚMEDIA_CACHE_CLEANUPSÚ
tick_countrj  rÝ  r¨  Ú
cache_nameÚ
cleanup_fnr,	  ÚdeletedÚ	remainingrÔ  rØ  rÙ  rÂ  rj  rÇ  Ú_adbri  r<   s#                                      r>   Ú_start_gateway_housekeepingrê  &i  s™  € ðð ð ð ð ð ð ð ð ð ð ð ð ð ð 7Ð6Ð6Ð6Ð6Ð6àÐØÐØÐØ€MØÐØÐð
 
Ð%Ð&Ø	Ð+Ð,Ø	Ð%Ð&Ø	Ð%Ð&Ø	Ð/Ð0ðÐõ ‡K‚KÐ=¸xÑHÔHÐHØ€JØ×ÒÑ!Ô!ñ r*Ø�a‰ˆ
àÐ)Ñ)¨QÒ.Ð.°8Ð.ðGØMÐMÐMÐMÐMÐMØÐ#õ
 3Ø/Ð/°Ñ9Ô9¸4Ý%Ø$Pðñ ô �Cð
 �ØŸ
š
¨2˜
Ñ.Ô.Ð.øøÝð Gð Gð GÝ—’ÐBÀAÑFÔFÐFÐFÐFÐFÐFÐFøøøøðGøøøð Ð)Ñ)¨QÒ.Ð.Ø*>ð Nð NÑ&�
˜JðNØ(˜j°rÐ:Ñ:Ô:�GØð gÝŸšÐ$PÐR\Ð^eÑfÔfÐføøÝ ð Nð Nð NÝ—L’LÐ!=¸zÈ1ÑMÔMÐMÐMÐMÐMÐMÐMøøøøðNøøøð Ð)Ñ)¨QÒ.Ð.ð9Ø%:Ð%:Ñ%<Ô%<Ñ"�˜Øð Ý—K’KØNØ ñô ð øøõ ð 9ð 9ð 9Ý—’Ð4°aÑ8Ô8Ð8Ð8Ð8Ð8Ð8Ð8øøøøð9øøøð ˜Ñ%¨Ò*Ð*ð:Ø;Ð;Ð;Ð;Ð;Ð;Ø!Ð!Ý%*¨5¡\¤\ØJÐJðñ ô ð ð øõ ð :ð :ð :Ý—’Ð5°qÑ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9øøøøð:øøøð<ØFÐFÐFÐFÐFÐFØ!Ð!Ñ#Ô#Ð#Ð#øÝð <ð <ð <Ý—’Ð7¸Ñ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;øøøøð<øøøð
@ØJÐJÐJÐJÐJÐJØ%Ð%Ñ'Ô'Ð'Ð'øÝð @ð @ð @Ý—’Ð;¸QÑ?Ô?Ð?Ð?Ð?Ð?Ð?Ð?øøøøð@øøøð Ð*Ñ*¨aÒ/Ñ/ð?ØNÐNÐNÐNÐNÐNØ2Ð2Ð2Ð2Ð2Ð2Ø.Ð.Ñ0Ô0×4Ò4°ZÑ@Ô@ÐFÀB�	Ø—=’= °Ñ7Ô7ð %Ø$˜9™;œ;�Dð%Ø×/Ò/Ý&+¨I¯MªMÐ:MÈqÑ,QÔ,QÑ&RÔ&RÝ/2°9·=²=ÐAUÐWYÑ3ZÔ3ZÑ/[Ô/[ð 0ñ ô ð ð
 Ÿ
š
™œ˜˜ø˜Ÿ
š
™œ˜˜øøøøøÝð ?ð ?ð ?Ý—’Ð:¸AÑ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>øøøøð?øøøð Ð)Ñ)¨QÒ.Ð.ðØ;Ð;Ð;Ð;Ð;Ð;à�Ð#CÐDÑDÔDÐDÐDøÝð 	ð 	ð 	õ
 —’ØEÝ˜‘I”IÔ&Øñô ð ð ð ð ð ð øøøøð	øøøð 	�Š ˆÑ)Ô)Ð)ðe ×ÒÑ!Ô!ñ r*õf ‡K‚KÐ.Ñ/Ô/Ð/Ð/Ð/sÛ   Á5AB7 Â7
C&ÃC!Ã!C&Ã:*D%Ä%
EÄ/EÅEÅ"+F Æ
F=ÆF8Æ8F=Ç
!G, Ç,
HÇ6HÈHÈH0 È0
IÈ:IÉIÉ#I4 É4
J#É>JÊJ#Ê1AN Ë=AM+ ÍN Í+NÎN Î
N4ÎN/Î/N4ÏO Ï
PÏ.PÐPc                 óT   — ddl m}  |¦   «                              | |||¬¦  «         dS )u  DEPRECATED shim â€” preserved for backward compatibility.

    The cron trigger now lives behind the ``CronScheduler`` provider
    (``cron.scheduler_provider``); the gateway resolves a provider and runs its
    ``start()`` directly (see ``start_gateway``). This shim runs ONLY the
    built-in in-process tick loop, exactly as before, for any external caller
    or test that still references this symbol (e.g. hermes_cli/debug.py). It no
    longer runs gateway housekeeping â€” that moved to
    ``_start_gateway_housekeeping``.
    r   )ÚInProcessCronScheduler)r°  rØ   r		  N)Úcron.scheduler_providerrì  r§  )rÀ  r°  rØ   r		  rì  s        r>   Ú_start_cron_tickerrî  Æi  sC   € ð ?Ð>Ð>Ð>Ð>Ð>ØÐÑÔ×"Ò" :¸ÀtÐV^Ð"Ñ_Ô_Ð_Ð_Ð_rM   g     @P@g     €A@r)
  r¶  Úpollc              ƒ   óÌ  K  — | €dS t          j        ¦   «                              ¦   «         t          d|¦  «        z   }|                      ¦   «         r€t          j        ¦   «                              ¦   «         |k     rWt          j        |¦  «        ƒ d{V —† |                      ¦   «         r)t          j        ¦   «                              ¦   «         |k     °W|                      ¦   «          S )u¨  Wait for a daemon thread to exit WITHOUT blocking the event loop.

    A synchronous ``thread.join()`` here would freeze the event loop â€” fatal
    for the cron ticker, whose in-flight delivery is a coroutine scheduled onto
    *this* loop via ``safe_schedule_threadsafe``. Blocking the loop deadlocks
    that delivery (the loop can never run it), so ``join(timeout=5)`` always
    times out and the message is silently dropped on restart (#58818).

    Polling ``is_alive()`` with ``await asyncio.sleep`` keeps the loop running
    so the pending delivery completes, then the ticker sees ``stop_event`` and
    exits. Returns True if the thread exited within ``timeout``.
    NTr@  )r  r!
  rU   rC  r  r–  )r¶  rÓ  rï  r+
  s       r>   Ú_await_thread_exitrñ  èi  sÔ   è è € ð €~ØˆtÝÔ'Ñ)Ô)×.Ò.Ñ0Ô0µ3°s¸GÑ3DÔ3DÑD€HØ
�/Š/Ñ
Ô
ð "¥Ô 8Ñ :Ô :× ?Ò ?Ñ AÔ AÀHÒ LÐ LÝŒm˜DÑ!Ô!Ð!Ð!Ð!Ð!Ð!Ð!Ð!ð �/Š/Ñ
Ô
ð "¥Ô 8Ñ :Ô :× ?Ò ?Ñ AÔ AÀHÒ LÐ Là�ŠÑ Ô Ð Ð rM   r	  c                 óÂ   — t          | dd¦  «        }|€dS d| _        	 |                     ¦   «          dS # t          $ r  t                               dd¬¦  «         Y dS w xY w)z9Idempotently drain and detach Gateway Health OTLP export.r�  Nz*gateway health OTLP export shutdown failedTrß   )rV   r�  r	  r2   r3   r4   )r	  r¿  s     r>   r�  r�  ÿi  sƒ   € å�fÐ>ÀÑEÔE€GØ€ØˆØ,0€FÔ)ðRØ×ÒÑÔÐÐÐøÝð Rð Rð RÝ�ŠÐAÈDˆÑQÔQÐQÐQÐQÐQðRøøøs   ž4 ´&AÁArl  Ú	verbosityc              ƒ   óh  ‡@‡AK  — ddl m}  |¦   «          ddlm}m}m}m}m}m}	  |¦   «         }
|
��P|
t          j
        ¦   «         k    �r8|�ré ||
¦  «        }t                               d|
¦  «         	 ddlm}  ||
¦  «         n2# t          $ r%}t                               d|¦  «         Y d}~nd}~ww xY w	 ddlm}  ||
¦  «        }n# t          $ r g }Y nw xY w	  |	|
d	¬
¦  «         n`# t"          $ r Y nTt$          t&          f$ rA t                               d|
¦  «         	 ddlm}  |¦   «          n# t          $ r Y nw xY wY d	S w xY wddlm} d	}t/          d¦  «        D ]%} ||
¦  «        sd} nÛt1          j        d¦  «         Œ&t                               d|
¦  «         	  |	|
d¬
¦  «         n$# t"          $ r d}Y nt$          t&          f$ r Y nw xY w|s5t/          d¦  «        D ]%} ||
¦  «        sd} nt1          j        d¦  «         Œ&|s?t                               d|
¦  «         	 ddlm}  |¦   «          n# t          $ r Y nw xY wd	S 	 ddlm}  |||
¬¦  «         n-# t          $ r  t                               d|
d¬¦  «         Y nw xY w |¦   «          	 t9          ¦   «         dz                       d¬¦  «         n# t          $ r Y nw xY w	 ddlm}  |¦   «          n# t          $ r Y nw xY w	 ddlm}  ||
|¬¦  «        }|rt                               d|¦  «         n\# t          $ r Y nPw xY wt?          t9          ¦   «         ¦  «        }t                               d|
|¦  «         tA          d|
› d�¦  «         d	S 	 dd l!m"}  |d¬!¦  «         n# t          $ r Y nw xY wdd"l#m$}m%}  |tL          d#¬$¦  «         	 dd%l'm(} d}	 dd&l)m*}  |¦   «         }n# t          $ r d}Y nw xY w |tL          |¬'¦  «         n2# t          $ r%}t                               d(|¦  «         Y d}~nd}~ww xY w|�ôdd)l+m,} tZ          j.        tZ          j/        d*œ 0                    |tZ          j1        ¦  «        } t[          j2         |¦   «         ¦  «        }!|! 3                    | ¦  «         |! 4                     |d+¦  «        ¦  «         t[          j5        ¦   «          6                    |!¦  «         | t[          j5        ¦   «         j7        k     r&t[          j5        ¦   «          3                    | ¦  «         tq          | ¦  «        ŠAts          |¦  «        ‰A_:        d	Š@dXˆ@ˆAfd,„	}"ˆAfd-„}#tw          j<        ¦   «         }$|$ =                    t|          ¦  «         t          j@        ¦   «         t          jA        ¦   «         u r‹t„          jC        t„          jD        fD ]*}%	 |$ E                    |%|"|%¦  «         Œ# tŒ          $ r Y Œ'w xY wt�          t„          d.¦  «        r2	 |$ E                    t„          jH        |#¦  «         n+# tŒ          $ r Y nw xY wnt                               d/¦  «         t          jI        ¦   «         }&t          jJ        t–          |&‰A|$|"fdd0¬1¦  «        }'|' L                    ¦   «          ddlM}(dd2lmN})m}m}  |¦   «         }*|*�4|*t          j
        ¦   «         k    rt                               d3|*¦  «         d	S  |¦   «         st                               d4¦  «         d	S 	  |)¦   «          n5# tž          $ r(  |¦   «          t                               d5¦  «         Y d	S w xY w|( P                    |¦  «         |( P                    |¦  «         	 dd6lQmR}+  |+¦   «          n2# t          $ r%},t                               d7|,¦  «         Y d},~,nd},~,ww xY w	 dd8lSmT}-  |-¦   «          n2# t          $ r%}.t                               d9|.¦  «         Y d}.~.nd}.~.ww xY wt«          ¦   «          	 dd:lVmW}/ tw          j<        ¦   «         }0|0 X                    d|/¦  «        ƒ d{V —† n2# t          $ r%}t                               d;|¦  «         Y d}~nd}~ww xY w	 ‰A L                    ¦   «         ƒ d{V —†}1n# t²          $ r tµ          ‰A¦  «         ‚ w xY w|1stµ          ‰A¦  «         d	S 	 dd<l[m\}2  |2¦   «         }3|3rt                               d=|3¦  «         n# t          $ r Y nw xY w‰Aj]        rStµ          ‰A¦  «         ‰Aj^        r t                               d>‰Aj^        ¦  «         ‰Aj_        �tÁ          ‰Aj_        ¦  «        ‚dS ‰Aja        s¾	 ‰A b                    ¦   «         ƒ d{V —† ‰Ajc        r9‰Aj^        r t                               d?‰Aj^        ¦  «         	 tµ          ‰A¦  «         d	S 	 dd@lVmd}4  |4¦   «          n# t          $ r Y nw xY w‰Aj_        �tÁ          ‰Aj_        ¦  «        ‚	 tµ          ‰A¦  «         dS # tµ          ‰A¦  «         w xY wddAlemf}5mg}6 t          jI        ¦   «         }7 |6¦   «         }8‰Ajh        tw          j<        ¦   «         dBœ}9tÓ          |8|5¦  «        r£tÕ          ‰Ajk        dCd	¦  «        r�	 ddDllmm}: tÝ           |:d¬E¦  «        ¦  «        };|;r8|;|9dF<   t                               dGtß          |;¦  «        dH„ |;D ¦   «         ¦  «         n2# t          $ r%}.t                               dI|.¦  «         Y d}.~.nd}.~.ww xY wtÓ          |8|5¦  «        rˆAfdJ„|9dK<   t          jJ        |8jL        |7f|9ddL¬M¦  «        }<|< L                    ¦   «          t          jJ        tà          |7f‰Ajh        tw          j<        ¦   «         dBœddN¬M¦  «        }=|= L                    ¦   «          tÕ          ‰AdOd¦  «        }>tã          |>¦  «        r
 |>¦   «          ‰A b                    ¦   «         ƒ d{V —† 	 ddPlSmr}?  |?¦   «          n# t          $ r Y nw xY w‰Ajc        r)‰Aj^        r t                               d?‰Aj^        ¦  «         d	S |7 s                    ¦   «          	 |8 t                    ¦   «          n2# t          $ r%}t                               dQ|¦  «         Y d}~nd}~ww xY wtë          |<tì          ¬R¦  «        ƒ d{V —†s t                               dStì          ¦  «         të          |=tî          ¬R¦  «        ƒ d{V —† |& s                    ¦   «          |' x                    dT¬R¦  «         	 dd@lVmd}4  |4¦   «          n# t          $ r Y nw xY w‰Aj_        �tÁ          ‰Aj_        ¦  «        ‚‰@r#‰Ajy        st                               dU¦  «         d	S ‰Ajz        r)t                               dV¦  «         tÁ          dW¦  «        ‚dS )Ya7  
    Start the gateway and run until interrupted.
    
    This is the main entry point for running the gateway.
    Returns True if the gateway ran successfully, False if it failed to start.
    A False return causes a non-zero exit code so systemd can auto-restart.
    
    Args:
        config: Optional gateway configuration override.
        replace: If True, kill any existing gateway instance before starting.
                 Useful for systemd services to avoid restart-loop deadlocks
                 when the previous process hasn't fully exited yet.
    r   )Úrecord_boot_fingerprint)Úacquire_gateway_runtime_lockÚget_running_pidÚget_process_start_timerˆ  r‡  Úterminate_pidNz<Replacing existing gateway instance (PID %d) with --replace.)Úwrite_takeover_markerz#Could not write takeover marker: %s)Ú_snapshot_gateway_childrenFrì   z1Permission denied killing PID %d. Cannot replace.)Úclear_takeover_marker)Ú_pid_existsr�  Tr¿  zAOld gateway (PID %d) did not exit after SIGTERM, sending SIGKILL.g      Ð?zjOld gateway (PID %d) still appears alive after SIGKILL; aborting replacement to avoid a duplicate gateway.)Úreap_gateway_children)Ú
parent_pidz-Child reap for replaced gateway PID %d failedrß   zgateway.pidrs  )Úrelease_all_scoped_locks)Ú	owner_pidÚowner_start_timez2Released %d stale scoped lock(s) from old gateway.z‘Another gateway instance is already running (PID %d, HERMES_HOME=%s). Use 'hermes gateway restart' to replace it, or 'hermes gateway stop' first.u"   
â�Œ Gateway already running (PID zš).
   Use 'hermes gateway restart' to replace it,
   or 'hermes gateway stop' to kill it first.
   Or use 'hermes gateway run --replace' to auto-replace.
)Úsync_skills)Úquiet)Úsetup_loggingÚ_safe_stderrr9   )r€  rf  )Úlog_startup_security_warnings)r€  )r€  rz   z-Startup security audit failed (non-fatal): %srÛ  )r   r(   z#%(levelname)s %(name)s: %(message)sc                 ó†  •— d}	 ddl m}  |¦   «         }n2# t          $ r%}t                               d|¦  «         Y d }~nd }~ww xY wd}| t
          j        k    rd}nF|sD	 ddl m}  |¦   «         }n2# t          $ r%}t                               d|¦  «         Y d }~nd }~ww xY w	 ddlm	}m
}m}  || ¦  «        }	n4# t          $ r'}
d }	t                               d	|
¦  «         Y d }
~
nd }
~
ww xY w|r&t                               d
|	r|	d         nd¦  «         nV|r&t                               d|	r|	d         nd¦  «         n.dŠd‰_        t                               d|	r|	d         nd¦  «         |	�­	 t                               d ||	¦  «        ¦  «         n2# t          $ r%}
t                               d|
¦  «         Y d }
~
nd }
~
ww xY w	 t          dz  dz  } |||	d         d¬¦  «         n2# t          $ r%}
t                               d|
¦  «         Y d }
~
nd }
~
ww xY wt!          j        ‰                     ¦   «         ¦  «         d S )NFr   )Ú consume_takeover_marker_for_selfz Takeover marker check failed: %sT)Ú$consume_planned_stop_marker_for_selfz$Planned stop marker check failed: %s)Úformat_context_for_logÚsnapshot_shutdown_contextÚspawn_async_diagnosticz$snapshot_shutdown_context failed: %su?   Received %s as a planned --replace takeover â€” exiting cleanlyrŒ  ÚSIGTERMu9   Received %s as a planned gateway stop â€” exiting cleanlyzSIGTERM/SIGINTu#   Received %s â€” initiating shutdownzShutdown context: %sz!format_context_for_log failed: %sr  zgateway-shutdown-diag.logr&   )r8  z!spawn_async_diagnostic failed: %s)r;	  r	  r2   r3   r4   rŒ  ÚSIGINTr
  r�  r  r  r  rz  r˜  rã   rl  r  r”  r¨  )Úreceived_signalÚplanned_takeoverr	  r¨  Úplanned_stopr
  r  r  r  Ú_shutdown_ctxrÄ  Ú	_diag_logr˜  r	  s               €€r>   Úshutdown_signal_handlerz.start_gateway.<locals>.shutdown_signal_handlerÿj  s†  ø€ ð !Ðð	@ØGÐGÐGÐGÐGÐGØ?Ð?ÑAÔAÐÐøÝð 	@ð 	@ð 	@Ý�LŠLÐ;¸QÑ?Ô?Ð?Ð?Ð?Ð?Ð?Ð?øøøøð	@øøøð ˆØ�fœmÒ+Ð+ØˆLˆLØ!ð 	HðHØOÐOÐOÐOÐOÐOØCÐCÑEÔE��øÝð Hð Hð HÝ—’ÐCÀQÑGÔGÐGÐGÐGÐGÐGÐGøøøøðHøøøð		Eðð ð ð ð ð ð ð ð ð ð
 6Ð5°oÑFÔFˆMˆMøÝð 	Eð 	Eð 	EØ ˆMÝ�LŠLÐ?ÀÑDÔDÐDÐDÐDÐDÐDÐDøøøøð	Eøøøð ð 	Ý�KŠKØQØ+8ÐG�˜hÔ'Ð'¸iñô ð ð ð ð 	Ý�KŠKØKØ+8ÐN�˜hÔ'Ð'Ð>Nñô ð ð ð
 *.Ð&ð 15ˆFÔ-Ý�KŠKØ5Ø+8ÐN�˜hÔ'Ð'Ð>Nñô ð ð Ð$ðFÝ—’Ø*Ð,BÐ,BÀ=Ñ,QÔ,Qñô ð ð øõ ð Fð Fð FÝ—’Ð@À"ÑEÔEÐEÐEÐEÐEÐEÐEøøøøðFøøøðFÝ(¨6Ñ1Ð4OÑO�	Ø&Ð&Ø˜}¨XÔ6Èðñ ô ð ð øõ ð Fð Fð FÝ—’Ð@À"ÑEÔEÐEÐEÐEÐEÐEÐEøøøøðFøøøåÔ˜FŸKšK™MœMÑ*Ô*Ð*Ð*Ð*st   … –
A A Á AÁ A1 Á1
B Á;BÂB Â$B: Â:
C+ÃC&Ã&C+Å/$F Æ
GÆF>Æ>GÇ!G) Ç)
HÇ3HÈHc                  ó6   •— ‰                       dd¬¦  «         d S )NFTr¾
  )rÇ
  ©r	  s   €r>   Úrestart_signal_handlerz-start_gateway.<locals>.restart_signal_handler^k  s"   ø€ Ø×Ò¨¸4ÐÑ@Ô@Ð@Ð@Ð@rM   ÚSIGUSR1z6Skipping signal handlers (not running in main thread).zplanned-stop-watcherr  )Úwrite_pid_filer‡  r÷  z^Another gateway instance (PID %d) started during our startup. Exiting to avoid double-running.zBGateway runtime lock is already held by another instance. Exiting.z8PID file race lost to another gateway instance. Exiting.)Úrecord_startupz*Lifecycle ledger startup record failed: %s)Ústart_nous_auth_keepalivez%Nous auth keepalive did not start: %s)r§  zMCP tool discovery failed: %s)Úrecover_pending_to_dbz3Recovered %d pending message(s) from shutdown flushzGateway exiting cleanly: %sz Gateway exiting with failure: %s)r¦  )rì  Úresolve_cron_scheduler)r°  rØ   r½  )r¤  r¥  Úprofile_homesz:Cron scheduler will tick %d profile(s) under multiplex: %sc                 óL   — g | ]!}t          |t          ¦  «        r|d          n|‘Œ"S rU  rV  r:  s     r>   r  z!start_gateway.<locals>.<listcomp>&l  s/   € ÐPÐPÐP¸Q�Z¨­5Ñ1Ô1Ð8�Q�q”T�T°qÐPÐPÐPrM   z6Could not resolve profile homes for multiplex cron: %sc                  ó"   •— ‰ j         p‰ j         S r^   )r*  r+  r  s   €r>   rò   zstart_gateway.<locals>.<lambda>2l  s   ø€ ØÔÐ= Ô =ð5
€ rM   Úcan_dispatchzcron-scheduler)r  r¸  rF  r  rÖ   zgateway-housekeepingr_  )Ústop_nous_auth_keepalivezCron provider stop() error: %sr  ub   Cron ticker did not exit within %.0fs of shutdown â€” an in-flight delivery may have been dropped.r|  z}Exiting with code 1 (signal-initiated shutdown without restart request) so systemd Restart=on-failure can revive the gateway.z_Exiting with code 75 (service-restart requested) so the service manager relaunches the gateway.éK   r^   ){Úgateway.code_skewrõ  r;	  rö  r÷  rø  rˆ  r‡  rù  r’   r‘
  r3   rz  rú  r2   r4   rû  ÚProcessLookupErrorÚPermissionErrorr–   rP   rü  rý  r  rU   r–  rã   rþ  rx  ru  r   rw   ÚprintÚtools.skills_syncr  Úhermes_loggingr  r  rl  Ú!hermes_cli.security_audit_startupr  r˜  r€  ró   rÜ  rS  ÚWARNINGrâ  rv   ÚDEBUGÚStreamHandlerrá  rà  rT  rä  Úlevelr
  rº   rV  r  r!
  Úset_exception_handlerrç   r¤  Úcurrent_threadÚmain_threadrŒ  r  r  Úadd_signal_handlerÚNotImplementedErrorrá   r  r¹  r¥  rÆ  r§  Úatexitr  ÚFileExistsErrorrN  Úgateway.lifecycle_ledgerr  Úhermes_cli.nous_auth_keepaliver  r«   r¬  r§  r„  rÓ  r�  rQ
  r  r2  r6  r8  Ú
SystemExitr’  r¢  r4  r¦  rí  rì  r  r°  rt   rV   rz   r?  r¤  r½  r7   rê  r/  r#  r•   r¨  rñ  Ú_CRON_SHUTDOWN_DRAIN_TIMEOUTÚ$_HOUSEKEEPING_SHUTDOWN_DRAIN_TIMEOUTrf   r,  r/  )Brz   rl  ró  rõ  rö  r÷  rø  rˆ  r‡  rù  Úexisting_pidÚexisting_start_timerú  r¨  rû  Ú_old_gateway_childrenrü  rý  Úold_gateway_exitedrK  rþ  r   Ú	_releasedr€  r  r  r  r  Ú
_audit_cfgr€  Ú
_audit_excrÜ  Ú_stderr_levelÚ_stderr_handlerr  r  rØ   ÚsigÚ_planned_stop_watcher_stopÚ_planned_stop_watcher_threadr5  r  Ú_current_pidÚ_lifecycle_record_startupÚ_lc_excr  r<   r§  Ú_loopr/  r  re  r¦  rì  r  Ú	cron_stopÚcron_providerÚcron_start_kwargsr¤  r  Úcron_threadÚhousekeeping_threadÚstart_watchdogr#  r˜  r	  sB                                                                   @@r>   Ústart_gatewayrR  j  s²  øøè è € ð$ :Ð9Ð9Ð9Ð9Ð9ØÐÑÔÐðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð #�?Ñ$Ô$€LØÑ LµB´I±K´KÒ$?Ñ$?Øñ Q	Ø"8Ð"8¸Ñ"FÔ"FÐÝ�KŠKØNØñô ð ðGØ@Ð@Ð@Ð@Ð@Ð@Ø%Ð% lÑ3Ô3Ð3Ð3øÝð Gð Gð GÝ—’ÐBÀAÑFÔFÐFÐFÐFÐFÐFÐFøøøøðGøøøð+ØEÐEÐEÐEÐEÐEØ(BÐ(BÀ<Ñ(PÔ(PÐ%Ð%øÝð +ð +ð +Ø(*Ð%Ð%Ð%ð+øøøðØ�˜l°%Ð8Ñ8Ô8Ð8Ð8øÝ%ð ð ð Ø�Ý#¥WÐ-ð ð ð Ý—’ØGØ ñô ð ðØDÐDÐDÐDÐDÐDØ)Ð)Ñ+Ô+Ð+Ð+øÝ ð ð ð Ø�Dðøøøà�u�uðøøøð  3Ð2Ð2Ð2Ð2Ð2Ø!&ÐÝ˜2‘Y”Yð (!ð (!�Ø"�{ <Ñ0Ô0ð Ø)-Ð&Ø�EÝ”
˜3‘”��õ —’ØWØ ñô ð ðØ!�M ,°dÐ;Ñ;Ô;Ð;Ð;øÝ)ð .ð .ð .Ø)-Ð&Ð&Ð&Ý'­Ð1ð ð ð Ø�Dðøøøð *ð )Ý" 2™YœYð )ð )˜Ø*˜{¨<Ñ8Ô8ð "Ø15Ð.Ø!˜EÝœ
 4Ñ(Ô(Ð(Ð(Ø)ð !Ý—L’LðMà$ñô ð ð
ØHÐHÐHÐHÐHÐHØ-Ð-Ñ/Ô/Ð/Ð/øÝ$ð ð ð Ø˜ðøøøà ˜5ð

Ø@Ð@Ð@Ð@Ð@Ð@Ø%Ð%Ø)°lðñ ô ð ð øõ ð ð ð Ý—’ØCØ Ø!ð ñ ô ð ð ð ðøøøð ˆOÑÔÐðÝ Ñ"Ô" ]Ñ2×:Ò:ÀdÐ:ÑKÔKÐKÐKøÝð ð ð Ø�ðøøøðØ@Ð@Ð@Ð@Ð@Ð@Ø%Ð%Ñ'Ô'Ð'Ð'øÝð ð ð Ø�ðøøøð
	ØCÐCÐCÐCÐCÐCØ4Ð4Ø*Ø%8ðñ ô �	ð ð aÝ—K’KÐ TÐV_Ñ`Ô`Ð`øøÝð ð ð Ø�ðøøøõ �oÑ/Ô/Ñ0Ô0ˆKÝ�LŠLð^à˜kñô ð õ
 ðO°lð Oð Oð Oñô ð ð �5ðØ1Ð1Ð1Ð1Ð1Ð1Øˆ˜$ÐÑÔÐÐøÝð ð ð Øˆðøøøð ;Ð:Ð:Ð:Ð:Ð:Ð:Ð:Ø€M�l°Ð;Ñ;Ô;Ð;ðRØSÐSÐSÐSÐSÐSàˆ
ð	Ø9Ð9Ð9Ð9Ð9Ð9à(˜Ñ*Ô*ˆJˆJøÝð 	ð 	ð 	ØˆJˆJˆJð	øøøà%Ð%µ,ÀzÐRÑRÔRÐRÐRøÝð Rð Rð RÝ�ŠÐDÀjÑQÔQÐQÐQÐQÐQÐQÐQøøøøðRøøøð ÐØ3Ð3Ð3Ð3Ð3Ð3å#œOµ´Ð=Ð=×AÒAÀ)ÍWÌ]Ñ[Ô[ˆÝ!Ô/°°±´Ñ?Ô?ˆØ× Ò  Ñ/Ô/Ð/Ø×$Ò$Ð%7Ð%7Ð8]Ñ%^Ô%^Ñ_Ô_Ð_ÝÔÑÔ×&Ò& Ñ7Ô7Ð7à�7Ô,Ñ.Ô.Ô4Ò4Ð4ÝÔÑÔ×(Ò(¨Ñ7Ô7Ð7å˜6Ñ"Ô"€Fõ /3°7©m¬m€FÔ+ð "'Ðð]+ð ]+ð ]+ð ]+ð ]+ð ]+ð ]+ð~Að Að Að Að Aõ Ô#Ñ%Ô%€Dð 	×ÒÕ>Ñ?Ô?Ð?åÔÑ!Ô!¥YÔ%:Ñ%<Ô%<Ð<Ð<Ý”M¥6¤>Ð2ð 	ð 	ˆCðØ×'Ò'¨Ð-DÀcÑJÔJÐJÐJøÝ&ð ð ð Ø�ðøøøå•6˜9Ñ%Ô%ð 	ðØ×'Ò'­¬Ð8NÑOÔOÐOÐOøÝ&ð ð ð Ø�ðøøøð	õ 	�ŠÐLÑMÔMÐMõ "+¤Ñ!2Ô!2ÐÝ#,Ô#3Ý(Ø(¨&°$Ð8OÐPØØ#ð	$ñ $ô $Ð ð !×&Ò&Ñ(Ô(Ð(ð €M€M€MØOÐOÐOÐOÐOÐOÐOÐOÐOÐOØ"�?Ñ$Ô$€LØÐ LµB´I±K´KÒ$?Ð$?Ý�Šð/Ø0<ñ	
ô 	
ð 	
ð ˆuØ'Ð'Ñ)Ô)ð Ý�ŠØPñ	
ô 	
ð 	
ð ˆuðØˆÑÔÐÐøÝð ð ð Ø$Ð$Ñ&Ô&Ð&Ý�ŠØFñ	
ô 	
ð 	
ð ˆuˆuðøøøð ‡O‚O�OÑ$Ô$Ð$Ø
‡O‚OÐ0Ñ1Ô1Ð1ðLØXÐXÐXÐXÐXÐXØ!Ð!Ñ#Ô#Ð#Ð#øÝð Lð Lð LÝ�ŠÐAÀ7ÑKÔKÐKÐKÐKÐKÐKÐKøøøøðLøøøðCØLÐLÐLÐLÐLÐLà!Ð!Ñ#Ô#Ð#Ð#øÝð Cð Cð CÝ�ŠÐ<¸cÑBÔBÐBÐBÐBÐBÐBÐBøøøøðCøøøõ )Ñ*Ô*Ð*ð9Ø5Ð5Ð5Ð5Ð5Ð5ÝÔ(Ñ*Ô*ˆØ×#Ò# DÐ*<Ñ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=Ð=øÝð 9ð 9ð 9Ý�ŠÐ4°aÑ8Ô8Ð8Ð8Ð8Ð8Ð8Ð8øøøøð9øøøðØŸš™œÐ&Ð&Ð&Ð&Ð&Ð&ˆˆøÝð ð ð Ý'¨Ñ/Ô/Ð/Øðøøøð ð Ý'¨Ñ/Ô/Ð/ØˆuðØ@Ð@Ð@Ð@Ð@Ð@Ø)Ð)Ñ+Ô+ˆ	Øð 	Ý�KŠKØEÀyñô ð øøõ ð ð ð ØˆðøøøàÔ!ð Ý'¨Ñ/Ô/Ð/ØÔð 	LÝ�LŠLÐ6¸Ô8JÑKÔKÐKð ÔÐ'Ý˜VÔ-Ñ.Ô.Ð.ØˆtØŒ?ð 4ð	4Ø×*Ò*Ñ,Ô,Ð,Ð,Ð,Ð,Ð,Ð,Ð,ØÔ.ð ØÔ%ð YÝ—L’LÐ!CÀVÔEWÑXÔXÐXØõ ,¨FÑ3Ô3Ð3Ð3Ð3ðØ?Ð?Ð?Ð?Ð?Ð?Ø$Ð$Ñ&Ô&Ð&Ð&øÝð ð ð Ø�ðøøøàÔÐ+Ý  Ô!1Ñ2Ô2Ð2Øå+¨FÑ3Ô3Ð3Ð3Ð3øÕ+¨FÑ3Ô3Ð3Ð3øøøð WÐVÐVÐVÐVÐVÐVÐVÝ”Ñ!Ô!€IØ*Ð*Ñ,Ô,€MØ5;´_ÍgÔNfÑNhÔNhÐ(iÐ(iÐõ 	�=Ð"8Ñ9Ô9ðå�F”MÐ#7¸Ñ?Ô?ðð	Ø=Ð=Ð=Ð=Ð=Ð=å Ð!2Ð!2¸TÐ!BÑ!BÔ!BÑCÔCˆMØð Ø5BÐ! /Ñ2Ý—’ØPÝ˜Ñ&Ô&ØPÐPÀ-ÐPÑPÔPñô ð øøõ
 ð 	ð 	ð 	Ý�NŠNØHØñô ð ð ð ð ð ð øøøøð	øøøõ �-Ð!7Ñ8Ô8ð 
ð-
ð -
ð -
ð -
Ð˜.Ñ)õ Ô"ØÔ"Øˆ\Ø ØØðñ ô €Kð ×ÒÑÔÐõ
 $Ô*Ý*Øˆ\Ø"œOµWÔ5MÑ5OÔ5OÐPÐPØØ#ðñ ô Ðð ×ÒÑÔÐõ
 ˜VÐ%>ÀÑEÔE€NÝ�ÑÔð ØˆÑÔÐð ×
"Ò
"Ñ
$Ô
$Ð$Ð$Ð$Ð$Ð$Ð$Ð$ðØKÐKÐKÐKÐKÐKà Ð Ñ"Ô"Ð"Ð"øÝð ð ð Øˆðøøøð Ô&ð ØÔð 	QÝ�LŠLÐ;¸VÔ=OÑPÔPÐPØˆuð ‡M‚M�O„O€Oð:Ø×ÒÑÔÐÐøÝð :ð :ð :Ý�ŠÐ5°qÑ9Ô9Ð9Ð9Ð9Ð9Ð9Ð9øøøøð:øøøå# KÕ9UÐVÑVÔVÐVÐVÐVÐVÐVÐVð 
Ý�Šð.Ý/Kñ	
ô 	
ð 	
õ ØÕ%Iðñ ô ð ð ð ð ð ð ð ð
 ×"Ò"Ñ$Ô$Ð$Ø ×%Ò%¨aÐ%Ñ0Ô0Ð0ðØ7Ð7Ð7Ð7Ð7Ð7ØÐÑÔÐÐøÝð ð ð Øˆðøøøð ÔÐ#Ý˜Ô)Ñ*Ô*Ð*ð "ð ¨&Ô*Cð Ý�ŠðMñ	
ô 	
ð 	
ð ˆuð Ô"ð Ý�Šð.ñ	
ô 	
ð 	
õ ˜‰nŒnÐàˆ4sH  Á4B Â
B5ÂB0Â0B5Â9C ÃCÃCÃC, Ã,
E	Ã8+E	Ä$D5Ä4E	Ä5
EÄ?E	ÅEÅE	ÅE	Æ%F3 Æ3GÇGÇGÈ,H= È=
I
É	I
ÉI$ É$'JÊJÊ%K Ë
KËKËK$ Ë$
K1Ë0K1Ë50L& Ì&
L3Ì2L3ÎN Î
N#Î"N#ÏP  Ï
O ÏP  ÏO*Ï'P  Ï)O*Ï*P  Ð 
P/Ð
P*Ð*P/×W×
W,×+W,Ø X& Ø&
X3Ø2X3Ü
\ Ü.]Ý
]Ý9^
 Þ

^9Þ^4Þ4^9Þ=_ ß
_=ß_8ß8_=à5a á
a4áa/á/a4á8b âb.ã-c3 ã3
d ã?d å%Ah ç g çh ç
gçh çgçh èhê	Ak# ë#
lë-lìlï1p ð
pðpñq, ñ,
rñ6ròrô!t2 ô2
t?ô>t?c                  óÎ  — 	 ddl m}   | ¦   «          n# t          $ r Y nw xY wddl}|                     d¬¦  «        }|                     ddd¬	¦  «         |                     d
ddd¬¦  «         |                     ¦   «         }d}|j        r]ddl}t          |j        d¬¦  «        5 }| 
                    |¦  «        pi }t          j        |¦  «        }ddd¦  «         n# 1 swxY w Y   	 t          j        t          |¦  «        ¦  «        }|rdnd}	nE# t           $ r8}
|
j        €d}	n$t%          |
j        t&          ¦  «        r|
j        }	nd}	Y d}
~
nd}
~
ww xY wt)          |	¦  «         dS )z CLI entry point for the gateway.r   )Úconfigure_windows_stdioNz)Hermes Gateway - Multi-platform messaging)r  z--configr…
  zPath to gateway config file)r>  z	--verboser  Ú
store_truezVerbose output)r?
  r>  rQ  r‚  r(   )Úhermes_cli.stdiorT  r2   ÚargparseÚArgumentParserÚadd_argumentÚ
parse_argsrz   r„  r™  r…  r»  rÐ  r  r®
  rR  r9  r/  rt   rh  Ú_exit_after_graceful_shutdown)rT  rW  Úparserr¸  rz   r„  rˆ  rî  r/  r8  r¨  s              r>   r³  r³   l  só  € ðØ<Ð<Ð<Ð<Ð<Ð<ØÐÑ!Ô!Ð!Ð!øÝð ð ð Øˆðøøøð €O€O€Oà×$Ò$Ð1\Ð$Ñ]Ô]€FØ
×Ò˜
 DÐ/LÐÑMÔMÐMØ
×Ò˜ T°,ÐEUÐÑVÔVÐVà×ÒÑÔ€Dà€FØ„{ð 3ØˆˆˆÝ�$”+¨Ð0Ñ0Ô0ð 	3°AØ—>’> !Ñ$Ô$Ð*¨ˆDÝ"Ô,¨TÑ2Ô2ˆFð	3ð 	3ð 	3ñ 	3ô 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3øøøð 	3ð 	3ð 	3ð 	3ð$
Ý”+�m¨FÑ3Ô3Ñ4Ô4ˆØ Ð'�A�A aˆ	ˆ	øÝð ð ð àŒ6ˆ>ØˆIˆIÝ˜œ¥Ñ$Ô$ð 	ØœˆIˆIàˆIøøøøøøøøøðøøøõ " )Ñ,Ô,Ð,Ð,Ð,s6   ‚ “
 Ÿ Â%,CÃC!Ã$C!Ã)'D Ä
EÄ.EÅEr8  c                 óœ  — t           j        t           j        fD ]'}	 |                     ¦   «          Œ# t          $ r Y Œ$w xY w	 ddlm}m}  |¦   «           |¦   «          n# t          $ r Y nw xY w	 ddlm	}  || d¬¦  «         n# t          $ r Y nw xY w	 ddl
m}  |d¬¦  «         n# t          $ r Y nw xY wt          j        | ¦  «         d	S )
u¤  Flush stdio, release the PID file + runtime lock, then hard-exit.

    Graceful teardown is already complete by the time this runs, so there is
    nothing left that needs a clean interpreter shutdown. We deliberately use
    ``os._exit`` (not ``sys.exit``): ``sys.exit`` raises ``SystemExit``, which
    triggers ``Py_FinalizeEx`` â†’ ``wait_for_thread_shutdown`` and joins every
    non-daemon thread â€” exactly the hang (#53107) a wedged tool-worker causes.

    ``os._exit`` bypasses ``atexit`` handlers, so we cannot rely on the
    ``atexit``-registered ``remove_pid_file`` / ``release_gateway_runtime_lock``
    (registered in ``start_gateway``) to run. The full-shutdown path releases
    both explicitly in ``_stop_impl``, but the EARLY exit paths â€”
    clean-fatal-config (#51228) and startup-aborted-before-running â€” raise
    ``SystemExit`` right after ``runner.start()`` without going through
    ``_stop_impl``, so on those paths ``atexit`` was the only thing releasing
    them. Now that those paths are routed through this backstop (#53107),
    release both here explicitly. Both calls are idempotent â€”
    ``remove_pid_file`` only unlinks a PID file that belongs to this process,
    and ``release_gateway_runtime_lock`` no-ops when the lock is already
    released â€” so this is a no-op on the normal shutdown path and the actual
    cleanup on the early-exit paths.

    Logging IS drained here: the rotating file handlers are driven by an
    async ``QueueListener`` on a dedicated thread (see
    ``hermes_logging._register_queued_handler``), so records emitted right
    before shutdown may still be sitting in the in-memory queue. ``os._exit``
    below bypasses ``atexit``, so the ``atexit``-registered listener drain
    never runs on this path â€” we drain explicitly (bounded, via
    ``drain_log_queue``) or lose the last log lines (including the shutdown
    reason on the early-exit paths). Stdio is flushed too.
    r   r†  )Úmark_exitedÚgraceful_shutdownr  )Údrain_log_queuerB	  r  N)rŽ   r  r  ræ  r2   r;	  r‡  rˆ  r7  r^  r*  r`  r’   Ú_exit)r8  r–  r‡  rˆ  r^  r`  s         r>   r[  r[  Õl  sa  € õ@ ”:�sœzÐ*ð ð ˆð	Ø�LŠL‰NŒNˆNˆNøÝð 	ð 	ð 	ØˆDð	øøøðØPÐPÐPÐPÐPÐPÐPÐPØˆÑÔÐØ$Ð$Ñ&Ô&Ð&Ð&øÝð ð ð ØˆðøøøðØ8Ð8Ð8Ð8Ð8Ð8Øˆ�IÐ&9Ð:Ñ:Ô:Ð:Ð:øÝð ð ð ØˆðøøøðØ2Ð2Ð2Ð2Ð2Ð2Øˆ Ð$Ñ$Ô$Ð$Ð$øÝð ð ð Øˆðøøøå„HˆYÑÔÐÐÐsB   œ1±
>½>ÁA Á
A,Á+A,Á0B Â
BÂBÂB( Â(
B5Â4B5Ú__main__r^   rŽ  r®  rŠ  )r   N)r‰  r   r-   N)r®  r   )r-   r»  )r-   rË  )r1  rý  r-   N)NNrø  )r)
  )NFr   (¯  r«  Úhermes_bootstraprH  r  Úconcurrent.futuresr%  ri  r‰  re  r3  rS  r’   r™  r_   rc	  r›   rŽ   rŒ  r¤  rU   Úcollectionsr   Úcontextvarsr   r  r   r   Útypingr   r	   r
   r   r   r   r   r   r   Úagent.async_utilsr   r   r€  r   r   r   r   r   r   r   r   Úagent.conversation_loopr   Ú
agent.i18nr   Úagent.interrupt_compatr   Úagent.turn_contextr   r˜  r    r!   rÐ  r"   rE  rK  r%  r$  r!  rD  r�  Úcompilerb  r�  Ú
IGNORECASEÚDOTALLr&  r5   r8   rw   ri  r?   rB   rº   rh  rL   rZ   rh   rf   r'  r|   r  r„   r†   Ú_GATEWAY_PROVIDER_ERROR_REr  r  r  rô   r«   rƒ   r´   r½   rÓ  r×   rç   rø   rû   r  r  r  r  r"  r(  r+  r6  r@  ru   rH  r•   rW  rc  r�  rv  rn  rs  ry  r‚  r„  r‹  r’  rž  r¥  r€  r¯  r³  r¶  r  r  r·  r¿  rÇ  rË  rÐ  rÖ  r  r  r  r  r2  Úagent.replay_cleanupró  rô  rõ  r  r  r   rò  r5  r6  rB  rP  r^  rf  ri  rm  ro  rq  rv  r“   r™   rš   r�   r‘   r¶  rx  ry  Úutilsrz  r{  rl  Údotenvr|  r·  r}  Ú	_env_pathr�   r‡  rˆ  r†  r¢  Ú
contextlibr£  Ú_contextmanagerrÆ  r¤  Ú_PORT_BINDING_PLATFORM_VALUESr¥  r´  r¾  r§  r­  rº  r¿  rÇ  rØ  rÙ  Úhermes_cli.config_defaultsrÉ  Ú_DEFAULT_CONFIGÚ_config_pathr˜   r�  rŽ  rF  rt   r™  r�  rš  r2   rñ  ro  Ú_valrv   Ú_terminal_cfgrx   ry   Ú_terminal_backendÚ_terminal_env_mapÚ_cfg_keyÚ_env_varrR	  r½  rB  Ú_auxiliary_cfgÚ_aux_bridged_keysr“  r  rš  r—   Ú	_task_keyÚ	_task_cfgÚ_provÚ_modelÚ	_base_urlrÏ  rd  Ú_upperÚ
_agent_cfgÚ_sessions_cfgrE  Ú_tz_cfgÚ_security_cfgÚ_redactÚ_gateway_cfgÚ_strictÚ_allow_dirsÚ_allow_dirs_strrž   Ú_trust_recentÚ_trust_recent_secondsÚ_bridge_errr(  rÎ   rÏ   r  rE  ÚdirÚ_network_cfgÚ_bootstrap_excrI  rJ  Úgateway.cwd_placeholderrM  rN  Ú_configured_cwdrÆ  r‰  Ú_resolved_cwdrU  rU  rÄ  rV  r»  rÁ  rW  r¾  rr  rX  rY  rZ  r[  r\  r]  r^  r_  r`  ra  rb  Úgateway.deliveryrc  rd  re  Úgateway.turn_leaserf  rg  rh  Úgateway.session_stateri  rp	  rj  rk  rl  Úgateway.authz_mixinrm  Úgateway.kanban_watchersrn  Úgateway.slash_commandsro  Úgateway.turn_contextrp  r	  rG  rq  rr  rs  rt  ru  rv  rw  rx  Úgateway.shutdown_watchdogry  rz  r{  r|  r}  r~  Úgateway.restartr  r€  r�  r‚  rƒ  r„  Úgateway.whatsapp_identityr…  Ú_canonical_whatsapp_identifierr†  Ú_expand_whatsapp_auth_aliasesr‡  Ú_normalize_whatsapp_identifierrT  r3   rº  r  r  r  r¶  r›  r¢  r½  rž  r¬  r^  rÅ  rÈ  rÊ  r½  r×  rÞ  rã  ræ  rê  rð  rõ  r  r"  r%  rt  rw  r9  Ú _INTERRUPT_REASON_SSE_DISCONNECTr�  rŒ  r1  r¹  rº  r;  rE  rG  rI  rN  r^  rq  ru  rz  r}  rs   r”  rÏ  r™  r   r¥  r°  r¸  rÊ  rÓ  Úweakrefr  rÕ  r€  rð  rì  rö  rü  r  r  r  r  r
  r´  rÆ  rê  rî  r:  r;  r¥  rñ  r�  rR  r³  r[  rN  rM   r>   ú<module>rª     sæ/  ððð ð ð"	ØÐÐÐÐøØð 	ð 	ð 	ð
 	€Dð	øøøð €€€Ø Ð Ð Ð Ø Ð Ð Ð Ø Ð Ð Ð Ø €€€Ø €€€Ø €€€Ø 	€	€	€	Ø €€€Ø 	€	€	€	Ø €€€Ø €€€Ø 
€
€
€
Ø €€€Ø Ð Ð Ð Ø €€€Ø #Ð #Ð #Ð #Ð #Ð #Ø $Ð $Ð $Ð $Ð $Ð $Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ UÐ Uà TÐ TÐ TÐ TÐ TÐ TÐ TÐ Tð	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	ð GÐ FÐ FÐ FÐ FÐ FØ Ð Ð Ð Ð Ð Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9ðð ð ð ð ð ð @Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9ð Ð Ø#Ð Ø)-Ð &ð */Ð &Ø+.Ð (ð &*Ð "Ø&6Ð #Ø)˜rœzÐ*TÑUÔUÐ Ø-Ð à&˜BœJð	ð> „M�B”IÑñA!ô !Ð ðH (1Ð $ð !'Ð ð#Ràð#Rð !ð#Rð ð	#Rð #Rð #Rð #RðLE¸ð EÀð Eð Eð Eð Eð)àð)ð ð)ð ð	)ð
 ð)ð ð)ð ð)ð ð)ð 
ð)ð )ð )ð )ð`  ñ	Ið IàðIð ðIð �CŒ=ð	Ið
 
ðIð Ið Ið IðB
=¨ð 
=°ð 
=ð 
=ð 
=ð 
=ð, #- "¤*Ø‡H‚Hð ð ð Ø/Ø1Ø+Ø7Ø6Ø4Ø=ð	
ðñ ô ñ ô ð „Mñ#ô #Ð ð$°tð ð ð ð ð: (˜iØ9Ð9Ð9ñô Ð ð
L¨sð L°tð Lð Lð Lð Lð
 (˜RœZð		ð „Mñô Ð ð )˜bœjð
	ð „Mñô Ð ð $˜œØ]Ø„Mñô Ð ð
 $˜œØ>Ø„Mñô Ð ð €B„JÐ7Ñ8Ô8Ø€B„JÐ1Ñ2Ô2Ø€B„JÐ1Ñ2Ô2Ø€B„JÐ3Ñ4Ô4Ø€B„JÐ)Ñ*Ô*Ø€B„JÐ/Ñ0Ô0Ø€B„JÐ9Ñ:Ô:ðÐ ñ3ð 3ð 3ð 3ðlK cð K¨cð Kð Kð Kð Kð *.ñ
ð ð
ð 
ð 
Ø�t˜C ˜H”~Ô&ð
ð ð
ð ˆd�3˜�8ŒnÔð	
ð 
ð 
ð 
ðØðà˜$˜s C˜xœ.Ô)ðð 
ðð ð ð ð0) ]ð )°tð )ð )ð )ð )ðX,Ø
%ð,Ø04°S¸#°X´ð,à	ð,ð ,ð ,ð ,ðD¨cð °cð ð ð ð ð:= ,ð =°3ð =ð =ð =ð =ð* !ØØðð ð Øðàðð ðð
 ðð ðð ðð 	ðð ð ð ð:¨ð °ð ð ð ð ð( $. 2¤:ð		ð „Mñ$ô $Ð  ð?¨Sð ?°Tð ?ð ?ð ?ð ?ð.$¨sð $¸#ð $À#ð $ð $ð $ð $ðN¨cð ¸sð ÈSð ÐU]Ð^aÔUbð ð ð ð ð<: #ð :ð :ð :ð :ð
Cð 
Cð 
Cð$ !ðð ð Øðàðð ðð
 ðð ˆc„]ðð ð ð ð@	F°ð 	FÀCð 	FÐRUð 	FÐZ^ð 	Fð 	Fð 	Fð 	Fð" ØØ59ð$ð $ð $Øð$àð$ð ð$ð
 ð$ð ð$ð $' s¤8¨d¡?ð$ð 
ð$ð $ð $ð $ðN<¨ð <°sð <¸sð <ð <ð <ð <ðL )0Ð %ð /3Ð +ð Sð ¨X°e¬_ð ð ð ð ðD,¨ð ,ð ,ð ,ð ,ð$B¨Uð Bð Bð Bð BðB˜#ð  (¨5°°c°¬?Ô";ð ð ð ð ð�Sð  5ð ¨Uð ð ð ð ð
1Øð
1à
ð
1ð %ð
1ð ð	
1ð
 
ð
1ð 
1ð 
1ð 
1ð   Ø#'ð	)ð )ð )Øð)ð 
�%Œð)ð ˜%”ð	)ð
 
ð)ð )ð )ð )ð> ñBð ð	Bð Bð BØ�SŒMðBàðBð ð	Bð
 	ðBð Bð Bð BðB-Ð ˜%  S œ/ð ð ñ ð  %ñ	?ð ?Ø
ð?àð?ð 
ˆc�3ˆhŒð?ð ð	?ð
 
ˆ#ˆsˆ(„^ð?ð ?ð ?ð ?ðD ,MÐ (Ø!aÐ ð %OÐ !ð_¸(À3¼-ð _ÈDð _ð _ð _ð _ð	C˜Sð 	C S¨¤Xð 	Cð 	Cð 	Cð 	Cð$¸ð $ÀÀCÄð $ð $ð $ð $ð*) cð )¨cð )ð )ð )ð )ðJ cð J°Cð J¸Dð Jð Jð Jð Jð¨X°d¬^ð Àð ð ð ð ð. %)Ø#ð	f+ð f+ð f+Ø�$�s˜C�x”.Ô!ðf+ð ˜S”Mðf+ð ð	f+ð
 ˆ4��S˜#�X”Ô ¨#¤Ð.Ô/ðf+ð f+ð f+ð f+ðRØ˜D  c œNÔ+ðàðð 
ˆ$ˆs�CˆxŒ.Ôðð ð ð ðD¸ð ÐPXÐY\ÔP]ð Ðbeð ð ð ð ð4¨°°d¸3À¸8´nÔ1EÔ(Fð È3ð ð ð ð ð:!ð !ð !Ð ðð ð ð ð ð ð ð ð ð ð @Ð Ø!>Ð ð Sð ¨Tð ð ð ð ð¨ð °ð ð ð ð ð.  NÐ ð �”ðð „Mñô €ð Ø)-ñN+ð N+Ø�4˜˜S˜”>Ô"ðN+àðN+ð " #œðN+ð ˆ4�Œ9�dˆ?Ôð	N+ð N+ð N+ð N+ðb=°°T¸#¸s¸(´^Ô0Dð =Èð =ð =ð =ð =ñF1ð 1ð 1ð 1ðf3¨ð 3°ð 3ð 3ð 3ð 3ð>¨ð >°ð >ð >ð >ð >ð
< tð <ð <ð <ð <ð
2¨Dð 2ð 2ð 2ð 2ð9¨tð 9ð 9ð 9ð 9ñ
Að Að Að Að !$€„
ÐÑ à Ð Ñ Ô Ð ð „‡‚��3�3�t�t˜H‘~”~Ô,Ô3Ñ4Ô4Ñ 5Ô 5Ð 5ð GÐ FÐ FÐ FÐ FÐ FÐ FÐ FØ 4Ð 4Ð 4Ð 4Ð 4Ð 4Ð 4Ð 4ØˆÑ Ô €ð Ð Ð Ð Ð Ð Ø 4Ð 4Ð 4Ð 4Ð 4Ð 4Ø˜6Ñ!€	Ø Ð ˜|¸¸¸h¹¼×9OÒ9OÑ9QÔ9QÔ9YÐZ[Ô9\Ð_eÑ9eÐ fÑ fÔ fÐ fñ0ð 0ð 0ð 0ñ:#Vð #Vð #Vð #VðL ð ð ð ð ð 9Ð 8Ð 8Ð 8Ð 8Ð 8ðð ð ð ð ð ð ð ðð ð ð ð ˜<ñ ô ð ðPð Pð Pð Pð PÐ&:ñ Pô Pð Pð ñ!/ð !/ð !/ñ „ð!/ñH ð  ð  ð  ðF¨:ð ÐHXð Ð]að ð ð ð ð( $˜œÐ$dÑeÔeÐ Ø(1°:Ð'>Ð $ð
 IÐ HÐ HÐ HÐ HÐ Hà*-¨#Ø�GÔÐ9Ô:ñ+ô +€„
Ð&Ñ 'ð ˜mÑ+€Ø×ÒÑÔñ @
ð
ð 	MÐLÐLÐLÐLÐLÐLÐLØ#Ð# LÑ1Ô1ˆàÐ Ñ%Ô%ˆØˆz˜$ Ñ%Ô%ð 	ØˆDð	Ø0Ð0Ð0Ð0Ð0Ð0Ø6�=Ô6°tÑ<Ô<ˆDˆDøØð 	ð 	ð 	ØˆDð	øøøð Ÿ*š*™,œ,ð 	-ð 	-‰JˆD�$Øˆz˜$  c¨5°$Ð 7Ñ8Ô8ð -¸TÈÌÐ=SÐ=SØ#& 3 t¡9¤9�”
˜4Ñ øð Ÿš ¨RÑ0Ô0ˆØñ :	9˜Z˜Z¨°tÑ<Ô<ñ :	9Ø # Ø×!Ò! )Ñ,Ô,ÐT°´
·²¸~Ñ0NÔ0NÐTÐRTñ!ô !çŠe‰gŒg—e’e‘g”gð ð !Ø˜>ð !àÐ!9ð !ð �~ð !ð Ð-ð	 !ð
 Ð1ð !ð #Ð$?ð !ð Ð 7ð !ð %Ð&Cð !ð $Ð%Að !ð Ð5ð !ð  Ð!9ð !ð !Ð";ð !ð Ð/ð !ð Ñ/ð !ñ Ñ/ð !ñ  Ñ-ð! !ñ"  Ñ!9ð# !ñ$ %@Ù";Ù(GÙ";Ù3Ù%AÙ#=Ù1YÙ";Ù+MÙ3]Ù(GÙ5Ù$?ñ? !ð  !ð  !ÐðB '8×&=Ò&=Ñ&?Ô&?ð 9ð 9Ñ"�˜(Ø˜}Ð,Ð,Ø(¨Ô2�Dð
   5Ò(Ð(¨S¨S°©Y¬YÑ:NÐ-NÐ-NØ ð   5Ò(Ð(¨Z¨Z¸¸cÑ-BÔ-BÐ(Ø7Ð7Ð8IÈ4Ï:Ê:É<Ì<ÑXÔXð <Ø#%¤7×#5Ò#5°dÑ#;Ô#;˜DØ!�z $¨¨t¨Ñ5Ô5ð 9Ø/9¨t¬z¸$Ñ/?Ô/?˜œ
 8Ñ,Ð,à/2¨s°4©y¬y˜œ
 8Ñ,øð Ÿš¡+¨rÑ2Ô2ˆØñ 	I˜j˜j¨¸Ñ>Ô>ñ 	Ið !FÑ EÐ EÐðØIÑIÐIÐIÐIÐIØ8Ð8Ñ:Ô:ð 9ð 9�FØ%×)Ò)¨&±¬-Ñ8Ô8Ð8Ð8ð9øàð ð ð ð �ðøøøð
 /ð Iñ I�	Ø*×.Ò.¨y¸"Ñ=Ô=�	Ø!�z )¨TÑ2Ô2ð ØØ˜˜IŸMšM©*°bÑ9Ô9Ñ:Ô:×@Ò@ÑBÔB�Ø˜˜YŸ]š]©7°BÑ7Ô7Ñ8Ô8×>Ò>Ñ@Ô@�Ø˜C 	§¢©j¸"Ñ =Ô =Ñ>Ô>×DÒDÑFÔF�	Ø˜3˜yŸ}š}©Y¸Ñ;Ô;Ñ<Ô<×BÒBÑDÔD�Ø"ŸšÑ*Ô*�Øð G˜U¡fš_˜_ØAF�B”JÑ=¨FÐ=Ñ=Ð=Ñ>Øð EØ>D�B”JÑ:¨FÐ:Ñ:Ð:Ñ;Øð KØAJ�B”JÑ=¨FÐ=Ñ=Ð=Ñ>Øð IØ@H�B”JÑ<¨FÐ<Ñ<Ð<Ñ=ùð —X’X˜g rÑ*Ô*ˆ
Øñ 	˜*˜* Z°Ñ6Ô6ñ 	Ù˜jÐ(Ð(Ø69°c¸*Á[Ô:QÑ6RÔ6R�”
Ñ2Ñ3Ù  JÐ.Ð.Ø58°S¸ÑDUÔ9VÑ5WÔ5W�”
Ñ1Ñ2Ø+¨zÐ9Ð9Ø:=¸#ØÐ;Ô<ñ;ô ;�”
Ð6Ñ7ñ )¨JÐ6Ð6Ø=@¸SÀÑLeÔAfÑ=gÔ=g�”
Ñ9Ñ:Ù(¨JÐ6Ð6Ø=@¸SÀÑLeÔAfÑ=gÔ=g�”
Ñ9Ñ:Ù&¨*Ð4Ð4Ø=@¸SØÑ6Ô7ñ>ô >�”
Ñ9Ñ:ñ '¨*Ð4Ð4Ø=@¸SÀÑLcÔAdÑ=eÔ=e�”
Ñ9Ñ:Ù0°JÐ>Ð>Ø?B¸sØÑ@ÔAñ@ô @�”
Ñ;Ñ<ñ 7¸*ÐDÐDØEHÀSØÑFÔGñFô F�”
ÑAÑBð
 Ÿš¡¨RÑ0Ô0ˆØð 	˜Z˜Z¨°tÑ<Ô<ð 	Ù˜MÐ)Ð)Ø/2¨s°=ÁÔ3KÑ/LÔ/L�”
Ñ+Ñ,Ù =Ð0Ð0Ø69°cØ!Ñ"2Ô3ñ7ô 7�”
Ñ2Ñ3ð —x’x¡	¨2Ñ.Ô.ˆØð 	˜J˜J |°TÑ:Ô:ð 	Ù  LÐ0Ð0Ø?B¸sÀ<ÑPaÔCbÑ?cÔ?c�”
Ñ;Ñ<Ù <Ð/Ð/Ø>A¸cÀ,ÑO_ÔB`Ñ>aÔ>a�”
Ñ:Ñ;Ù! \Ð1Ð1Ø@CÀÀLÑQcÔDdÑ@eÔ@e�”
Ñ<Ñ=ñ
 )¨LÐ8Ð8Ù;À2Ä:ÐMÐMàFIÀcØ Ñ!9Ô:ñGô G�”
ÑBÑCð —(’(™: rÑ*Ô*ˆØð 	<�z�z '¨3Ñ/Ô/ð 	<Ø,3¯MªM©O¬OˆBŒJÑ(Ñ)àŸš¡¨RÑ0Ô0ˆØˆ:�m TÑ*Ô*ð 	KØ#×'Ò'Ñ(8Ñ9Ô9ˆGØÐ"Ø69°c¸'±l´l×6HÒ6HÑ6JÔ6J�”
Ñ2Ñ3à—x’x¡	¨2Ñ.Ô.ˆØˆ:�l DÑ)Ô)ñ #	Ø"×&Ò&¡xÑ0Ô0ˆGØÐ"à"Ð+�C�C©ð ”
Ñ9Ñ:ð '×*Ò*Ñ+FÑGÔGˆKØð LØ�:˜k¨3Ñ/Ô/ð )Ø&1�O�OØ�Z ¨d°E¨]Ñ;Ô;ð )Ø&(¥j§o¢oÑ5WÐ5WÀkÐ5WÑ5WÔ5WÑ&WÔ&W�O�Oà&(�OØ"ð LØ<K�B”JÑ8Ñ9Ø(×,Ò,Ñ-AÑBÔB‰MÙÐ(á(Ð1�C�C©cð ”
Ñ<Ñ=ð %1×$4Ò$4Ñ5QÑ$RÔ$RÑ!Ù$Ð0ØBEÀ#ÑF[ÑB\ÔB\�”
Ñ>Ñ?ñ +¨lÐ:Ð:Øœ
ŸšÑ'PÐRTÑUÔU×[Ò[Ñ]Ô]ð ;ð ILÈØ Ñ!;Ô<ñIô I�”
ÑDÑEøøð ð 
ð 
ñ 
ð 	‰ñ;Ø‰t‘KÑ Ô Õ)ð;ñ ;Ù-8ð;ð ;à•ñ	
ñ 	
ô 	
ð 	
ð
 	‰ñLà•ñ	
ñ 	
ô 	
ð 	
ð 	
ð 	
ñ 	
ñ 	
ð 	
øùùøð
øøøð(_Ø6Ñ6Ð6Ñ6Ñ6Ð6Ù" c¡c¡e¤e˜O˜O�D�D°×8Ò8¹ÀBÑGÔG�LØ€z‘, Ñ%Ô%ð *©,×*:Ò*:¹<Ñ*HÔ*Hð *ØÑ DÑ)Ñ)Ô)Ð)øøØð _ð _ñ _Ø	�EÑ
L¹NÐ
LÐ
LÐSVÕS]Ñ^Ñ^Ô^Ð^Ð^Ð^Ñ^Ñ^Ð^øùùøð_øøøðUØ7Ñ7Ð7Ñ7Ñ7Ð7ØÑÑÔÐÐøØð Uð Uñ UØ	�EÑ
B±.Ð
BÐ
BÈÍÑTÑTÔTÐTÐTÐTÑTÑTÐTøùùøðUøøøðUØ>Ñ>Ð>Ñ>Ñ>Ð>Ø Ñ Ñ"Ô"Ð"Ð"øØð Uð Uñ UØ	�EÑ
B±.Ð
BÐ
BÈÍÑTÑTÔTÐTÐTÐTÑTÑTÐTøùùøðUøøøð !€„
‰>Ñ ð !$€„
ÑÑ ð WÑ VÑ VÑ VÑ VÑ VÑ VÐ Và”*—.’. °Ñ4Ô4�Ùð 3™/Ñ-=Ð=Ð=Ø4Ñ4Ù&ØœŸš¨¸Ñ;Ô;Ø�b•i¡Ñ0Ô0Ø&/ b¥iÙ4±gñ'
ô '
ç
Š%‰'Œ'Ùð' ð �c˜)˜$�)™+œ+Ñ&Ô&ñ	ñ 	ô 	�Mñ ÐØ
Œ
�‹�~ tÑ,Ô,Ð,Ð,á%2ˆŒ
�>Ñ"ðñ ð ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ð ðñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ð ðñ ñ ñ ñ ñ ñ ñ ñ ð ð
ñ ñ ñ ñ ñ ñ ñ ñ ð ð
ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ð ð :Ñ 9Ñ 9Ñ 9Ñ 9Ð 9Ø >Ñ >Ñ >Ñ >Ñ >Ð >Ø <Ñ <Ñ <Ñ <Ñ <Ð <Ø ,Ñ ,Ñ ,Ñ ,Ñ ,Ð ,ð
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ñ 
ð 
ðñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ð ðñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ñ ð ðñ ñ ñ ñ ñ ñ ñ ñ ð ð 
ˆÕ	™8Ñ	$Ô	$�ñ …NÑVÙ…OÑZÙÕÑ^Ù…NÑ6ÙÕÑbðÑ ð°(¸3´-ð ñ ð ñ ðJ !™&™(œ(Ñ ñ2%Ñ ˜Eð ñ ñ ð$ 
‰‰Œ�ðD tð Dñ Dð Dñ DñN¸ð Àð ñ ð ñ ñ,¨H°S¬Mð ñ ð ñ ð"-¨¨t©ð -ñ -ð -ñ -ñ`B sð B¨sð Bñ Bð Bñ BñE¨ð E°ð Eñ Eð Eñ EñZ¨ð Z°ð Zñ Zð Zñ Zñ¨Cð °Dð ñ ð ñ ñE¨ð E°ð Eñ Eð Eñ Eð sð ñ ð ñ ñ,¨sñ Àñ ÈCð ÐTWð ñ ð ñ ñ6#˜eð #¨ð #ñ #ð #ñ #ñ' cð '¨h°s¬mð 'ñ 'ð 'ñ 'ðT4°ð 4¹ÈÑ9Lð 4ñ 4ð 4ñ 4ñ *Ñ Ù3Ñ Ù>Ñ Ù#<Ñ  Ù%<Ñ "Ù$8Ñ !ð 6:ñDð Dñ DØñDð ñ	Dð
 ˜x¨¨D¨Ô1Ô2ðDð 	ðDñ Dð Dñ Dð^ 6:ñ$ð $ñ $ð ñ$ð
 •ñ$ð •?ñ$ð •.ñ$ð ˜x¨¨D¨Ô1Ô2ð$ð 
ð$ñ $ð $ñ $ð` Ø59ñ"ð "ñ "ð ð"ð
 ñ"ð •ñ"ð •?ñ"ð •.ñ"ð ñ"ð ˜x¨¨D¨Ô1Ô2ð"ð 
ð"ñ "ð "ñ "ðJ (˜iá×$Ò$Ñ&Ô&Ù×%Ò%Ñ'Ô'Ù!×'Ò'Ñ)Ô)Ù(×.Ò.Ñ0Ô0Ù*×0Ò0Ñ2Ô2Ù)×/Ò/Ñ1Ô1ðñ	ô 	Ñ ð5¨8°C¬=ð 5¸Tð 5ñ 5ð 5ñ 5ñ¸#ð È3ð ñ ð ñ ñ"0¨4ð 0°E¸#À¹*ÀcÈDÁjÐ:PÔ4Qð 0ñ 0ð 0ñ 0ñf=¨3ð =°3¸±:ð =ñ =ð =ñ =ð@C :ð C°#ð Cñ Cð Cñ Cð
F¨ð Fñ Fð Fñ Fð˜dð ñ ð ñ ð;˜dð ;ñ ;ð ;ñ ;ð| T¨D¡[ð °Tð ñ ð ñ ð:: dð :ñ :ð :ñ :ñ(ð  4¨$¡;ð ¸#ð ñ ð ñ ð&  $Ø#ñ	ð ð Øñð ˜Œ}ñð ˜Œ}ð	ð
 
ˆ#„Yðñ ð ñ ð:  $Ø#ñð ð Ùðáðð ñð
 ˜Œ}ñð ˜Œ}ðð ‰oÔðñ ð ñ ð:˜X d¨3¤iÔ0ð ñ ð ñ ð6 Cð ©Mð ñ ð ñ ñ4¨dð °|ð ñ ð ñ ñ@ñ ð ñ ð> Ð Ñ Ñ Ù$0 LÑ ‘X•\Ð 0Ñ 0Ñ 0ð ñ	kð kñ kØñkàñkð ð	kð
 	ðkñ kð kñ kñ\>¸tð >Èð >ñ >ð >ñ >ñ0¸$ð À4ð ñ ð ñ ñ(Øñàðð 
ðñ ð ñ ñ@3
ñ 3
ð 3
ñ 3
ñp Ñ ñB ð B¨ð Bñ Bð Bñ Bð
e 
ð e 
ñ e 
ð e 
ñ e 
ñ e 
ô e 
ñ e 
ðRAfGð fGñ fGð fGñ fGÑ-Ñ/IÑKdñ fGô fGñ fGñ^O
 ñV'ð V'ñ V'Ø•ðV'ð Õ
#ñV'ð ðV'ð 
ðV'ñ V'ð V'ñ V'ñr]0ñ ]0¨I­Oñ ]0Ðadð ]0ñ ]0ð ]0ñ ]0ñ@`ñ ` 9¥?ñ `ÐX[ð `ñ `ð `ñ `ñ(  $Ñ ñ (,Ñ $ð GJñ!ñ !Ø�YÕ%Ô&ð!Ø16ñ!Ø>Cð!à	ð!ñ !ð !ñ !ñ.	R¨Cð 	R°Dð 	Rñ 	Rð 	Rñ 	RñR
ð R
 ©Ô 7ñ R
Èñ R
ÐbjÐknÔboð R
Ðx|ð R
ñ R
ð R
ñ R
ñj2-ð 2-ñ 2-ñjD¨Sð D°Tð Dñ Dð Dñ DñN ‰zÒÐØ�D�F„F€F€F€Fð ÐsÏ   …
 Š‘Ü#,}/ Ý]' Ý&}/ Ý']/Ý,}/ Ý.]/Ý/H}/ æ0f5 æ4}/ æ5f=æ:}/ æ<f=æ=V1}/ ý/ý5AÿÿA#A@0 Á@0AAÁ@6AAÁAAAÁA"AA7 ÁA7AB%ÁA=ABÁBAB%ÁB)AB> ÁB>AC,ÁCAC%ÁC%AC,