Ë
    âß²j™²  ã                   ó  — U d Z ddlZddlZddlZddlZddlZddlmZ ddlm	Z	m
Z
mZmZmZ ddlmZmZmZmZmZ ddlmZ ddlmZ ddlmZmZ dd	lmZmZmZ dd
l m!Z!  ejD                  e#«      Z$ e%h d£«      Z& e%h d£«      Z'dedee(   fd„Z)dodede(de(fd„Z*dpd„Z+dede,fd„Z-defd„Z.dede/de/fd„Z0dede1de1fd„Z2dede,dee1   fd„Z3dZ4	 dqdede,de1fd„Z5dedee,ef   fd„Z6h d£Z7dZ8dede9de,de,fd „Z:d!e;de,de;fd"„Z<drd#e,dee,   dee,   fd$„Z=dsd#e,de,de,fd%„Z>da?ee9   e@d&<   daAee;   e@d'<   d(edee,   fd)„ZB G d*„ d+e«      ZC e%d,„ eCjˆ                  j‹                  «       D «       «      ZF e%h d-£«      ZGd.d/iZHe;e,e,f   e@d0<    e%d1d/h«      ZId2d3d4œZJe;e,e,f   e@d5<   drd6e,d7ee;   de(fd8„ZK ej˜                  d9«      ZMde,dee,   fd:„ZNe
 G d;„ d<«      «       ZOd=d>œd?eOd@e(ddfdA„ZPe
 G dB„ dC«      «       ZQe
 G dD„ dE«      «       ZReCj¦                  dFeCj¨                  dGeCjª                  dHeCj¬                  dIeCj®                  dJeCj°                  dKiZYe;d+e,f   e@dL<   e
 G dM„ dN«      «       ZZdOZ[e/e@dP<   dQZ\e1e@dR<   dSZ]e,e@dT<   e
 G dU„ dV«      «       Z^de_de(fdW„Z`dXe,deeZge(f   fdY„ZaeCj°                  dZ„ eCjÄ                   ead[d\«      eCjÆ                   ead]«      eCjÈ                  d^„ eCjÊ                  d_„ eCjÌ                  d`„ eCjÎ                   eadadb«      eCjÐ                   eadcdd«      eCjÒ                   eadcde«      eCjÔ                  df„ i
Zke;eCeeZge(f   f   e@dg<   ddddd=dhœZle
 G di„ dj«      «       Zmdemfdk„Zndtdm„Zodlemddfdn„ZpddlqZqy)uzšGateway configuration: connected platforms, home channels, session reset
policies and delivery preferences, loaded from config.yaml / gateway.json / env.
é    N)ÚPath)ÚasdictÚ	dataclassÚfieldÚfieldsÚis_dataclass)ÚDictÚListÚOptionalÚAnyÚCallable)ÚEnum©Úget_hermes_home)Úcurrent_secret_scopeÚ
get_secret)Ú DEFAULT_LOOP_WATCHDOG_INTERVAL_SÚ!DEFAULT_LOOP_WATCHDOG_MAX_STRIKESÚDEFAULT_LOOP_WATCHDOG_TIMEOUT_S)Úis_truthy_value>   Ú1ÚonÚyesÚtrue>   Ú0ÚnoÚoffÚfalseÚvalueÚreturnc                 ó|   — t        | «      j                  «       j                  «       }|t        v rdS |t        v rdS dS )z:True/False for a recognized truthy/falsy token, else None.TFN)ÚstrÚstripÚlowerÚ_TRUTHY_STRINGSÚ_FALSY_STRINGS)r   Útokens     ú3/home/ubuntu/.hermes/hermes-agent/gateway/config.pyÚ_bool_tokenr)      s<   € ä�‹J×ÑÓ×$Ñ$Ó&€EØœOÑ+ˆ4Ð[¸%Ä>Ñ:Q°Ð[ÐW[Ð[ó    TÚdefaultc                 óf   — | €|S t        | t        «      rt        | «      }|€|S |S t        | |¬«      S )zDCoerce bool-ish config values, preserving a caller-provided default.)r+   )Ú
isinstancer"   r)   r   )r   r+   Úparseds      r(   Ú_coerce_boolr/   $   s<   € à€}ØˆÜ�%œÔÜ˜UÓ#ˆØ ˜.ˆwÐ4¨fÐ4Ü˜5¨'Ô2Ð2r*   c                  óØ   — t        j                  d«      } | xs dj                  «       syt        | «      }|€2t        j                  d| t        t        «      t        t        «      «       |S )aj  GATEWAY_MULTIPLEX_PROFILES operator override: True/False for a recognized token.

    ``None`` when unset, blank, or unrecognized so the caller keeps the config.yaml
    value (env > config > default). Blank is deliberately ``None``, not ``False``:
    a provisioned-but-unpopulated Fly secret arrives as ``""`` and must NOT shadow
    a config.yaml opt-in.
    ÚGATEWAY_MULTIPLEX_PROFILESÚ NzlIgnoring unrecognized GATEWAY_MULTIPLEX_PROFILES=%r (expected one of %s or %s); falling back to config.yaml.)	ÚosÚgetenvr#   r)   ÚloggerÚwarningÚsortedr%   r&   )Úrawr.   s     r(   Ú _env_multiplex_profiles_overrider9   .   s_   € ô �)‰)Ð0Ó
1€CØŠI�2×ÑÔØÜ˜Ó€FØ€~Ü�‰ðGà”œÓ(¬&´Ó*@ô	
ð
 €Mr*   c                 óŠ   — | €yt        | t        «      r| rdS dS t        | «      j                  «       j	                  «       xs dS )uú   Canonical streaming transport token. YAML 1.1 parses bare ``on``/``off`` as
    booleans (``mode: off`` â†’ ``False`` â†’ ``"false"`` would ENABLE streaming), so
    booleans map to ``"auto"``/``"off"``; anything else lower-cases, default ``"auto"``.Úautor   )r-   Úboolr"   r#   r$   ©r   s    r(   Ú_normalize_transport_tokenr>   C   sD   € ð €}ØÜ�%œÔÙˆvÐ) EÐ)Üˆu‹:×ÑÓ×#Ñ#Ó%Ò/¨Ð/r*   c                 óT   — 	 |€|S  | |«      S # t         t        t        f$ r |cY S w xY w©N)Ú	TypeErrorÚ
ValueErrorÚOverflowError)Úcastr   r+   s      r(   Ú_coerce_numrE   N   s5   € ðØ˜-ˆwÐ8©T°%«[Ð8øÜ”z¤=Ð1ò ØŠðús   ‚ † Ž'¦'c                 ó$   — t        t        | |«      S r@   )rE   Úfloat©r   r+   s     r(   Ú_coerce_floatrI   V   s   € Ü”u˜e WÓ-Ð-r*   c                 ó$   — t        t        | |«      S r@   )rE   ÚintrH   s     r(   Ú_coerce_intrL   Z   s   € Ü”s˜E 7Ó+Ð+r*   Úkeyc                 óT  — | €y	 t        | t        «      s t        | t        «      r| j                  «       st	        | «      ‚t        | t
        «      rt        | j                  «       d«      n
t        | «      }|dkD  r|S dS # t        t        f$ r t        j                  d|| «       Y yw xY w)zh``None``/0/negative disable; malformed values are ignored with a warning so a typo never blocks startup.Né
   zEIgnoring invalid %s=%r (expected a positive integer; 0/null disables)r   )r-   r<   rG   Ú
is_integerrB   r"   rK   r#   rA   r5   r6   ©r   rM   r.   s      r(   Ú_coerce_optional_positive_intrR   ^   s˜   € à€}ØðÜ�eœTÔ"¤z°%¼Ô'?È×HXÑHXÔHZÜ˜UÓ#Ð#Ü+5°e¼SÔ+A”�U—[‘[“] BÔ'ÄsÈ5Ãzˆð ˜a’Zˆ6Ð) TÐ)øô ”zÐ"ò Ü�‰Ð^Ð`cÐejÔkÙðús   …A0A> Á>&B'Â&B'iÿÿÿc                 ó"  — | €yd}t        | t        «      rt        | t        «      s| }n’t        | t        «      r‚| j	                  «       j                  «       rd| j	                  «       j                  «       rFt        j                  t        t        t        «      5  t        | j	                  «       d«      }ddd«       |€t        j                  d|«       y|r-d|cxk  r	t        k  sn t        j                  d|t        «       y|S # 1 sw Y   ŒSxY w)z¯Bounded positive watchdog interval, or zero when disabled/invalid. Shared by runtime
    and service generation so a value can never enable ``Type=notify`` without heartbeats.Nr   rO   z1Ignoring invalid %s (expected a positive integer)z6Ignoring invalid %s (expected an integer from 1 to %d))r-   rK   r<   r"   r#   ÚisasciiÚ	isdecimalÚ
contextlibÚsuppressrA   rB   rC   r5   r6   Ú_SYSTEMD_WATCHDOG_MAX_SECONDSrQ   s      r(   Úcoerce_systemd_watchdog_secondsrY   o   sÐ   € ð
 €}ØØ €FÜ�%œÔ¤j°¼Ô&=Ø‰Ü	�Eœ3Ô	 E§K¡K£M×$9Ñ$9Ô$;ÀÇÁÃ×@WÑ@WÔ@YÜ× Ñ ¤¬J¼ÓFñ 	,Ü˜Ÿ™›¨Ó+ˆF÷	,à€~Ü�‰ÐJÈCÔPØÙ�a˜&ÔAÔ$AÔAÜ�‰ÐOÐQTÔVsÔtØØ€M÷	,ð 	,ús   ÂDÄDc                 ó*   — t        | t        «      r| S i S r@   )r-   Údictr=   s    r(   Ú_coerce_dictr\   …   s   € Ü˜u¤dÔ+ˆ5Ð3°Ð3r*   >   ÚpairÚignoreÚdeclinezbHi! I'm a personal assistant and can only chat with my owner, so I can't help you directly. Sorry!Úchoicesc                 ór   — t        | t        «      r| j                  «       j                  «       nd}||v r|S |S )z@Lower-cased *value* when it is one of *choices*, else *default*.N)r-   r"   r#   r$   )r   r`   r+   Ú
normalizeds       r(   Ú_normalize_choicerc   ‘   s3   € ä*4°U¼CÔ*@�—‘“×$Ñ$Ô&Àd€JØ# wÑ.ˆ:Ð;°GÐ;r*   Ú	containerc                 óX   — | j                  |i «      }t        |t        «      si }|| |<   |S )zSGet-or-create ``container[key]`` as a dict, replacing a non-dict value with ``{}``.)Ú
setdefaultr-   r[   )rd   rM   r   s      r(   Ú
_dict_slotrg   —   s1   € à× Ñ   bÓ)€EÜ�eœTÔ"ØˆØˆ	�#‰Ø€Lr*   Únamec                 óz   — t        «       �t        | d«      }|�|S |S t        j                  j	                  | |«      S )z�Env read through the active profile secret scope when present (multiplexed
    per-profile secrets must win); otherwise legacy ``os.getenv``.N)r   Ú_get_secretr3   ÚenvironÚget)rh   r+   Ú	scope_vals      r(   Ú_getenvrn       s>   € ô ÓÐ)Ü  dÓ+ˆ	Ø%Ð1ˆyÐ>°wÐ>Ü�:‰:�>‰>˜$ Ó(Ð(r*   c                 ó&   — t        | |«      x}�|S |S r@   )rn   )rh   r+   Úvals      r(   Ú_getenv_strrq   ©   s   € Ü! $¨Ó0Ð0�3Ð=ˆ3ÐJÀ7ÐJr*   Ú_Platform__bundled_plugin_namesÚ!_Platform__bundled_plugin_aliasesÚ
plugin_dirc                 óB  ‡ — 	 ddl }t        ˆ fd„dD «       d«      }|€y|j                  |j                  d¬«      «      xs i }t	        |t
        «      r|j                  d«      nd}t        |«      j                  «       j                  «       xs dS # t        $ r Y yw xY w)z]Lowercased ``name:`` from a bundled platform's plugin manifest (None when absent/unreadable).r   Nc              3   óP   •K  — | ]  }‰|z  j                  «       sŒ‰|z  –— Œ y ­wr@   )Úexists)Ú.0Úmrt   s     €r(   ú	<genexpr>z2_bundled_platform_manifest_name.<locals>.<genexpr>¶   s%   øè ø€ Ò` ÀzÐTUÁ~×F]ÑF]ÕF_ˆZ˜!�^Ñ`ùs   ƒ&œ
&)úplugin.yamlú
plugin.ymlzutf-8)Úencodingrh   )ÚyamlÚnextÚ	safe_loadÚ	read_textr-   r[   rl   r"   r#   r$   Ú	Exception)rt   r~   Úmanifest_fileÚdatarh   s   `    r(   Ú_bundled_platform_manifest_namer…   ±   s–   ø€ ð
ÛÜÛ`Ð%BÔ`ÐbfóhˆàÐ ØØ�~‰~˜m×5Ñ5¸wÐ5ÓGÓHÒNÈBˆÜ#-¨d´DÔ#9ˆt�x‰x˜Ô¸tˆÜ�4‹y�‰Ó ×&Ñ&Ó(Ò0¨DÐ0øÜò Ùðús   ƒB ŸA2B Â	BÂBc                   ó¬   — e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZed„ «       Zededd fd„«       Zed d„«       Z y)!ÚPlatformz¦Supported messaging platforms. Plugin platforms are dynamic members created on
    demand by ``_missing_`` and cached so ``Platform("irc") is Platform("irc")`` holds.ÚlocalÚtelegramÚdiscordÚwhatsappÚwhatsapp_cloudÚslackÚsignalÚ
mattermostÚmatrixÚhomeassistantÚemailÚsmsÚdingtalkÚ
api_serverÚwebhookÚmsgraph_webhookÚfeishuÚwecomÚwecom_callbackÚweixinÚbluebubblesÚqqbotÚyuanbaoÚrelayc                 ó>  — t        |t        «      r|j                  «       sy|j                  «       j                  «       }|| j                  v r| j                  |   S t
        €| j                  «       \  aa|t
        v }|s~t        j                  |«      }|�.| j                  j                  |«      xs | j                  |«      S t        j                  t        «      5  ddlm} |j                  |«      }ddd«       |r| j                  |«      S dS # 1 sw Y   ŒxY w)z`Accept unknown names only for bundled or runtime-registered plugin adapters (no enum pollution).Nr   ©Úplatform_registry)r-   r"   r#   r$   Ú_value2member_map_rr   Ú_scan_bundled_plugin_platformsrs   rl   Ú_add_pseudo_memberrV   rW   r‚   Úgateway.platform_registryr¢   Úis_registered)Úclsr   Ú
registeredÚaliasr¢   s        r(   Ú	_missing_zPlatform._missing_Ü   s	  € ô ˜%¤Ô%¨U¯[©[¬]ØØ—‘“×#Ñ#Ó%ˆØ�C×*Ñ*Ñ*Ø×)Ñ)¨%Ñ0Ð0ä*Ð2ØQT×QsÑQsÓQuÑNÐ+Ð-NØÔ=Ð=ˆ
ÙÜ5×9Ñ9¸%Ó@ˆEØÐ ð
 ×-Ñ-×1Ñ1°%Ó8ÒY¸C×<RÑ<RÐSXÓ<YÐYÜ×$Ñ$¤YÓ/ñ DÝGØ.×<Ñ<¸UÓC�
÷Dñ 1;ˆs×%Ñ% eÓ,ÐDÀÐD÷Dð Dús   ÃDÄDr   r    c                 óø   — t         j                  | «      }||_        |j                  «       j	                  dd«      j	                  dd«      |_        || j                  |<   || j                  |j
                  <   |S )Nú-Ú_ú )ÚobjectÚ__new__Ú_value_ÚupperÚreplaceÚ_name_r£   Ú_member_map_)r¨   r   Úpseudos      r(   r¥   zPlatform._add_pseudo_memberõ   sg   € ä—‘ Ó$ˆØˆŒØŸ™›×-Ñ-¨c°3Ó7×?Ñ?ÀÀSÓIˆŒØ(.ˆ×Ñ˜uÑ%Ø*0ˆ×Ñ˜Ÿ™Ñ'Øˆr*   c                 ób  — 	 t        t        «      j                  j                  dz  dz  }|j                  «       r|j	                  «       ndD �cg c]M  }|j                  «       r;|dz  j                  «       r(|dz  j                  «       s|dz  j                  «       r|‘ŒO }}|D �ch c]  }|j                  j                  «       ’Œ }}i }|D ]7  }t        |«      }|sŒ||vsŒ||vsŒ|j                  j                  «       ||<   Œ9 ||fS c c}w c c}w # t        $ r t        «       i fcY S w xY w)a  Directory names of bundled platform plugins under ``plugins/platforms/``, plus a map of
        manifest ``name:`` keys that differ from their directory (alias -> directory name). Aliases
        never shadow a directory name, so the directory stays the canonical platform value.ÚpluginsÚ	platforms© z__init__.pyr{   r|   )r   Ú__file__ÚparentÚis_dirÚiterdirrw   rh   r$   r…   r‚   Úset)r¨   Úplatforms_dirÚchildÚdirsÚnamesÚaliasesÚmanifest_names          r(   r¤   z'Platform._scan_bundled_plugin_platformsþ   s2  € ð
	Ü ¤›N×1Ñ1×8Ñ8¸9ÑDÀ{ÑRˆMà?L×?SÑ?SÔ?U M×$9Ñ$9Ô$;Ð[]öØØ—<‘<”> u¨}Ñ'<×&DÑ&DÔ&FØ˜mÑ+×3Ñ3Ô5¸%À,Ñ:N×9VÑ9VÔ9Xò ðˆDð ð
 6:Ö:¨E�U—Z‘Z×%Ñ%Õ'Ð:ˆEÐ:ØˆGØò @�Ü ?ÀÓ F�Ú  ]¸%Ò%?ÀMÐY`ÒD`Ø-2¯Z©Z×-=Ñ-=Ó-?�G˜MÒ*ð@ð ˜'�>Ð!ùòùò
 ;øô ò 	Ü“5˜"�9Òð	úsC   ‚AD ÁADÂ!D Â'!DÃD ÃD Ã$D Ã)"D Ä
D ÄD.Ä-D.N)r    ztuple[set, dict])!Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚLOCALÚTELEGRAMÚDISCORDÚWHATSAPPÚWHATSAPP_CLOUDÚSLACKÚSIGNALÚ
MATTERMOSTÚMATRIXÚHOMEASSISTANTÚEMAILÚSMSÚDINGTALKÚ
API_SERVERÚWEBHOOKÚMSGRAPH_WEBHOOKÚFEISHUÚWECOMÚWECOM_CALLBACKÚWEIXINÚBLUEBUBBLESÚQQBOTÚYUANBAOÚRELAYÚclassmethodr«   r"   r¥   r¤   r»   r*   r(   r‡   r‡   À   sÊ   „ ñ[à€EØ€HØ€GØ€HØ%€NØ€EØ€FØ€JØ€FØ#€MØ€EØ
€CØ€HØ€JØ€GØ'€OØ€FØ€EØ%€NØ€FØ€KØ€EØ€GØ€EàñEó ðEð0 ð sð ¨zò ó ðð òó ñr*   r‡   c              #   ó4   K  — | ]  }|j                   –— Œ y ­wr@   r=   )rx   ry   s     r(   rz   rz     s   è ø€ Ò$T° Q§W¥WÑ$Tùs   ‚>
   r“   ÚlineÚteamsr˜   r–   r•   rœ   rš   rŒ   r—   r˜   r–   ÚPORT_BINDING_CONDITIONAL_MODESr•   z/v1z/webhooks/<route>©r•   r–   ÚSHARED_LISTENER_MIRROR_PATHSÚplatform_valueÚextrac                 óÆ   — | t         vryt        j                  | «      }|du xs> t        |xs i j                  dd«      «      j	                  «       j                  «       |k(  S )zDTrue when *platform_value* actually binds a port for *extra* config.FNÚconnection_modeÚ	websocket)ÚPORT_BINDING_PLATFORM_VALUESrç   rl   r"   r#   r$   )rê   rë   Úexpected_modes      r(   Úplatform_binds_portrñ   (  s]   € àÔ9Ñ9ØÜ2×6Ñ6°~ÓF€MØ˜DÐ Ò{¤C¨ª°"×(9Ñ(9Ð:KÈ[Ó(YÓ$Z×$`Ñ$`Ó$b×$hÑ$hÓ$jÐn{Ñ${Ð{r*   zThttps://(?:(?:ptb|canary)\.)?discord(?:app)?\.com/channels/(?:[0-9]+|@me)/([0-9]+)/?c                 óV   — t         j                  | «      }|r|j                  d«      S dS )zøChannel id from a pasted Discord channel link (``https://discord.com/channels/<guild>/<channel>``),
    else None. Message links (a third path segment) and anything that is not a channel link are
    left alone so callers keep their own error path.é   N)Ú_DISCORD_CHANNEL_LINK_REÚ	fullmatchÚgroup)r   Úmatchs     r(   Údiscord_channel_id_from_linkrø   3  s)   € ô %×.Ñ.¨uÓ5€EÙ"ˆ5�;‰;�q‹>Ð,¨Ð,r*   c                   ó®   — e Zd ZU dZeed<   eed<   eed<   dZee   ed<   dZ	ee   ed<   dZ
ee   ed<   dd
„Zd	eeef   fd„Zedeeef   d	d fd„«       Zy)ÚHomeChannelzœDefault destination for a platform (``deliver="telegram"`` without a chat ID);
    ``thread_id`` routes the bare target to the topic where /sethome was run.ÚplatformÚchat_idrh   NÚ	thread_idÚuser_idÚscope_idr    c                 óâ   — | j                   t        j                  k(  rRt        | j                  t
        «      r7t        | j                  j                  «       «      xs | j                  | _        y y y r@   )rû   r‡   rÍ   r-   rü   r"   rø   r#   ©Úselfs    r(   Ú__post_init__zHomeChannel.__post_init__G  sQ   € ð �=‰=œH×,Ñ,Ò,´¸D¿L¹LÌ#Ô1NÜ7¸¿¹×8JÑ8JÓ8LÓMÒ]ÐQU×Q]ÑQ]ˆD�Lð 2OÐ,r*   c                 óª   — dD �ci c]  }t        | |«      x}sŒ||“Œ }}| j                  j                  | j                  | j                  dœ|¥S c c}w )N©rý   rþ   rÿ   ©rû   rü   rh   )Úgetattrrû   r   rü   rh   )r  ÚkÚvÚoptionals       r(   Úto_dictzHomeChannel.to_dictM  s[   € Ø"FÖb˜QÔPWÐX\Ð^_ÓP`ÐK`È1ÑK`�A�q‘DÐbˆÐbØ ŸM™M×/Ñ/¸D¿L¹LÐRV×R[ÑR[ÑhÐ_gÐhÐhùò cs
   …A™Ar„   c           	      óÒ   — dD �ci c]$  }||j                  |«      rt        ||   «      nd “Œ& }} | dt        |d   «      t        |d   «      |j                  dd«      dœ|¤ŽS c c}w )Nr  rû   rü   rh   ÚHomer  r»   )rl   r"   r‡   )r¨   r„   r  r
  s       r(   Ú	from_dictzHomeChannel.from_dictQ  s{   € àFjÖkÀ�A t§x¡x°¤{”s˜4 ™7”|¸Ñ<ÐkˆÐkÙð  AœH T¨*Ñ%5Ó6ÄÀDÈÁOÓ@TÐ[_×[cÑ[cÐdjÐlrÓ[sñ  AÐwñ  Að  	Aùò ls   …)A$©r    N)rÇ   rÈ   rÉ   rÊ   r‡   Ú__annotations__r"   rý   r   rþ   rÿ   r  r	   r   r  rã   r  r»   r*   r(   rú   rú   ;  sŒ   … ñQàÓØƒLØ
ƒIØ#€Iˆx˜‰}Ó#à!€GˆX�c‰]Ó!Ø"€Hˆh�s‰mÓ"ó^ði˜˜c 3˜h™ó ið ðA˜T # s (™^ð A°ò Aó ñAr*   rú   F)Úenabled_if_newÚhomer  c                óÔ   — ddl m}m}  |«       }t        t        |d«      | j                  j
                  «      }|r|j                  dd«       | j                  «       |d<    ||«       y)zHPersist a logical home without falsely enabling a Relay-fronted adapter.r   )Úload_configÚsave_configrº   ÚenabledTÚhome_channelN)Úhermes_cli.configr  r  rg   rû   r   rf   r  )r  r  r  r  ÚconfigÚplatform_configs         r(   Úpersist_home_channelr  W  sT   € ç:Ù‹]€FÜ ¤¨F°KÓ!@À$Ç-Á-×BUÑBUÓV€OÙØ×"Ñ" 9¨dÔ3Ø&*§l¡l£n€O�NÑ#Ù�Õr*   c                   ó    — e Zd ZU dZ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eeef   fd„Zedeeef   dd fd„«       Zy)ÚSessionResetPolicyz£Inert legacy value type retained solely for the scheduled plugin-compat window.

    Gateway configuration and session lifecycle do not consume this datatype.
    ÚnoneÚmodeé   Úat_houri   Úidle_minutesTÚnotifyrè   Únotify_exclude_platformsé   Úbg_process_max_age_hoursr    c                 óJ   — i t        | «      ¥dt        | j                  «      i¥S )Nr$  )r   Úlistr$  r  s    r(   r  zSessionResetPolicy.to_dicto  s$   € Ø`”&˜“,Ð`Ð :¼DÀ×A^ÑA^Ó<_Ñ`Ð`r*   r„   c                 óp  — t        |«      }|j                  d«      }t        | «      D �ci c]Q  }|j                  dvrA|j                  |j                  |j                  «      €|j                  n||j                     “ŒS }} | dt        |j                  d«      d«      |�t        |«      nddœ|¤ŽS c c}w )Nr$  )r#  r$  r#  Trè   r»   )r\   rl   r   rh   r+   r/   Útuple)r¨   r„   ÚexcludeÚfÚplains        r(   r  zSessionResetPolicy.from_dictr  s¸   € ä˜DÓ!ˆØ—(‘(Ð5Ó6ˆô ˜C“[ö
à A§F¡FÐ2XÑ$Xð �F‰F §¡¨!¯&©&Ó!1Ð!9�A—I’I¸tÀAÇFÁF¹|ÑKð
ˆð 
ñ ð 
Ü §¡¨Ó 2°DÓ9Ø7>Ð7J¤U¨7¤^ÐPiñ
ð ñ
ð 	
ùò	
s   ªAB3N)rÇ   rÈ   rÉ   rÊ   r  r"   r  r!  rK   r"  r#  r<   r$  r*  r&  r	   r   r  rã   r  r»   r*   r(   r  r  b  sˆ   … ñð €Dˆ#ÓØ€GˆSÓØ€L�#ÓØ€FˆDÓØ&?Ð˜eÓ?Ø$&Ð˜cÓ&ða˜˜c 3˜h™ó að ð
˜T # s (™^ð 
Ð0Dò 
ó ñ
r*   r  c                   óˆ   — e Zd ZU dZdZee   ed<   dZee   ed<   dZ	ee   ed<   de
eef   fd„Zede
eef   dd fd	„«       Zy)
ÚChannelOverridezgPer-channel model/provider/system_prompt override (``platforms.<name>.channel_overrides[channel_id]``).NÚmodelÚproviderÚsystem_promptr    c                 ón   — t        | «      j                  «       D ��ci c]  \  }}|€Œ	||“Œ c}}S c c}}w r@   )r   Úitems)r  r  r	  s      r(   r  zChannelOverride.to_dict‰  s/   € Ü!'¨£×!3Ñ!3Ó!5×G™˜˜A¸¹��1‘ÓGÐGùÓGs   �
1¨1r„   c                 ó¤   — |rC | di t        | «      D �ci c](  }|j                  |j                  |j                  «      “Œ* c}¤ŽS  | «       S c c}w )Nr»   )r   rh   rl   )r¨   r„   r,  s      r(   r  zChannelOverride.from_dictŒ  sC   € áIM‰sÑE¼¸s»ÖD°1�a—f‘f˜dŸh™h q§v¡vÓ.Ñ.ÒDÑEÐXÑSVÓSXÐXùÒDs   ”-A)rÇ   rÈ   rÉ   rÊ   r0  r   r"   r  r1  r2  r	   r   r  rã   r  r»   r*   r(   r/  r/  ‚  st   … áqØ€Eˆ8�C‰=ÓØ"€Hˆh�s‰mÓ"Ø#'€M�8˜C‘=Ó'ðH˜˜c 3˜h™ó Hð ðY˜T # s (™^ð YÐ0Aò Yó ñYr*   r/  ÚTELEGRAM_BOT_TOKENÚDISCORD_BOT_TOKENÚSLACK_BOT_TOKENÚMATTERMOST_TOKENÚMATRIX_ACCESS_TOKENÚWEIXIN_TOKENÚPLATFORM_TOKEN_ENV_NAMESc                   ó4  — e Zd ZU dZdZeed<   dZee	   ed<   dZ
e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	   ed<    ee¬«      Zee	ef   ed<    ee¬«      Zee	ef   ed<   dee	ef   fd„Z eh d£«      Zedee	ef   dd fd„«       Zy)ÚPlatformConfigz.Configuration for a single messaging platform.Fr  Nr'   Úapi_keyr  ÚfirstÚreply_to_modeTÚgateway_restart_notificationÚtyping_indicatorÚtyping_status_text©Údefault_factoryÚchannel_overridesrë   r    c                 óð  — | j                   | j                  | j                  | j                  | j                  dœ| j
                  �d| j
                  ini ¥dD �ci c]  }t        | |«      x}sŒ||“Œ c}¥}| j                  r| j                  j                  «       |d<   | j                  r?| j                  j                  «       D ��ci c]  \  }}||j                  «       “Œ c}}|d<   |S c c}w c c}}w )N)r  rë   rA  rB  rC  rD  )r'   r?  r  rG  )r  rë   rA  rB  rC  rD  r  r  r  rG  r4  )r  r  r	  ÚresultÚcidÚovs         r(   r  zPlatformConfig.to_dict¯  sò   € à—|‘|¨d¯j©jÈ4×K]ÑK]Ø,0×,MÑ,MØ $× 5Ñ 5ñ
ð CG×BYÑBYÐBeÐ$ d×&=Ñ&=Ñ>Ðkmð	
ð
 2ÖM˜¼7À4ÈÓ;KÐ6K°aÑ6Kˆq�!‰tÒMð
ˆð ×ÒØ%)×%6Ñ%6×%>Ñ%>Ó%@ˆF�>Ñ"Ø×!Ò!ØLP×LbÑLb×LhÑLhÓLj×*kÁÀÀb¨3°·
±
³Ñ+<Ó*kˆFÐ&Ñ'Øˆùò Nùó
 +ls   ÁC-Á.C-Ã	C2>
   rë   r'   r?  r  r  rA  rC  rG  rD  rB  r„   c                 óR  ‡‡
— t        ‰«      Š‰j                  d«      }i ‰j                  «       D ��ci c]  \  }}|| j                  vsŒ||“Œ c}}¥t        ‰j                  di «      «      ¥Š
dt        dt
        fˆˆ
fd„}‰j                  d«      xs i }t        |t        «      rP|j                  «       D ��ci c]4  \  }}t        |t        «      rt	        |«      t        j                  |«      “Œ6 c}}ni }	 | t        ‰j                  d«      d«      ‰j                  d	«      ‰j                  d
«      t        |t        «      rt        j                  |«      nd ‰j                  dd«      t         |d«      d«      t         |d«      d«       |d«      |	‰
¬«
      S c c}}w c c}}w )Nr  rë   rM   r    c                 óP   •— ‰j                  | «      }|€‰j                  | «      S |S r@   ©rl   )rM   r   r„   rë   s     €€r(   Útoplevel_or_extraz3PlatformConfig.from_dict.<locals>.toplevel_or_extraÎ  s'   ø€ Ø—H‘H˜S“MˆEØ%* ]�5—9‘9˜S“>Ð=¸Ð=r*   rG  r  Fr'   r?  rA  r@  rB  TrC  rD  )
r  r'   r?  r  rA  rB  rC  rD  rG  rë   )r\   rl   r4  Ú_TYPED_KEYSr"   r   r-   r[   r/  r  r/   rú   )r¨   r„   r  r  r	  rO  Úraw_overridesrJ  Úov_datarG  rë   s    `        @r(   r  zPlatformConfig.from_dictÄ  s‰  ù€ ä˜DÓ!ˆØ�x‰x˜Ó'ˆð
 w T§Z¡Z£\×N™T˜Q °Q¸c¿o¹oÒ5M�A�q‘DÓNÐvÔR^Ð_c×_gÑ_gÐhoÐqsÓ_tÓRuÐvˆð	>¤3ð 	>¬3ö 	>ð Ÿ™Ð!4Ó5Ò;¸ˆô
 ˜¤tÔ,ð !.× 3Ñ 3Ó 5÷
á��WÜ˜'¤4Ô(ô �‹H”o×/Ñ/°Ó8Ñ8ô
ð 35ð	 	ñ Ü  §¡¨)Ó!4°eÓ<Ø—(‘(˜7Ó#Ø—H‘H˜YÓ'Ü8BÀ4ÌÔ8Nœ×.Ñ.¨tÔ4ÐTXØŸ(™( ?°GÓ<Ü)5Ñ6GÐHfÓ6gÐimÓ)nÜ)Ñ*;Ð<NÓ*OÐQUÓVÙ0Ð1EÓFØ/Øô
ð 	
ùó Oùó
s   ³FÁ
FÂ:9F#)rÇ   rÈ   rÉ   rÊ   r  r<   r  r'   r   r"   r?  r  rú   rA  rB  rC  rD  r   r[   rG  r	   r/  rë   r   r  Ú	frozensetrP  rã   r  r»   r*   r(   r>  r>     sê   … á8Ø€GˆTÓØ€Eˆ8�C‰=ÓØ!€GˆX�c‰]Ó!Ø*.€L�(˜;Ñ'Ó.Ø €M�3Ó Ø)-Ð  $Ó-Ø!Ð�dÓ!à(,Ð˜ ™Ó,Ù49È$Ô4OÐ�t˜C Ð0Ñ1ÓOÙ!°$Ô7€Eˆ4��S�‰>Ó7ð˜˜c 3˜h™ó ñ  ò ó €Kð
 ð
˜T # s (™^ð 
Ð0@ò 
ó ñ
r*   r>  gš™™™™™é?ÚDEFAULT_STREAMING_EDIT_INTERVALr%  Ú"DEFAULT_STREAMING_BUFFER_THRESHOLDu    â–‰ÚDEFAULT_STREAMING_CURSORc                   ó    — 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<   eZeed<   d	Zeed
<   deeef   fd„Zedeeef   dd fd„«       Zy)ÚStreamingConfigz1Real-time token streaming to messaging platforms.Fr  r;   Ú	transportÚedit_intervalÚbuffer_thresholdÚcursorç        Úfresh_final_after_secondsr    c                 ó   — t        | «      S r@   )r   r  s    r(   r  zStreamingConfig.to_dict   s   € Ü�d‹|Ðr*   r„   c                 óä  — t        |t        «      r|s | «       S |j                  d«      }|j                  d«      }d|v rt        |j                  d«      d«      }n|d uxr t	        |«      dk7  } | |t	        |�|n|«      t        |j                  d«      t        «      t        |j                  d«      t        «      |j                  dt        «      t        |j                  d	«      d
«      ¬«      S )NrY  r  r  Fr   rZ  r[  r\  r^  r]  )r  rY  rZ  r[  r\  r^  )
r-   r[   rl   r/   r>   rI   rT  rL   rU  rV  )r¨   r„   Úraw_transportÚraw_moder  s        r(   r  zStreamingConfig.from_dict  sØ   € ä˜$¤Ô%©TÙ“5ˆLð
 Ÿ™ Ó-ˆØ—8‘8˜FÓ#ˆØ˜ÑÜ" 4§8¡8¨IÓ#6¸Ó>‰Gà dÐ*Ò\Ô/IÈ(Ó/SÐW\Ñ/\ˆGÙØÜ0À-ÐB[±ÐaiÓjÜ'¨¯©°Ó(AÔCbÓcÜ(¨¯©Ð2DÓ)EÔGiÓjØ—8‘8˜HÔ&>Ó?Ü&3°D·H±HÐ=XÓ4YÐ[^Ó&_ô
ð 	
r*   N)rÇ   rÈ   rÉ   rÊ   r  r<   r  rY  r"   rT  rZ  rG   rU  r[  rK   rV  r\  r^  r	   r   r  rã   r  r»   r*   r(   rX  rX  î  s†   … á;Ø€GˆTÓð €IˆsÓØ:€M�5Ó:Ø>Ð�cÓ>Ø*€FˆCÓ*ð (+Ð˜uÓ*ð˜˜c 3˜h™ó ð ð
˜T # s (™^ð 
Ð0Aò 
ó ñ
r*   rX  c                 ó’   — | sy	 ddl m}  || d¬«      S # t        $ r( t        t	        | «      j                  «       «      dk\  cY S w xY w)z§True when API_SERVER_KEY is strong enough for the adapter to start (mirrors the
    ``has_usable_secret(min_length=16)`` guard in ``gateway/platforms/api_server.py``).Fr   ©Úhas_usable_secreté   ©Ú
min_length)Úhermes_cli.authre  ÚImportErrorÚlenr"   r#   )rM   re  s     r(   Ú_has_usable_api_server_keyrl    sI   € ñ Øð+Ý5Ù  °Ô4Ð4øÜò +Ü”3�s“8—>‘>Ó#Ó$¨Ñ*Ò*ð+ús   … •.AÁAÚkeysc                  ó   ‡ — ˆ fd„S )Nc                 ó.   •‡ — t        ˆ fd„‰D «       «      S )Nc              3   óT   •K  — | ]  }‰j                   j                  |«      –— Œ! y ­wr@   )rë   rl   )rx   r  Úcfgs     €r(   rz   z1_needs_extra.<locals>.<lambda>.<locals>.<genexpr>(  s   øè ø€ Ò:°˜3Ÿ9™9Ÿ=™=¨×+Ñ:ùs   ƒ%()Úall)rq  rm  s   `€r(   ú<lambda>z_needs_extra.<locals>.<lambda>(  s   ù€ ”sÓ:°TÔ:Ó:€ r*   r»   )rm  s   `r(   Ú_needs_extrart  '  s	   ø€ Û:Ð:r*   c                 ó    — t        | j                  j                  d«      xr) | j                  xs | j                  j                  d«      «      S )NÚ
account_idr'   )r<   rë   rl   r'   ©rq  s    r(   rs  rs  .  s9   € ¤ c§i¡i§m¡m°LÓ&AÒ&kÀsÇyÁyÒGjÐTW×T]ÑT]×TaÑTaÐbiÓTjÓ!l€ r*   Úphone_number_idÚaccess_tokenÚhttp_urlc                 óZ   — t        | r| j                  j                  d«      «      S d «      S )NrM   )rl  rë   rl   rw  s    r(   rs  rs  1  s$   € Ô%?ÑX[ÀÇ	Á	ÇÁÈeÓ@TÓ%f€ ÐaeÓ%f€ r*   c                  ó   — y)NTr»   rw  s    r(   rs  rs  2  s   � r*   c                 ó€   — t        t        | j                  j                  d«      xs d«      j	                  «       «      S )NÚclient_stater2   )r<   r"   rë   rl   r#   rw  s    r(   rs  rs  3  s,   € ¬$¬s°3·9±9·=±=ÀÓ3PÒ3VÐTVÓ/W×/]Ñ/]Ó/_Ó*`€ r*   Ú
server_urlÚpasswordÚapp_idÚclient_secretÚ
app_secretc                 ó„   — t        | j                  j                  d«      xs | j                  j                  d«      «      S )NÚ	relay_urlÚurl)r<   rë   rl   rw  s    r(   rs  rs  8  s+   € ¤ S§Y¡Y§]¡]°;Ó%?Ò%WÀ3Ç9Á9Ç=Á=ÐQVÓCWÓ X€ r*   Ú_PLATFORM_CONNECTED_CHECKERS)Úwrite_sessions_jsonÚalways_log_localÚfilter_silence_narrationÚgroup_sessions_per_userÚthread_sessions_per_userc                   óÀ  — e Zd ZU dZ ee¬«      Zeee	f   e
d<    ed„ ¬«      Zee   e
d<    ee¬«      Zeeef   e
d<    e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
d<   dZee   e
d<   dZee   e
d<   dZee   e
d<   dZee
d<   d	Z ee
d<   e!Z"e#e
d<   e$Z%e#e
d<   e&Z'ee
d<   dZ(ee
d<   dZ)ee
d<    ee*¬«      Z+e*e
d <   d!Z,ee
d"<    ee-¬«      Z.e-e
d#<   d$Z/d5d&„Z0d%ee   fd'„Z1d(ed)e	d%efd*„Z2d(ed%ee3   fd+„Z4d%eeef   fd,„Z5e6d-eeef   d%d fd.„«       Z7d(ee   d/ed0e8d1ed%ee   f
d2„Z9d6d(ee   d%efd3„Z:d6d(ee   d%efd4„Z;y)7ÚGatewayConfigzVMain gateway configuration: platform connections, session policies, delivery settings.rE  rº   c                  ó
   — ddgS )Nú/newú/resetr»   r»   r*   r(   rs  zGatewayConfig.<lambda>G  s   € ¸vÀxÐ>P€ r*   Úreset_triggersÚquick_commandsc                  ó   — t        «       dz  S )NÚsessionsr   r»   r*   r(   rs  zGatewayConfig.<lambda>I  s   € ´Ó7HÈ:Ñ7U€ r*   Úsessions_dirTrˆ  r‰  rŠ  Ústt_enabledÚstt_echo_transcriptsr‹  FrŒ  NÚmax_concurrent_sessionsÚmultiplex_profilesÚroom_link_urlr   Úsystemd_watchdog_secondsÚloop_watchdogÚloop_watchdog_probe_interval_sÚloop_watchdog_probe_timeout_sÚloop_watchdog_max_strikesr]   Úunauthorized_dm_behaviorr2   Úunauthorized_dm_decline_messageÚ	streamingéZ   Úsession_store_max_age_daysÚprofile_routes)rˆ  r‰  rŠ  r—  r˜  r‹  rŒ  r™  rš  r›  rœ  r�  rž  rŸ  r   r¡  r¢  r    c                 ó8   — t        | j                  «      | _        y r@   )rY   rœ  r  s    r(   r  zGatewayConfig.__post_init__ƒ  s   € Ü(GÈ×HeÑHeÓ(fˆÕ%r*   c                 óÂ   — | j                   j                  «       D ��cg c]'  \  }}|j                  sŒ| j                  ||«      sŒ&|‘Œ) }}}t	        |d„ ¬«      S c c}}w )z�Enabled + configured platforms, sorted by value so the rendered "Connected
        Platforms" prompt block is byte-stable (a reorder busts the prompt cache).c                 ó,   — t        | j                  «      S r@   )r"   r   )Úps    r(   rs  z7GatewayConfig.get_connected_platforms.<locals>.<lambda>Š  s   € ¬s°1·7±7«|€ r*   )rM   )rº   r4  r  Ú_is_platform_connectedr7   )r  rª  ÚcÚ	connecteds       r(   Úget_connected_platformsz%GatewayConfig.get_connected_platforms†  sS   € ð $(§>¡>×#7Ñ#7Ó#9×m™4˜1˜a¸Q¿Y»YÈ4×KfÑKfÐghÐjkÕKl’QÐmˆ	ÑmÜ�iÑ%;Ô<Ð<ùó ns   žA³AÁArû   r  c                 óè  — t         j                  |«      }|t        j                  k(  r ||«      S |j                  s|j
                  ry|� ||«      S 	 ddlm} t        j                  t        «      5  ddlm}  |«        d d d «       |j                  |j                  «      }|r0|j                  �|j                  n|j                  }|€dS  ||«      S 	 y# 1 sw Y   ŒXxY w# t        $ r Y yw xY w)NTr   r¡   )Údiscover_pluginsF)r‡  rl   r‡   rÞ   r'   r?  r¦   r¢   rV   rW   r‚   Úhermes_cli.pluginsr°  r   Úis_connectedÚvalidate_config)r  rû   r  Úcheckerr¢   r°  ÚentryÚchecks           r(   r«  z$GatewayConfig._is_platform_connectedŒ  sê   € Ü.×2Ñ2°8Ó<ˆà”x—‘Ò&Ù˜6“?Ð"Ø�<Š<˜6Ÿ>š>ØØÐÙ˜6“?Ð"ð	ÝCÜ×$Ñ$¤YÓ/ñ #õ  @Ù Ô"÷##ð$ &×)Ñ)¨(¯.©.Ó9ˆEÙØ.3×.@Ñ.@Ð.L˜×*Ò*ÐRW×RgÑRg�Ø$˜}�tÐ?±%¸³-Ð?ð ð
 ÷1#ð #ûô, ò 	ØØð	ús1   ÁC% Á4CÂAC% ÃC% ÃC"ÃC% Ã%	C1Ã0C1c                 ón   — | j                   j                  |«      r| j                   |   j                  S d S r@   )rº   rl   r  )r  rû   s     r(   Úget_home_channelzGatewayConfig.get_home_channel³  s.   € Ø8<¿¹×8JÑ8JÈ8Ô8Tˆt�~‰~˜hÑ'×4Ñ4Ð^ÐZ^Ð^r*   c                 óˆ  — | j                   j                  «       D ��ci c]   \  }}|j                  |j                  «       “Œ" c}}| j                  | j
                  t        | j                  «      dœ| j                  D �ci c]  }|t        | |«      “Œ c}¥| j                  j                  «       | j                  | j                  D ���cg c]T  }t        |«      rEt        |t        «      s5t!        |«      j                  «       D ��ci c]  \  }}|dk7  s|€Œ||“Œ c}}n|‘ŒV c}}}dœ¥S c c}}w c c}w c c}}w c c}}}w )N©rº   r’  r“  r–  rþ   )r£  r¥  r¦  )rº   r4  r   r  r’  r“  r"   r–  Ú_SCALAR_DICT_FIELDSr  r£  r¥  r¦  r   r-   Útyper   )r  rª  r¬  rh   Úrr  r	  s          r(   r  zGatewayConfig.to_dict¶  s  € à;?¿>¹>×;OÑ;OÓ;Q×R±4°1°a˜!Ÿ'™' 1§9¡9£;Ñ.ÓRØ"×1Ñ1Ø"×1Ñ1Ü × 1Ñ 1Ó2ñ	
ð
 6:×5MÑ5MÖN¨Tˆt”W˜T 4Ó(Ñ(ÒNð
ð Ÿ™×/Ñ/Ó1Ø*.×*IÑ*Ið ×,Ñ,÷ð ð ô   ”?¬:°a¼Ô+>ô #)¨£)§/¡/Ó"3×W™$˜!˜Q°q¸I²~ÈÉ��A‘ÔWØDEñFôò
ð 	
ùÛRùò Oùó Xùôs)   ž%D,Â D2Ã<D=ÄD7ÄD7ÄD=Ä7D=r„   c                 óp  ‡‡‡— t        ‰«      Št        ‰j                  d«      «      Šdt        dt        fˆˆfd„Šdt        dt        fˆfd„}ddœdt        dt        dt
        fˆfd	„}d
t        dt        dt        fˆfd„}dt        dt        dt        dt        dt        f
ˆfd„}‰j                  d«      }t         ‰d«      t        «      }d|cxk  rdk  sn t        }t         ‰d«       |d«      «      }‰j                  d«      }	|	€‰j                  d«      }	t        «       }
|
�|
}	t         ‰d«       |d«      «      }	 t        t        ‰j                  dd«      «      d«      }ddlm}  | d6 |dt$        j&                  d¬«      ‰j                  ddd g«      t        ‰j                  d!i «      «      d"‰v rt)        ‰d"   «      nt+        «       d#z  d$œt,        j/                  «       D ��ci c]!  \  }}|t1        ‰j                  |«      |«      “Œ# c}}¤t1         |d%d&«      d«      t1         |d'd(«      d«      |	€d nt1        |	d«      t3        |t        «      r|nd |t1         ‰d)«      d«       |d*t4        d+d,«       |d-t6        d+d.«      ||t9        ‰j                  d/«      t:        d0«      t        ‰j                  d1«      xs d2«      j=                  «       t>        j'                  ‰j                  d3i «      «      | |‰j                  d4«      xs g «      d5œ¤ŽS # t        t        f$ r d}Y �ŒÇw xY wc c}}w )7NÚgatewayrM   r    c                 ó8   •— | ‰v r‰|    S ‰j                  | «      S )zGTop-level key wins by presence; else the nested ``gateway.<key>`` form.rN  )rM   r„   Únested_gateways    €€r(   Úpickz%GatewayConfig.from_dict.<locals>.pickË  s#   ø€ à # t¡�4˜‘9ÐH°×1CÑ1CÀCÓ1HÐHr*   c                 ó   •— | ‰v r| S d| › �S )zJWarning key prefix: "gateway." when the nested form was the one consulted.zgateway.r»   )rM   r„   s    €r(   Ú	key_labelz*GatewayConfig.from_dict.<locals>.key_labelÏ  s   ø€ à ™+�3Ð;¨X°c°UÐ+;Ð;r*   F)Ú
dicts_onlyrÅ  c                óÜ   •— i }t        ‰j                  | i «      «      j                  «       D ]-  \  }}|rt        |t        «      sŒ	  ||«      |t        |«      <   Œ/ |S # t        $ r Y Œ=w xY w)z[``{Platform(name): parse(block)}`` for a platform-keyed mapping; unknown platforms skipped.)r\   rl   r4  r-   r[   r‡   rB   )rM   ÚparserÅ  ÚoutÚplatform_nameÚblockr„   s         €r(   Úby_platformz,GatewayConfig.from_dict.<locals>.by_platformÓ  sw   ø€ àˆCÜ(4°T·X±X¸cÀ2Ó5FÓ(G×(MÑ(MÓ(Oò Ñ$�˜uÙ¤j°¼Ô&=ØðÙ38¸³<�Cœ Ó/Ò0ð	ð ˆJøô "ò Ùðús   ÁAÁ	A+Á*A+Úflat_keyÚ
nested_keyc                 ó€   •— ‰j                  | «      }|€)t        ‰j                  d«      «      j                  |«      S |S )NÚstt)rl   r\   )rÌ  rÍ  r   r„   s      €r(   Ústt_settingz,GatewayConfig.from_dict.<locals>.stt_settingß  s9   ø€ Ø—H‘H˜XÓ&ˆEØDIÀM”< §¡¨£Ó0×4Ñ4°ZÓ@Ð\ÐW\Ð\r*   r+   ÚloÚhic                 ór   •— t         ‰| «      |«      }t        j                  |«      r||cxk  r|k  r|S  |S r@   )rI   ÚmathÚisfinite)rM   r+   rÑ  rÒ  r   rÂ  s        €r(   Úbounded_floatz.GatewayConfig.from_dict.<locals>.bounded_floatã  s8   ø€ ä!¡$ s£)¨WÓ5ˆEÜ ŸM™M¨%Ô0°R¸5Ô5FÀBÒ5F�5ÐSÐ5FÈGÐSr*   r›  r   ró   iè  rœ  rš  r™  r¥  r¤  r   )Úparse_profile_routesrº   Tr’  r�  r‘  r“  r–  r•  rº  r—  r  r˜  Úecho_transcriptsr�  rž  g      ð?g      ¬@rŸ  g     À‚@r¡  r]   r¢  r2   r£  r¦  )r—  r˜  rš  r›  rœ  r�  rž  rŸ  r   r™  r¡  r¢  r£  r¥  r¦  r»   ) r\   rl   r"   r   r<   r[   rG   rL   r   rY   r9   rR   ÚmaxrK   rA   rB   Úgateway.profile_routingr×  r>  r  r   r   Ú_TOPLEVEL_BOOL_DEFAULTSr4  r/   r-   r   r   rc   ÚUNAUTHORIZED_DM_BEHAVIORSr#   rX  )r¨   r„   rÄ  rË  rÐ  rÖ  r›  Úmax_strikesrœ  rš  Úenv_multiplexr™  r¥  r×  rh   r+   rÁ  rÂ  s    `              @@r(   r  zGatewayConfig.from_dictÆ  sY  ú€ ä˜DÓ!ˆÜ% d§h¡h¨yÓ&9Ó:ˆð	I”cð 	Iœcö 	Ið	<œ3ð 	<¤3õ 	<ð @Eò 
	œSð 
	¼ð 
	Ìõ 
	ð	]¤#ð 	]´3ð 	]¼3õ 	]ð	Tœsð 	T¬Uð 	T¼ð 	TÄ5ð 	TÌUõ 	Tð
 Ÿ™ Ó1ˆÜ!¡$Ð'BÓ"CÔEfÓgˆØ�KÔ' 4Ô'Ü;ˆKä#BÙÐ+Ó,©iÐ8RÓ.Só$
Ð ð "ŸX™XÐ&:Ó;ÐØÐ%Ø!/×!3Ñ!3Ð4HÓ!IÐÜ8Ó:ˆØÐ$Ø!.ÐÜ"?ÙÐ*Ó+©YÐ7PÓ-Qó#
Ðð	,Ü),¬S°·±Ð:VÐXZÓ1[Ó-\Ð^_Ó)`Ð&õ 	Aáð 
Ù! +¬~×/GÑ/GÐTXÔYØŸ8™8Ð$4°v¸xÐ6HÓIÜ'¨¯©Ð1AÀ2Ó(FÓGØ7EÈÑ7Mœ˜d >Ñ2Ô3ÔSbÓSdÐgqÑSqñ	
ô
 Qh×PmÑPmÓPo×p¹}¸tÀWˆt”\ $§(¡(¨4£.°'Ó:Ñ:Ópð
ô %¡[°À	Ó%JÈDÓQÜ!-©kÐ:PÐRdÓ.eÐgkÓ!lØ'9Ð'A™tÄ|ÐTfÐhlÓGmÜ+5°mÄSÔ+I™-ÈtØ%=Ü&¡t¨OÓ'<¸dÓCÙ+8Ð9YÔ[{ð  ~Að  CIó  ,JÙ*7Ð8WÔYxÐz}ð  @Eó  +FØ&1Ø$;Ü%6°t·x±xÐ@ZÓ7[Ô]vÐx~Ó%Ü,/°·±Ð9ZÓ0[Ò0aÐ_aÓ,b×,hÑ,hÓ,jÜ%×/Ñ/°·±¸ÀbÓ0IÓJØ'AÙ/°·±Ð9IÓ0JÒ0PÈbÓQó)
ð 	
øô œ:Ð&ò 	,Ø)+Ó&ð	,üó qs   Å%L Ç,&L2ÌL/Ì.L/rM   r`   r+   c                 ó®   — |r| j                   j                  |«      nd}|r4||j                  v r&t        |j                  j                  |«      ||«      S y)zQNormalized ``platforms[platform].extra[key]`` when the key is present, else None.N)rº   rl   rë   rc   )r  rû   rM   r`   r+   Úplatform_cfgs         r(   Ú_extra_choicezGatewayConfig._extra_choice  sM   € á7?�t—~‘~×)Ñ)¨(Ô3ÀTˆÙ˜C <×#5Ñ#5Ñ5Ü$ \×%7Ñ%7×%;Ñ%;¸CÓ%@À'È7ÓSÐSØr*   c                 ó�   — | j                  |dt        | j                  «      }|�|S |t        j                  k(  rdS | j                  S )z±Effective unauthorized-DM behavior. Email is inbox-shaped so it defaults to ``"ignore"``
        unless its own ``unauthorized_dm_behavior`` opts in (a global default does not).r¡  r^   )rá  rÜ  r¡  r‡   rÕ   ©r  rû   Úchoices      r(   Úget_unauthorized_dm_behaviorz*GatewayConfig.get_unauthorized_dm_behavior#  sU   € ð ×#Ñ# HÐ.HÔJcÐei÷  fCñ  fCó  DˆØÐØˆMØ#¤x§~¡~Ò5ˆxÐX¸4×;XÑ;XÐXr*   c                 ó:   — | j                  |dddhd«      }|€dS |S )zCEffective notice-delivery mode ("public"/"private") for a platform.Únotice_deliveryÚpublicÚprivate)rá  rã  s      r(   Úget_notice_deliveryz!GatewayConfig.get_notice_delivery+  s.   € à×#Ñ# HÐ.?À(ÈIÐAVÐX`ÓaˆØ!˜>ˆxÐ5¨vÐ5r*   r  r@   )<rÇ   rÈ   rÉ   rÊ   r   r[   rº   r	   r‡   r>  r  r’  r
   r"   r“  r   r–  r   rˆ  r<   r‰  rŠ  r—  r˜  r‹  rŒ  r™  r   rK   rš  r›  rœ  r�  r   rž  rG   r   rŸ  r   r   r¡  r¢  rX  r£  r¥  r(  r¦  r»  r  r®  r«  rú   r¸  r  rã   r  rÀ   rá  rå  rê  r»   r*   r(   rŽ  rŽ  C  sQ  … á`Ù05ÀdÔ0K€Iˆt�H˜nÐ,Ñ-ÓKÙ %Ñ6PÔ Q€N�D˜‘IÓQÙ%*¸4Ô%@€N�D˜˜c˜‘NÓ@ÙÑ/UÔV€L�$ÓVð
 !%Ð˜Ó$Ø!Ð�dÓ!ð &*Ð˜dÓ)Ø€K�ÓØ!%Ð˜$Ó%Ø$(Ð˜TÓ(Ø%*Ð˜dÓ*Ø-1Ð˜X c™]Ó1ð *.Ð˜ ™Ó-ð $(€M�8˜C‘=Ó'Ø$%Ð˜cÓ%ð €M�4ÓØ,LÐ" EÓLØ+JÐ! 5ÓJØ%FÐ˜sÓFØ$*Ð˜cÓ*Ø+-Ð# SÓ-Ù!&°Ô!G€IˆÓGà&(Ð Ó(Ù °Ô6€N�DÓ6ðÐógð=¨¨h©ó =ð%¨xð %Àð %ÐTXó %ðN_¨ð _°h¸{Ñ6Kó _ð
˜˜c 3˜h™ó 
ð  ðS
˜T # s (™^ð S
°ò S
ó ðS
ðj h¨xÑ&8ð ¸sð ÈSð Ð[^ð ÐckÐloÑcpó ñY°X¸hÑ5Gð YÐSVó Yñ6¨H°XÑ,>ð 6È#ô 6r*   rŽ  c                  ó$  — ddl m}  t        «       }| j                  |«      }	 | j	                  ||«       t        j                  |«      }t        |«       t        |«       |S # t
        $ r$}t        j                  d|dz  |«       Y d}~ŒUd}~ww xY w)zcLoad gateway configuration. Priority: env > ~/.hermes/config.yaml > legacy gateway.json > defaults.r   )Úconfig_loaderus   Failed to process config.yaml â€” falling back to .env / gateway.json values. Check %s for syntax errors. Error: %szconfig.yamlN)r¿  rì  r   Úload_legacy_gateway_jsonÚload_yaml_layerr‚   r5   r6   rŽ  r  Ú_apply_env_overridesÚ_validate_gateway_config)rì  Ú_homeÚgw_dataÚer  s        r(   Úload_gateway_configrô  1  s‹   € å%äÓ€EØ×4Ñ4°UÓ;€Gð
Ø×%Ñ% e¨WÔ5ô  ×$Ñ$ WÓ-€FÜ˜Ô Ü˜VÔ$Ø€Møô% ò 
Ü�‰ð4à�MÑ! 1÷	
ñ 	
ûð
ús   £A" Á"	BÁ+B
Â
Br  c           	      ób  — 	 ddl m} | j                  j	                  «       D ��cg c]1  \  }}|j
                  r |t        v r|j                  �||t        |   f‘Œ3 }}}|D ]B  \  }}}|j                  j                  «       rŒ"t        j                  d|j                  |«       ŒD |€y|D ]k  \  }}}|j                  }|j                  «       sŒ$ ||d¬«      rŒ/t        j                  d|j                  ||j                  «       dd d	z   «       d
|_        Œm y# t        $ r d}Y �Œw xY wc c}}w )zUValidate and sanitize a loaded GatewayConfig in place (after all sources are merged).r   rd  NzG%s is enabled but %s is empty. The adapter will likely fail to connect.r   rg  z�%s is enabled but %s is set to a placeholder value ('%s'). Set a real bot token before starting the gateway. The adapter will NOT be started.é   z...F)ri  re  rj  rº   r4  r  r<  r'   r#   r5   r6   r   Úerror)	r  re  rª  r¬  Útoken_platformsrû   ÚpconfigÚenv_namer'   s	            r(   rð  rð  N  s7  € ð!õ 	6ð
 9?×8HÑ8H×8NÑ8NÓ8P÷Ù04°°1Ø�9Š9˜Ô6Ñ6¸1¿7¹7Ð;Nð 
ˆAÔ'¨Ñ*Ò+ð€Oñ ð (7ò @Ñ#ˆ�'˜8Ø�}‰}×"Ñ"Õ$Ü�N‰NÐdÐfn×ftÑftÐv~Õð@ð Ð ØØ'6ò 	$Ñ#ˆ�'˜8Ø—‘ˆØ�;‰;�=Ñ!2°5ÀQÖ!GÜ�L‰Lð3ð —‘ ¨%¯+©+«-¸¸Ð*;¸eÑ*Cô	ð $ˆG�Oñ	$øô ò !Ø Óð!üós   ‚D ¥6D+ÄD(Ä'D(c                 ó    — ddl m}  || «       y)zLApply environment variable overrides to config (see ``gateway.config_env``).r   )rï  N)Úgateway.config_envrï  )r  Ú_impls     r(   rï  rï  m  s   € å@Ù	ˆ&…Mr*   )T)r    zbool | None)z gateway.systemd_watchdog_secondsr@   )r2   )r  rŽ  r    N)rrÊ   rV   ÚloggingrÔ  r3   ÚreÚpathlibr   Údataclassesr   r   r   r   r   Útypingr	   r
   r   r   r   Úenumr   r  r   Úagent.secret_scoper   r   rj   Úgateway.shutdown_watchdogr   r   r   Úutilsr   Ú	getLoggerrÇ   r5   rS  r%   r&   r<   r)   r/   r9   r"   r>   rE   rG   rI   rK   rL   rR   rX   rY   r\   rÜ  Ú'DEFAULT_UNAUTHORIZED_DM_DECLINE_MESSAGErÀ   rc   r[   rg   rn   rq   rr   r  rs   r…   r‡   Ú__members__ÚvaluesÚ_BUILTIN_PLATFORM_VALUESrï   rç   Ú SHARED_LISTENER_MIRROR_PLATFORMSré   rñ   Úcompilerô   rø   rú   r  r  r/  rÌ   rÍ   rÐ   rÒ   rÓ   rÞ   r<  r>  rT  rU  rV  rX  r°   rl  rt  rÏ   rÑ   rØ   rÙ   rÚ   rß   rà   rá   râ   r‡  rÛ  rŽ  rô  rð  rï  Újsonr»   r*   r(   ú<module>r     sa  ðòó Û Û Û 	Û 	Ý ß FÕ Fß 6Õ 6Ý å -ß N÷ñ õ
 "à	ˆ×	Ñ	˜8Ó	$€áÒ6Ó7€ÙÒ6Ó7€ð\�sð \˜x¨™~ó \ñ3˜ð 3 dð 3°dó 3óð*0 cð 0¨có 0ð˜Só ð.˜ð . uð .°ó .ð,�sð , Sð ,¨Só ,ð*¨ð *°3ð *¸8ÀC¹=ó *ð !.Ð ð >ñØðØðàóð,4˜ð 4  S¨# X¡ó 4ò :Ð àhð (ð
<˜Sð <¨3ð <¸ð <Àó <ð˜$ð  Sð ¨Tó ñ)�#ð ) ¨¡ð )¸À#¹ó )ñK�cð K Cð K°ó Kð 26Ð  ¨#¡Ó 5Ø48Ð ! 8¨D¡>Ó 8ð°ð ¸À#¹ó ôRˆtô Rñl %Ñ$T°h×6JÑ6J×6QÑ6QÓ6SÔ$TÓTÐ ñ
  )ò *ó  Ð ð
 3;¸IÐ1FÐ   S¨# X¡Ó Fñ $-¨l¸IÐ-FÓ#GÐ  à>CÐPcÑ/dÐ ˜d 3¨ 8™nÓ dñ|¨ð |°H¸T±Nð |Èdó |ð &˜2Ÿ:™:Ø[ó]Ð ð-¨ð -°¸±ó -ð ÷Að Aó ðAð6 GLò ˜{ð ¸tð ÐPTó ð ÷
ð 
ó ð
ð> ÷Yð Yó ðYð( ×ÑÐ+Ø×ÑÐ)Ø‡N�NÐ%Ø×ÑÐ+Ø‡O�OÐ*Ø‡O�O�^ð3Ð ˜$˜z¨3˜Ñ/ó ð ÷C
ð C
ó ðC
ðP *-Ð  Ó ,Ø*,Ð " CÓ ,Ø &Ð ˜#Ó &ð ÷)
ð )
ó ð)
ðX	+ Fð 	+¨tó 	+ð;˜ð ; ¨.Ð)9¸4Ð)?Ñ @ó ;ð ‡O�OÑlØ×Ñ™\Ð*;¸^ÓLØ‡O�O‘\ *Ó-Ø×ÑÑfØ×ÑÑ&Ø×ÑÑ`Ø×Ñ™, |°ZÓ@Ø‡N�N‘L ¨?Ó;Ø×Ñ‘l 8¨\Ó:à‡N�NÑXðRÐ ˜d 8¨X°~Ð6FÈÐ6LÑ-MÐ#MÑNó ð"  °TÐW[Ø#ÀñÐ ð ÷j6ð j6ó ðj6ðZ˜]ó ó:$ð> ð °4ó ô r*   