+
    jHàjl£ ã                  óÄ  € R t ^ RIHt ^ RIt^ RIHt ^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ R	IHtHt ^ R
IHt ^ RIHt ^ RIH t  ^ RI!H"t" ^ RI#H$t$ ^ RI%H&t&H't'H(t(H)t)H*t* ^ RI+H,t,H-t-H.t.H/t/ ^ RI0H1t1 ^ RIH2t2H3t3H4t4H5t5H6t6 ]'       d   ^ RI7H8t8 ^ RI9H:t: ]Pv                  ! R4      t<R R lt=R R lt> ! R R] ]"]$4      t?R# )aa  Inbound message pipeline (_handle_message, text/media preparation, durable-turn markers, plugin injection) for GatewayRunner.

Split out of ``gateway/run.py``; bound onto ``GatewayRunner`` via the MRO.
``gateway.run`` internals are imported lazily inside method bodies (import cycle),
so ``patch("gateway.run.X")`` keeps intercepting them at call time.
)ÚannotationsN)ÚTYPE_CHECKING)Úsuppress)ÚPath)Út)ÚPlatform)ÚEphemeralReply)ÚMessageEventÚMessageType)Úapproval_input_words)Úrehome_inbound_media)ÚGatewayInboundHooksMixin)Ú GatewayInboundTranscriptionMixin)ÚGatewayPluginInjectionMixin)ÚUnauthorizedOwnerNotifierÚpairing_code_replyÚpairing_profile_argÚpairing_rate_limited_replyÚunauthorized_owner_hint)ÚSessionSourceÚbuild_session_contextÚis_shared_multi_user_sessionÚ neutralize_untrusted_inline_text)ÚTurnLeaseTimeoutError)ÚAnyÚDictÚListÚOptionalÚTuple)ÚGatewayRunner)Ú
TurnRunnerzgateway.runc               ó    € V ^8„  d   QhRRRR/# )é   Ú
message_idr   ÚreturnÚstr© )Úformats   "Ú8/home/ubuntu/.hermes/hermes-agent/gateway/run_inbound.pyÚ__annotate__r)   2   s   € ÷ ñ ¨ð °ñ ó    c                ó   € RV  R2# )zUModel-facing routing note for a Discord turn (rides the API-bound user message only).z[Triggering message id: `uE   ` â€” use as `message_id` for reply/react/pin via the discord tools.]r&   )r#   s   &r(   Údiscord_triggering_noter,   2   s   € ð $ J <ð 0"ð 	#ðr*   c               ó$   € V ^8„  d   QhRRRRRR/# )r"   Úeventr   Úmessage_textr$   r&   )r'   s   "r(   r)   r)   :   s!   € ÷ 
-ñ 
-¨ð 
-¸Cð 
-ÀCñ 
-r*   c                óš   € \        V RR4      pV'       d   \        V\        4      '       g   V# \        V4       R2pVP	                  V4      # )uŒ  Authored text for the durable user row: peel off exactly the note
``_prepend_inbound_reply_context`` added for THIS event, if present. The note is a
model instruction, not something the user wrote â€” persisted as ``content`` it renders
verbatim in every transcript surface and pollutes FTS/memory (#71304, #114719). It
keeps riding ``message_text`` (and the replay-only ``api_content`` sidecar).r#   Nú

)ÚgetattrÚ
isinstancer%   r,   Úremoveprefix)r.   r/   r#   Úprefixs   &&  r(   Ústrip_discord_triggering_noter6   :   sJ   € ô ˜ ¨dÓ3€JßœZ¨´c×:Ò:ØÐÜ'¨
Ó3Ð4°DÐ9€FØ×$Ñ$ VÓ,Ð,r*   c                  óÚ  € ] tR t^GtRtR R ltR R ltR R ltR R	 ltR
 R lt	R R lt
]R R l4       tR R ltR R ltRRRRRRRRRRRRRRRRRRRR/
tR”tR R  ltR! R" ltR# R$ ltR% R& ltR' R( ltR)R*/R+ R, lltR- R. ltR/ R0 ltR1 R2 lt]R3 R4 l4       tR5 R6 ltR7 R8 ltR9 R: ltR; R< ltR= R> ltR? R@ lt RA t!RB t"RC t#RD RE lt$RF t%RG t&RH t'RI t(RJ t)RK t*RL t+]RM RN l4       t,RO t-].! 0 R•m4      t/RP RQ lt0RR RS lt1]RT RU l4       t2RV RW lt3RX RY lt4RZ R[ lt5R\ R] lt6R^ R_ lt7R` Ra lt8R–Rc Rd llt9Re Rf lt:]Rg Rh l4       t;Ri Rj lt<RkRbRlRm/Rn Ro llt=Rp Rq lt>]Rr Rs l4       t?]@Rt Ru l4       tA]@Rv Rw l4       tB]Rx Ry l4       tCRz R{ ltDR| R} ltER~Rb/R R€ lltFR~Rb/R� R‚ lltGRƒ R„ ltHR… R† ltIR‡ Rˆ ltJR‰ RŠ ltKR‹RbR~RbRŒRbR�RbRŽRb/R� R� lltLR‘ R’ ltMR“tNRb# )—ÚGatewayInboundMixinz}Inbound message pipeline (_handle_message, text/media preparation, durable-turn markers, plugin injection) for GatewayRunner.c               ó    € V ^8„  d   QhRRRR/# ©r"   Úsourcer   r$   ÚNoner&   )r'   s   "r(   r)   Ú GatewayInboundMixin.__annotate__J   s   € ÷ Lñ L°=ð LÀTñ Lr*   c              ƒ  ó  "  € VP                   '       d   VP                   P                  MRpV P                  V4      pVf   \        P	                  RV4       R# VP                  W!P                  4      '       d   R#  \        P                  ! VP                  Y!P                  VP                  ;'       g    R4      G Rj  x€L
 pT P                  T4      pT'       d   \        Y$\!        T4      4      pM
\#        4       pT'       d%   TP%                  TP&                  T4      G Rj  x€L
  T'       g   TP)                  Y!P                  4       R# R#  L�  \        \        3 d    \        P                  RTRR7        R# i ; i L]5i)zQDM an unauthorized sender a pairing code (rate-limited; groups never reach here).ÚunknownNz1Cannot offer pairing code on %s: no pairing storeÚ z%Could not record a pairing code on %sT©Úexc_info)ÚplatformÚvalueÚ_pairing_store_forÚloggerÚerrorÚ_is_rate_limitedÚuser_idÚasyncioÚ	to_threadÚgenerate_codeÚ	user_nameÚOSErrorÚTimeoutErrorÚwarningÚ_delivery_adapter_forr   r   r   ÚsendÚchat_idÚ_record_rate_limit)Úselfr;   Úplatform_nameÚpairing_storeÚcodeÚadapterÚreplys   &&     r(   Ú_hm_offer_pairing_codeÚ*GatewayInboundMixin._hm_offer_pairing_codeJ   s4  é € à17··°˜Ÿ™×-Ò-ÀiˆØ×/Ñ/°Ó7ˆØÒ Ü�L‰LÐLÈmÔ\Ùà×)Ñ)¨-¿¹×HÒHÙð	Ü ×*Ò*Ø×+Ñ+¨]¿N¹NÈF×L\ÑL\×LbÐLbÐ`bó÷ ˆDð ×,Ñ,¨VÓ4ˆßÜ& }Ô<OÐP]Ó<^Ó_‰Eä.Ó0ˆEßØ—,‘,˜vŸ~™~¨uÓ5×5Ð5ßà×,Ñ,¨]¿N¹NÖKñ ñøô œÐ&ô 	Ü�N‰NÐBÀMÐ\`ˆNÔaÚð	úñ 6ùs`   ‚A;FÁ>8E Â7
E ÃEÃE ÃFÃ'FÄFÄ&FÄ'FÄ3FÅE Å)FÅ=FÆ FÆFc               ó    € V ^8„  d   QhRRRR/# r:   r&   )r'   s   "r(   r)   r=   g   s   € ÷ lñ l¸-ð lÈDñ lr*   c              ƒ  ó  "  € ^ RI Hp VP                  '       d   VP                  P                  MRpV P	                  V4      pVe"   VP                  W1P                  4      '       d   R#  \        P                  ! VP                  W1P                  4      G Rj  x€L
  T P                  T4      pT'       g   R# \        T RR4      p\!        \        TRR	4      ;'       g    R	4      P#                  4       p TP%                  TP&                  T;'       g    T4      G Rj  x€L
  R#  L‹  \        \        3 d    \        P                  RTRR7        R# i ; i L8  \(         d    \        P                  R
TRR7        R# i ; i5i)uø   ``decline`` behavior: one short refusal per sender per DECLINE_DEDUPE_SECONDS, then silence
(#88028). The stamp is written BEFORE the send so a delivery
hiccup cannot become a decline storm; without a store there is no dedupe state â†’ stay silent.)Ú'DEFAULT_UNAUTHORIZED_DM_DECLINE_MESSAGEr?   Nz1Could not record an unauthorized-DM decline on %sTrA   ÚconfigÚunauthorized_dm_decline_messager@   z/Failed to deliver unauthorized-DM decline on %s)Úgateway.configr_   rC   rD   rE   Úhas_recent_declinerI   rJ   rK   Úrecord_declinerN   rO   rF   rP   rQ   r2   r%   ÚstriprR   rS   Ú	Exception)rU   r;   r_   rV   rW   rY   r`   Útexts   &&      r(   Ú_hm_send_unauthorized_declineÚ1GatewayInboundMixin._hm_send_unauthorized_declineg   sH  é € õ 	KØ17··°˜Ÿ™×-Ò-ÀiˆØ×/Ñ/°Ó7ˆØÒ  M×$DÑ$DÀ]×TbÑTb×$cÒ$cÙð	Ü×#Ò# M×$@Ñ$@À-×Q_ÑQ_Ó`×`Ð`ð ×,Ñ,¨VÓ4ˆßÙÜ˜˜x¨Ó.ˆÜ”7˜6Ð#DÀbÓI×OÐOÈRÓP×VÑVÓXˆð	lØ—,‘,˜vŸ~™~¨t×/^Ð/^Ð7^Ó_×_Ò_ñ aøÜœÐ&ô 	Ü�N‰NÐNÐP]ÐhlˆNÔmÚð	úñ `øÜô 	lÜ�N‰NÐLÈmÐfjˆN×kð	lüs~   ‚A)FÁ,.D( ÂD&ÂD( ÂFÂ8=FÃ6E Ä
E ÄEÄ E Ä$FÄ&D( Ä()EÅFÅEÅFÅE Å#FÅ=FÆ FÆFc               ó    € V ^8„  d   QhRRRR/# r:   r&   )r'   s   "r(   r)   r=   €   s   € ÷ 6ñ 6°-ð 6ÀDñ 6r*   c              ƒ  óÞ  "  € ^ RI Hp VP                  '       d   VP                  P                  MRp\	        Y1P
                  VP                  ;'       g    RV! 4       R7      p\        P                  RV4       \        V RR4      pVf   \        4       ;qPn        VP                  W1P
                  4      '       d.   \        V RR4      e   VP                  WV4      G Rj  x€L
  R# R# R#  L
5i)	zºUnauthorized DM under behaviour ``ignore``: nothing goes to the sender. The owner gets the
sender's ID and the allowlist fix in the WARNING log and, once per sender, in the home channel.)Údisplay_hermes_homer?   r@   )Úhermes_homezUnauthorized user (ignored): %sÚ_unauthorized_owner_notifierNr`   )Úhermes_constantsrl   rC   rD   r   rI   rM   rF   rP   r2   r   rn   Ú
first_timeÚnotify)rU   r;   rl   rV   ÚhintÚnotifiers   &&    r(   Ú_hm_report_ignored_dmÚ)GatewayInboundMixin._hm_report_ignored_dm€   sÄ   é € õ 	9Ø17··°˜Ÿ™×-Ò-ÀiˆÜ&ØŸ>™>¨6×+;Ñ+;×+AÐ+A¸rÑObÓOdô
ˆô 	�‰Ð8¸$Ô?Ü˜4Ð!?ÀÓFˆØÒÜ;TÓ;VÐVˆHÔ8Ø×Ñ˜}¯n©n×=Ò=Ä'È$ÐPXÐZ^ÓB_ÒBkØ—/‘/ $°Ó5×5Ò5ñ ClÑ=Ù5ùs   ‚AC-ÁB
C-Ã C+Ã!C-c               ó    € V ^8„  d   QhRRRR/# )r"   r.   r	   r$   z2Optional[tuple[MessageEvent, SessionSource, bool]]r&   )r'   s   "r(   r)   r=   �   s    € ÷ e$ñ e$Ø!ðe$à	;ñe$r*   c              ƒ  ó$	  "  € ^ RI Hp VP                  p\        V RR4      p ^ RIHp V! 4        \        VRR	4      '       d   V P                  V4       \        VR
R	4      RJ dD   ^ RI
Hp Rp\        \        4      ;_uu_ 4        V P                  V4      pRRR4       V! Ws4       R# \        \        VRR	4      4      p\        VRR4      p	V'       gT   \        VRR4      \        P                   8X  d4   Rp
\        \        4      ;_uu_ 4        V P                  V4      p
RRR4       V'       gH   \        VRR4      \        P                   8X  d(   V! WIX
4      '       d   \        P#                  RV	4       R# ^ RIHp \        V RR	4      '       dE   V'       g=   \        VRR	4      '       g*   VP)                  4       '       g   V P+                  V4       R# V'       d   WR3# \        VRR	4      '       d   WR	3# V P-                  4        V P/                  W4      G Rj  x€L
 pVf   R# VP                  pV P1                  V4      '       Eg¾   VP2                  f-   \        P                  RVP4                  P6                  4       R# VP8                  R8H  ;'       d    \        VRR	4      '       * pV'       d(   V P;                  VP4                  VP<                  R7      MRpVR8X  d\   \        P?                  RVP2                  VP@                  VP4                  P6                  4       V PC                  V4      G Rj  x€L
  R# VR8X  d\   \        P?                  RVP2                  VP@                  VP4                  P6                  4       V PE                  V4      G Rj  x€L
  R# V'       d   V PG                  V4      G Rj  x€L
  R# \        P?                  RVP2                  VP@                  VP4                  P6                  4       R# \        VRR	4      '       g   V PI                  V4      '       g   R# WR	3#   \         d    \        P                  RRR7        EL*i ; i  + '       g   i     ELÑ; i  + '       g   i     EL]; i ELm ELR Lò LÑ5i)z¡Ingress gates for ``_handle_message``; None when dropped, else ``(event, source, is_internal)``
(the ``pre_gateway_dispatch`` hook may have rewritten ``event``).)Ú_is_slack_ignored_channelr`   N)Úreset_session_varsz*reset_session_vars failed at handler entryTrA   Úmultiplex_profilesFÚprofile_route_rejected)Údrop_rejected_routeÚinternalrS   rC   z9Dropping Slack message from configured ignored channel %s©Úexecuting_admissionÚ_startup_restore_in_progressÚ_hermes_startup_restore_replayÚ
_fifo_onlyz(Ignoring message with no user_id from %sÚdmÚis_bot)ÚprofileÚpairz Unauthorized user: %s (%s) on %sÚdeclineÚ_bot_loop_admitted)%Úgateway.runrx   r;   r2   Úgateway.session_contextry   rf   rF   ÚdebugÚ_canonicalizeÚgateway.parked_route_refusalr|   r   Ú_intake_adapter_forÚboolr   ÚSLACKÚinfoÚgateway.session_ingressr   ÚgetÚ_queue_startup_restore_eventÚ _scale_to_zero_note_real_inboundÚ_hm_pre_gateway_dispatch_hookÚ_is_user_authorized_for_sourcerI   rC   rD   Ú	chat_typeÚ_get_unauthorized_dm_behaviorr…   rP   rM   r[   rh   rt   Ú_admit_bot_message_for_source)rU   r.   rx   r;   Ú_configry   r|   Ú_intakeÚis_internalÚ_chat_idÚ_slack_adapterr   Úpairable_dmÚbehaviors   &&            r(   Ú_hm_admit_eventÚ#GatewayInboundMixin._hm_admit_event�   s¿  é € õ
 	:Ø—‘ˆä˜$ ¨$Ó/ˆð
	VÝBÙÔ ô �7Ð0°%×8Ò8Ø×Ñ˜vÔ&Ü�6Ð3°UÓ;¸tÓCÝHØˆGÜœ)×$Õ$Ø×2Ñ2°6Ó:�÷ %á Ô0Ùäœ7 5¨*°eÓ<Ó=ˆô ˜6 9¨dÓ3ˆßœw v¨z¸4Ó@ÄHÇNÁNÔRà!ˆNÜœ)×$Õ$Ø!%×!9Ñ!9¸&Ó!A�÷ %÷ Ü˜ 
¨DÓ1´X·^±^ÔCÙ)¨'¸^×LÒLä�K‰KÐSÐU]Ô^Ùõ 	@ä�DÐ8¸%×@Ò@ßÜ˜EÐ#CÀU×KÒKØ'×+Ñ+×-Ò-à×-Ñ-¨eÔ4ÙçØ $Ð&Ð&Ü�5˜,¨×.Ò.Ø %Ð'Ð'ð 	×-Ñ-Ô/Ø×8Ñ8¸ÓG×GˆØŠ=ÙØ—‘ˆà×2Ñ2°6×:Ó:Ø�~‰~Ò%ô —‘ÐGÈÏÉ×I^ÑI^Ô_Ùð !×*Ñ*¨dÑ2×[Ð[¼7À6È8ÐUZÓ;[Ô7[ˆKßfq�t×9Ñ9¸&¿/¹/ÐSY×SaÑSaÐ9ÔbÐw{ˆHØ˜6Ô!Ü—‘ÐAÀ6Ç>Á>ÐSY×ScÑScÐek×etÑet×ezÑezÔ{Ø×1Ñ1°&Ó9×9Ð9ñ ð ˜YÔ&Ü—‘ÐAÀ6Ç>Á>ÐSY×ScÑScÐek×etÑet×ezÑezÔ{Ø×8Ñ8¸Ó@×@Ð@ñ
 ÷	 Ø×0Ñ0°Ó8×8Ð8ñ ô —‘ÐAÀ6Ç>Á>ÐSY×ScÑScÐek×etÑet×ezÑezÔ{Ùä�uÐ2°E×:Ò:À4×CeÑCeÐfl×CmÒCmÙØ˜eÐ#Ð#øôk ô 	VÜ�L‰LÐEÐPTˆL×Uð	Vú÷ %×$Ð$ú÷ %×$Ð$úò> Hò" :ñ Aá8ùsÖ   ‚ R£P5 °ARÂQÂA6RÄQ2ÄRÄ.A'RÆ(RÆ?RÇ?RÈRÈ-RÉARÊRÊ3BRÌ7R	Ì8A!RÎRÎRÎ(RÎ<RÎ=A1RÐ/RÐ5"QÑRÑQÑRÑQ/	Ñ)	RÑ2R	Ñ=
RÒ	RÒRÒRc               ó$   € V ^8„  d   QhRRRRRR/# )r"   r.   r	   r;   r   r$   r�   r&   )r'   s   "r(   r)   r=   ö   s"   € ÷ ñ ¨Lð À-ð ÐTXñ r*   c                ó¨  € \        \        4      ;_uu_ 4        VP                  4       pV'       d   ^ RIHp V! V4      e    RRR4       R# RRR4       \        \        4      ;_uu_ 4        V P                  V4      pV P                  V4      pVe(   VP                  P                  '       d    RRR4       R# V P                  V4      '       d    RRR4       R# ^ RI
Hp VP                  V4      '       d    RRR4       R# ^ RIHp V! V4      '       d    RRR4       R#  RRR4       R#   + '       g   i     Lé; i  + '       g   i     R# ; i)uO  Whether a turn may bypass the global emergency stop: pause blocks NEW agent turns, never
running work or control traffic â€” recognized slash commands (incl. /pause off, the in-band
resume) and replies owned by in-flight work (pending update prompt, running session,
pending slash-confirm, dangerous-command approval) all pass through.©Úresolve_commandNT©Úslash_confirm©Úhas_blocking_approvalF)r   rf   Úget_commandÚhermes_cli.commandsr§   Ú_session_key_for_sourceÚ_peek_session_stateÚ
persistentÚupdate_prompt_pendingÚ_is_session_runningÚtoolsr©   Úget_pendingÚtools.approvalr«   )	rU   r.   r;   Ú
_estop_cmdÚ_resolve_estop_cmdÚ
_estop_keyÚ_estop_stateÚ_estop_confirm_modÚ_estop_has_approvals	   &&&      r(   Ú_hm_estop_turn_allowedÚ*GatewayInboundMixin._hm_estop_turn_allowedö   s  € ô
 ”i× Õ Ø×*Ñ*Ó,ˆJßÝUÙ% jÓ1Ò=Ø÷ !× Ñ ô ”i× Õ Ø×5Ñ5°fÓ=ˆJØ×3Ñ3°JÓ?ˆLØÒ'¨L×,CÑ,C×,Y×,YÐ,YØ÷	 !Ñ ð ×'Ñ'¨
×3Ò3Ø÷ !Ñ õ BØ!×-Ñ-¨j×9Ò9Ø÷ !Ñ õ TÙ" :×.Ò.Ø÷ !Ñ ð /÷ !ñ ÷) !× ú÷ !Ö ñ úsB   ˜*D-Á+AE Â.E Â9E ÃE ÃE Ã8E ÄE ÄE Ä-D=	Å E	c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r"   r.   r	   r;   r   r�   r�   r$   úOptional[str]r&   )r'   s   "r(   r)   r=     s,   € ÷ ñ Ø!ðØ+8ðØGKðà	ñr*   c           
     ól  € V'       d   R#  ^ RI Hp T! 4       pTe   T P                  Y4      '       d   R# \	        TRR4      '       d   \
        P                  R4       R# \
        P                  R\	        \	        TRR4      RR	4      \	        TR
R4      ;'       g    R	4       T#   \         d     R# i ; i)aQ  Global emergency-stop (`hermes pause`) notice when this turn must be blocked, else None.
Placed after auth so unauthorized senders can't probe pause state. A synthetic heartbeat that
slipped past the poller's pause check gets "" (blocked, nothing sent): nobody typed it, and
settle_heartbeat_attempt leaves its tick due for after resume.N)Úpaused_replyÚ_heartbeat_session_idz/Heartbeat turn dropped by global emergency stopr@   zBGateway turn paused by global emergency stop (platform=%s chat=%s)rC   rD   r?   rS   )Úagent.estoprÁ   ÚImportErrorr¼   r2   rF   r‹   r‘   )rU   r.   r;   r�   Ú_estop_paused_replyÚ_paused_notices   &&&&  r(   Ú_hm_estop_gateÚ"GatewayInboundMixin._hm_estop_gate  s©   € ÷ Ùð	ÝGñ -Ó.ˆØÒ! T×%@Ñ%@À×%OÒ%OÙÜ�5Ð1°4×8Ò8Ü�L‰LÐJÔKÙÜ�‰ØPÜ”G˜F J°Ó5°wÀ	ÓJÜ�F˜I tÓ,×9Ð9°	ô	
ð
 Ðøô ô 	Úð	ús   ŒB$ Â$B3Â2B3c               ó    € V ^8„  d   QhRRRR/# )r"   Úresponse_textr%   r$   r¿   r&   )r'   s   "r(   r)   r=   ,  s   € ÷ ñ °ð ¸ñ r*   c                ó  € ^ RI Hp VR,          p VP                  R4      pVP                  V RR7       VP	                  V4       VR,          P                  RR7       R	#   \         d   p\        T4      u R	p?# R	p?ii ; i)
zXAtomically hand *response_text* to the detached update process; returns the OSError str.)Ú_hermes_homez.update_responsez.tmpzutf-8)Úencodingz.update_prompt.jsonT)Ú
missing_okN)r‰   rÌ   Úwith_suffixÚ
write_textÚreplaceÚunlinkrN   r%   )rÊ   rÌ   Úresponse_pathÚtmpÚes   &    r(   Ú_hm_write_update_responseÚ-GatewayInboundMixin._hm_write_update_response+  sz   € õ 	-Ø$Ð'9Õ9ˆð	Ø×+Ñ+¨FÓ3ˆCØ�N‰N˜=°7ˆNÔ;Ø�K‰K˜Ô&ØÐ1Õ1×9Ñ9ÀTÐ9ÔJñ øô ô 	Ü�q“6�Mûð	ús   ‘AA! Á!BÁ,
A<Á6BÁ<Bc               ó$   € V ^8„  d   QhRRRRRR/# ©r"   r.   r	   Ú
_quick_keyr%   r$   r¿   r&   )r'   s   "r(   r)   r=   9  s!   € ÷ +ñ +¨\ð +Àsð +È}ñ +r*   c                óŠ  € V P                  V4      pVe   VP                  P                  '       g   R# VP                  4       pRpVR9   d   RpM„VR9   d   RpMzV'       dE   \	        \
        4      ;_uu_ 4        ^ RIHp V! V4      pV'       d   VP                  MRpRRR4       V'       d   RM#VP                  ;'       g    RP                  4       pV'       dy   V P                  V4      p	V	e$   \        P                  RV	4       \        RV	R7      # R	VP                  n        \        V4      ^8:  d   TMVR
,          R,           p
\        RV
R7      # V'       dT   V P                  R4      p	V	f   \        P!                  RWR4       M\        P                  RV	4       R	VP                  n        R#   + '       g   i     EL; i)zùConsume a reply to a pending ``/update`` prompt (routed to the detached update process via
``.update_response``); None when nothing was consumed. Recognized slash commands must bypass
this or /new, /help etc. get silently consumed as update answers.NÚyÚnr¦   r@   z#Failed to write update response: %szgateway.update.reply_failed)rG   F:Né   Nõ   â€¦zgateway.update.reply_sent)ÚlabelziRecognized /%s during pending update prompt for %s; cancelled prompt with default and dispatching commandz=Failed to write cancel response for pending update prompt: %s>   ÚyesÚapprove>   ÚnoÚdeny)r¯   r°   r±   r¬   r   rf   r­   r§   Únamerg   re   rÖ   rF   rP   r   Úlenr‘   )rU   r.   rÚ   Ú	_up_stateÚcmdÚ_recognized_cmdrÊ   Ú_resolve_update_cmdÚ_cmd_defÚerrrà   s   &&&        r(   Ú_hm_update_prompt_replyÚ+GatewayInboundMixin._hm_update_prompt_reply9  sw  € ð ×,Ñ,¨ZÓ8ˆ	ØÒ I×$8Ñ$8×$N×$NÐ$NÙà×ÑÓ!ˆØˆØÐ$Ô$Ø‰MØ�NÔ"Ø‰MçÜœi×(Õ(ÝZÙ2°3Ó7�Hß7? h§m¢mÀT�O÷ )÷ #2™B¸¿
¹
×8HÐ8HÀb×7OÑ7OÓ7QˆMßØ×0Ñ0°Ó?ˆCØŠÜ—‘ÐDÀcÔJÜÐ6¸cÔBÐBØ9>ˆI× Ñ Ô6Ü%(¨Ó%7¸2Ô%=‘MÀ=ÐQTÕCUÐX]ÕC]ˆEÜÐ0¸Ô>Ð>÷ Ø×0Ñ0°Ó4ˆCØŠ{Ü—‘ðLà#õô —‘Ð^Ð`cÔdØ9>ˆI× Ñ Ô6Ù÷7 )×(Ð(ús   Á9%F1Æ1G	c               ó(   € V ^8„  d   QhRRRRRRRR/# ©	r"   r.   r	   r;   r   rÚ   r%   r$   r¿   r&   )r'   s   "r(   r)   r=   f  s2   € ÷ Mñ MØ!ðMØ+8ðMØFIðMà	ñMr*   c              ƒ  óà  aa
"  €  ^ RI Hp VP                  SRR7      o
S
f   R# \	        T P                  T4      4      pT P                  T4      G Rj  x€L
 pR T
T3R llpT'       d   T'       g	   T! R4      # T'       d   TP                  R4      '       d   R# TP                  ST4      pY„P                  8X  dá   \        P                  R	SS
P                  4       T P                  T4      p	T	'       d¥    T	P                  TP                  4       \#        \%        \'        T	4      RR4      4      '       dd    T	P)                  S
P                  \+        RS
P,                  TP.                  8X  d   TMS
P,                  ;'       g    TR7      4      G Rj  x€L
  R# R# Y„P0                  8X  d	   T! R4      # Y„P2                  8X  d“   TP5                  S
P                  TP6                  4      '       dg   T P                  T4      p	\#        \%        \'        T	4      RR4      4      '       d1    T	P)                  S
P                  \+        R4      4      G Rj  x€L
  R# R#   \         d     R# i ; i EL  \         d    \        P!                  R
RR7        EL€i ; i EL  \         d    \        P!                  RRR7        R# i ; i Lr  \         d    \        P!                  RRR7        R# i ; i5i)u  Intercept a reply to a pending clarify prompt; None when the message falls through.
Free text answers open-ended/"Other" prompts; "2" answers a multi-choice one. Resolved/retained
replies return "" so adapters don't double-post â€” the agent produces the next user-facing message.)Úclarify_gatewayT)Úinclude_choice_promptsNc               ó    € V ^8„  d   QhRRRR/# )r"   Úwhyr%   r$   r&   )r'   s   "r(   r)   Ú;GatewayInboundMixin._hm_clarify_reply.<locals>.__annotate__v  s   € ÷ 	ñ 	˜ð 	 ñ 	r*   c                óL   <€ \         P                  R V SSP                  4       R# )z=Gateway retained pending clarify after %s (session=%s, id=%s)r@   )rF   r‘   Ú
clarify_id)rõ   Ú_pending_clarifyrÚ   s   &€€r(   Ú_retainÚ6GatewayInboundMixin._hm_clarify_reply.<locals>._retainv  s%   ø€ Ü�K‰KØOØ�ZÐ!1×!<Ñ!<ôñ r*   z+voice transcription produced no usable textÚ/z=Gateway intercepted clarify text response (session=%s, id=%s)z.Failed to resume typing after clarify responserA   Úretire_clarify_cardzgateway.clarify.answered)Úresponsez0Failed to retire clarify card after typed answerr@   zinvalid selection attemptzgateway.clarify.cancelledz6Failed to retire clarify card after prose cancellation)r³   rò   Úget_pending_for_sessionrf   r�   Ú_pending_event_audio_pathsÚ_prepare_clarify_reply_textÚ
startswithÚ!attempt_text_response_for_sessionÚTEXT_RESOLVEDrF   r‘   rø   rQ   Úresume_typing_for_chatrS   r‹   Úcallabler2   Útyperý   r   rþ   ÚSKIPPEDÚTEXT_REJECTED_SELECTIONÚTEXT_REJECTED_PROSEÚresolve_gateway_clarifyÚ	CANCELLED)rU   r.   r;   rÚ   Ú_clarify_modÚ_clarify_has_audioÚ_raw_clarify_replyrú   Ú_text_outcomeÚ_clarify_adapterrù   s   &&&f      @r(   Ú_hm_clarify_replyÚ%GatewayInboundMixin._hm_clarify_replyf  sÃ  ùé € ð	Ý=Ø+×CÑCÀJÐgkÐCÓlÐð Ò#ÙÜ! $×"AÑ"AÀ%Ó"HÓIÐØ#'×#CÑ#CÀEÓ#J×JÐ÷	ñ 	÷ ×&8ÙÐHÓIÐI÷ "Ð%7×%BÑ%BÀ3×%GÒ%GÙØ$×FÑFÀzÐSeÓfˆØ×6Ñ6Ô6Ü�K‰KØOØÐ,×7Ñ7ôð  $×9Ñ9¸&ÓAÐßðbØ$×;Ñ;¸F¿N¹NÔKô
 œG¤DÐ)9Ó$:Ð<QÐSWÓX×YÒYðhØ.×BÑBØ,×7Ñ7ÜÐ8Ø=M×=VÑ=VÐZf×ZnÑZnÔ=nÑ'9Ø#3×#<Ñ#<×#RÐ#RÐ@RôTóU÷ Uð Uó Ø×@Ñ@Ô@ñ Ð6Ó7Ð7Ø×<Ñ<Ô<ð ×3Ñ3Ð4D×4OÑ4OÐQ]×QgÑQg×hÒhð
 $(×#=Ñ#=¸fÓ#EÐ äœG¤DÐ)9Ó$:Ð<QÐSWÓX×YÒYðnØ.×BÑBØ,×7Ñ7ÜÐ9Ó:ó<÷ <ð <ó
 øôI ô 	Úð	úò
 Køô6 !ô bÜ—L‘LÐ!QÐ\`�L×aðbúòUøô
 %ô hÜŸ™Ð%WÐbf˜ÕgÙðhúñ(<øô %ô nÜŸ™Ð%]Ðhl˜ÕmÙðnüsê   „K.†I Ÿ4K.ÁI+ÁK.Á*K.Á2K.ÂK.ÂAK.Ã8I. Ä%K.Ä9AJ ÆJ ÆJÆJ ÆAK.Ç16K.È((K ÉKÉK ÉK.ÉI(É$K.É'I(É(K.É."JÊK.ÊJÊK.ÊJ Ê"K Ê<K.Ê?K Ë K.ËK Ë"K+Ë'K.Ë*K+Ë+K.râ   Úoncerá   ÚokÚconfirmÚalwaysÚrememberÚcancelrã   rä   Ú	nevermindc               ó   € V ^8„  d   QhRR/# )r"   r$   zdict[str, str]r&   )r'   s   "r(   r)   r=   ¿  s   € ÷ ñ ¨^ñ r*   c                	óz   € / pV P                    F(  w  r#\        V4       F  pVP                  WC4       K  	  K*  	  V# ©N)Ú_SLASH_CONFIRM_TEXT_INPUT_KEYSr   Ú
setdefault)rU   ÚchoicesÚ	input_keyÚchoiceÚwords   &    r(   Ú_slash_confirm_text_choicesÚ/GatewayInboundMixin._slash_confirm_text_choices¿  s?   € Ø"$ˆØ!%×!DÔ!DÑˆIÜ,¨YÖ7�Ø×"Ñ" 4Ö0ó 8ñ "Eð ˆr*   c               ó$   € V ^8„  d   QhRRRRRR/# rÙ   r&   )r'   s   "r(   r)   r=   Æ  s"   € ÷ ñ °<ð ÈSð ÐUbñ r*   c              ƒ  ó°  "  € ^ RI Hp VP                  V4      pV'       g   R# \        \        4      ;_uu_ 4        ^ RIHp V! V4      '       d    RRR4       R#  RRR4       VP                  ;'       g    RP                  4       P                  R4      P                  4       pV P                  P                  VP                  4       4      ;'       g     V P                  4       P                  V4      pVe6   VP                  W$P                  R4      V4      G Rj  x€L
 pT;'       g    R# VP!                  V4       R#   + '       g   i     Lí; i L65i)u  Resolve a reply (/approve, /always, /cancel + aliases) to a pending slash-confirm prompt;
None when it falls through â€” a stale pending confirm does NOT block other commands. A pending
dangerous-command approval takes precedence: /approve there unblocks the waiting tool thread.r¨   Nrª   r@   z!/Ú
confirm_id)r³   r©   r´   r   rf   rµ   r«   rg   re   ÚlstripÚlowerÚ_SLASH_CONFIRM_CMD_CHOICESr“   r¬   r$  ÚresolveÚclear_if_stale)	rU   r.   rÚ   Ú_slash_confirm_modÚ_pending_confirmr«   Ú_norm_replyÚ_confirm_choiceÚ	_resolveds	   &&&      r(   Ú_hm_slash_confirm_replyÚ+GatewayInboundMixin._hm_slash_confirm_replyÆ  s  é € õ 	>Ø-×9Ñ9¸*ÓEÐßÙÜ”i× Õ Ý<Ù$ Z×0Ò0Ø÷ !Ñ à0÷ !ð —z‘z×'Ð' R×.Ñ.Ó0×7Ñ7¸Ó=×CÑCÓEˆà×+Ñ+×/Ñ/°×0AÑ0AÓ0CÓD÷ Cð CØ×/Ñ/Ó1×5Ñ5°kÓBð 	ð Ò&Ø0×8Ñ8Ø×0Ñ0°Ó>Àó÷ ˆIð —?�? Ð"ð 	×)Ñ)¨*Ô5Ù÷) !× úñùsB   ‚9E»EÁ
EÁEÁ7AEÃAEÄEÄEÄ+EÅE	Å	Ec               ó    € V ^8„  d   QhRRRR/# ©r"   rÚ   r%   r$   r<   r&   )r'   s   "r(   r)   r=   ä  s   € ÷ 3Uñ 3U°Sð 3U¸Tñ 3Ur*   c                óð  € ^ RI HpHp V! RR4      pV P                  V4      pV'       d   VP                  P
                  M^ pVe!   VP                  P                  e	   V'       g   R# \        P                  ! 4       V,
          pVP                  P                  p\        R4      p	Rp
RpV'       Ed   \        VR4      '       Ed   \        \        4      ;_uu_ 4        VP                  4       p^ R	IHp \        V\         4      '       d   TM/ pT! \        V\         4      '       d   TMR\        P                  ! 4       R
7      pVe;   Tp	Rp\#        VP                  P$                  RR4      pVe   VP'                  V	4      p	RVP)                  RR4       RV	R RVP)                  R^ 4       RVP)                  R^ 4       2p
RRR4       V^ 8”  d   \+        V^
,          R4      M
\        R4      pW‚J;'       d8    T;'       d    V^ 8„  ;'       d    W”8¬  ;'       g    V'       * ;'       d    VV8„  pV'       d-   \,        P/                  RWW”V
4       V P1                  VR4       R# R#   + '       g   i     L­; i)u=  Evict a leaked lock from a hung/crashed handler: only when the agent has been *idle* past
the threshold (active tasks can run for hours), or has no activity tracker and an extreme
wall-clock age. The pending sentinel is never evicted (no get_activity_summary() â†’ idle
reads inf and would race the async setup path).)Ú_AGENT_PENDING_SENTINELÚ
_float_envÚHERMES_AGENT_TIMEOUTi  NÚinfr@   FÚget_activity_summary)Ú*resolve_session_idle_seconds_from_activity)ÚnowTÚ
awake_idlez | last_activity=Úlast_activity_descr?   z (z.0fzs ago) | iteration=Úapi_call_countrü   Úmax_iterationsi   zWEvicting stale _running_agents entry for %s (age: %.0fs, idle: %.0fs, timeout: %.0fs)%sÚstale_running_agent_eviction)r‰   r8  r9  r¯   ÚturnÚ
started_tsÚagentÚtimeÚfloatÚhasattrr   rf   r<  Úgateway.session_stallr=  r3   Údictr2   ÚctxÚmeasurer“   ÚmaxrF   rP   Ú_hm_evict_running_agent)rU   rÚ   r8  r9  Ú_raw_stale_timeoutÚ_quick_stateÚ	_stale_tsÚ
_stale_ageÚ_stale_agentÚ_stale_idleÚ_stale_detailÚ_activity_summary_validÚ_sar=  Ú_sa_dÚ_resolved_idleÚ_awake_idleÚ	_wall_ttlÚ_should_evicts   &&                 r(   Ú_hm_evict_idle_stale_agentÚ.GatewayInboundMixin._hm_evict_idle_stale_agentä  sC  € ÷
 	DÙ'Ð(>ÀÓEÐØ×/Ñ/°
Ó;ˆß4@�L×%Ñ%×0Ò0Àaˆ	ØÒ <×#4Ñ#4×#:Ñ#:Ò#BÏ)ÙÜ—Y’Y“[ 9Õ,ˆ
Ø#×(Ñ(×.Ñ.ˆÜ˜E“lˆØˆØ"'Ðßˆ<œG LÐ2H×IÓIÜœ)×$Õ$Ø"×7Ñ7Ó9�Ý\ä)¨#¬t×4Ò4™¸"�Ù!KÜ% c¬4×0Ò0‘C°dÄÇ	Â	Ãô"�ð "Ò-Ø"0�KØ.2Ð+ä")¨,×*;Ñ*;×*?Ñ*?ÀÈtÓ"T�KØ"Ò.Ø&1×&9Ñ&9¸+Ó&F˜à'¨¯	©	Ð2FÈ	Ó(RÐ'Sð TØ# CÐ(ð )#Ø#(§9¡9Ð-=¸qÓ#AÐ"BÀ!ÀEÇIÁIÐN^Ð`aÓDbÐCcðeð ÷ %ð. ;MÈqÔ:P”CÐ*¨RÕ/°Ô6ÔV[Ð\aÓVbˆ	Ø$ÐC÷ 
ð 
Ø$×eÐeÐ);¸aÑ)?×eÐeÀKÑDe÷ Hð HØ+Ô+×FÐF°
¸YÑ0Fð 	÷ Ü�N‰Nð>à¨Èôð
 ×(Ñ(¨Ð5SÖTñ ÷9 %×$ús   ÃC#I%É%I5	c               ó    € V ^8„  d   QhRRRR/# r6  r&   )r'   s   "r(   r)   r=     s   € ÷ Qñ Q°ð Q¸ñ Qr*   c                ó´  €  \        V RR4      p\        VRR4      p\        VRR4      p\        V4      '       d	   V! V4      MRp\        V\        4      '       dV   V'       dL   \        V4      '       d9   V! V4      RJ d+   \        P                  RW4       V P                  VR4       R# R# R# R# R#   \         d    \        P                  RRR	7        R# i ; i)
a  Evict the in-memory turn slot of a session whose durable row was ended while the gateway
lived (``ws_orphan_reap`` / ``agent_close``): otherwise the fast-path queues every next
message into the dead runtime. The cold path re-attaches via ``get_or_create_session``.Úsession_storeNÚpeek_session_idÚ_is_session_ended_in_dbTuŠ   Evicting stale _running_agents entry for %s â€” durable session %s is ended (reaped) in state.db; healing routing on next message (#99106)Úreaped_session_evictionz%reaped-session staleness check failedrA   )	r2   r  r3   r%   rF   rP   rO  rf   r‹   )rU   rÚ   Ú_reap_storeÚ
_reap_peekÚ	_is_endedÚ	_reap_sids   &&    r(   Ú_hm_evict_reaped_agentÚ*GatewayInboundMixin._hm_evict_reaped_agent  sÐ   € ð	Qô
 " $¨¸Ó>ˆKô ! Ð.?ÀÓFˆJÜ Ð-FÈÓMˆIÜ2:¸:×2FÒ2F™
 :Ô.ÈDˆIÜ˜)¤S×)Ò)¯i¼HÀY×<OÒ<OÑT]Ð^gÓThÐlpÓTpÜ—‘ð?à@Jôð
 ×,Ñ,¨ZÐ9RÖSñ UqÑ<O©iÑ)øô ô 	QÜ�L‰LÐ@È4ˆL×Pð	Qús   ‚AB1 Á"AB1 Â1"CÃCc               ó$   € V ^8„  d   QhRRRRRR/# )r"   rÚ   r%   Úreasonr$   r<   r&   )r'   s   "r(   r)   r=   3  s&   € ÷ Rñ R°#ð R¸sð RÀtñ Rr*   c                	ób   € ^ RI HpHp V P                  WVVR7      pV P	                  WR7       R# )é    )Ú_INTERRUPT_REASON_EVICTEDÚ_INTERRUPT_TOOL_REASON_EVICTED)Úinterrupt_reasonÚinvalidation_reasonÚtool_reason©Úrun_generationN)r‰   rp  rq  Ú_interrupt_running_turnÚ_drop_turn_slot)rU   rÚ   rm  rp  rq  Ú_generation_at_interrupts   &&&   r(   rO  Ú+GatewayInboundMixin._hm_evict_running_agent3  s8   € ßYØ#'×#?Ñ#?ØÐX^Ø6ð $@ó $8Ð ð 	×Ñ˜ZÐÖQr*   Ú
merge_textFc          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r"   r;   r   rÚ   r%   r.   r	   r{  r�   r$   r<   r&   )r'   s   "r(   r)   r=   :  s;   € ÷ mñ mØ#ðmØ14ðmØ=IðmØZ^ðmà	ñmr*   c               ór   € ^ RI Hp V P                  V4      pV'       d   V! VP                  W#VR7       R# R# )zPMerge *event* into the source adapter's pending slot (no-op without an adapter).)Úmerge_pending_message_event©r{  N)Úgateway.platforms.baser~  rQ   Ú_pending_messages)rU   r;   rÚ   r.   r{  r~  rY   s   &&&&$  r(   Ú_hm_merge_pending_for_sourceÚ0GatewayInboundMixin._hm_merge_pending_for_source:  s3   € õ 	GØ×,Ñ,¨VÓ4ˆßÙ'¨×(AÑ(AÀ:Ðak×lñ r*   c               ó(   € V ^8„  d   QhRRRRRRRR/# ©	r"   r.   r	   r;   r   rÚ   r%   r$   útuple[bool, Optional[str]]r&   )r'   s   "r(   r)   r=   C  s,   € ÷  ñ  Ø!ð Ø+8ð ØFIð à	#ñ r*   c              ƒ  ó’  "  € ^ RI Hp VP                  4       pV'       d	   V! V4      MRpV'       dÂ   VP                  R8X  d   RV P	                  V4      G Rj  x€L
 3# VP                  R8X  d   RV P                  V4      G Rj  x€L
 3# V P                  W&P                  4      pVe   RV3# VP                  R9   d   V P                  V4      G Rj  x€L
  RV P                  WW24      G Rj  x€L
 3# VP                  \        P                  8X  d+   \        P                  RV4       V P                  W#V4       R# R	#  Lå L» Lo LV5i)
u±   Slash-command / photo-burst handling on the busy fast-path â†’ ``(handled, result)``. Each
command's mid-run behavior is declared on its CommandDef (busy_policy / busy_handler).r¦   NÚstatusTÚcontextuF   PRIORITY photo follow-up for session %s â€” queueing without interrupt)ÚstopÚnew©TN©FN)r­   r§   r¬   rå   Ú_handle_status_commandÚ_handle_context_commandÚ_check_slash_accessÚ_hm_stop_owner_turnÚ_dispatch_busy_slash_commandÚmessage_typer
   ÚPHOTOrF   r‹   r‚  )rU   r.   r;   rÚ   Ú_resolve_cmd_innerÚ_evt_cmdÚ_cmd_def_innerÚ_denieds   &&&&    r(   Ú_hm_busy_slash_or_photoÚ+GatewayInboundMixin._hm_busy_slash_or_photoC  s7  é € õ
 	NØ×$Ñ$Ó&ˆß9AÑ+¨HÔ5Àtˆçà×"Ñ" hÔ.Ø 4×#>Ñ#>¸uÓ#E×EÐEÐEØ×"Ñ" iÔ/Ø 4×#?Ñ#?ÀÓ#F×FÐFÐFð ×.Ñ.¨v×7JÑ7JÓKˆGØÒ"Ø˜W�}Ð$Ø×"Ñ" oÔ5Ø×.Ñ.¨zÓ:×:Ð:ð ˜t×@Ñ@ÀÐXbÓk×kÐkÐkð ×Ñ¤×!2Ñ!2Ô2Ü�L‰LÐaÐcmÔnØ×-Ñ-¨fÀ%ÔHØÐØÐñ) FáFñ ;ñ lùsN   ‚0E³&EÁD?Á+EÂEÂAEÃEÃEÃ.EÃ/AEÅEÅEÅEc               ó    € V ^8„  d   QhRRRR/# r6  r&   )r'   s   "r(   r)   r=   e  s   € ÷ &Sñ &S°Cð &S¸Dñ &Sr*   c           	   ƒ  óâ  "  € ^ RI Hp V! V 4      pV'       d+   VP                  V P                  P	                  V4      4      MRpV'       d   WCP
                  9  d   Ve   VP                  V4       R# ^ RIHpH	p ^ RI
HpHp V! VP                  V4      p	V! RVP                  \        RR04      R4      p
\        P                   ! WƒP"                  VR	7      G Rj  x€L
 p\$        ;QJ d    R
 V 4       F  '       g   K   RM	  RM! R
 V 4       4      pV'       g<   VP                  V4       \        P                   ! WƒP"                  VR	7      G Rj  x€L
 pV'       d   . MT Fp  pVR,          R8X  g   K  VR,          P'                  R4      '       g   K3  \)        V4      ;_uu_ 4        VP+                  W©VR,          4      G Rj  x€L
  RRR4       Kr  	  VP-                  V	4      pVP.                  R8X  dC   \)        V4      ;_uu_ 4        VP1                  W©VP2                  4      G Rj  x€L
  RRR4       R# R#  ELb Lí L{  + '       g   i     Kò  ; i L+  + '       g   i     R# ; i5i)aÇ  Messaging /stop and /new (busy, idle or confirmed) act on the authority's turn, as main
cancelled the adapter task that ran it and dropped its pending slot. Cancels the still-queued
``messaging:*`` rows of this route's logical owner first (automation wakes, LOCAL/API input
and ``unknown`` rows are untouched; settled silently, no pause notice), then interrupts the
claimed generation: a turn still constructing its agent latches the Stop for adopt_agent.©Úactive_authorityN)Ú	PrincipalÚ
SessionRef)ÚRuntimeStoreErrorÚlist_session_admissionszmessaging-controlzsession:submitzsession:controlzbusy-command)Ú
session_idc              3  ó8   "  € T F  qR ,          R8H  x € K  	  R# 5i)rˆ  r?   Nr&   )Ú.0Úrows   & r(   Ú	<genexpr>Ú:GatewayInboundMixin._hm_stop_owner_turn.<locals>.<genexpr>{  s   é € Ð@¹4°C˜•] iÖ/»4ùs   ‚TFrˆ  ÚqueuedÚprincipal_idz
messaging:Úadmission_idÚrunning)Úgateway.session_authoritiesrž  Úlogical_ownerrb  rc  ÚsessionsÚfence_routeÚgateway.session_contractrŸ  r   Úhermes_state_runtimer¡  r¢  Ú
profile_idÚ	frozensetrJ   rK   ÚdbÚanyr  r   Úcancel_queuedÚ_handleÚexecution_stateÚ	interruptÚexecution_generation)rU   rÚ   rž  Ú	authorityÚsidrŸ  r   r¡  r¢  ÚrefÚactorÚrowsÚpausedr¦  Úhandles   &&             r(   r‘  Ú'GatewayInboundMixin._hm_stop_owner_turne  sï  é € õ 	AÙ$ TÓ*ˆ	ßYbˆi×%Ñ% d×&8Ñ&8×&HÑ&HÈÓ&TÔUÐhlˆß�c×!3Ñ!3Ô3ØÒ$à×%Ñ% jÔ1ÙßBßSÙ˜×-Ñ-¨sÓ3ˆÙÐ-¨y×/CÑ/CÜ#Ð%5Ð7HÐ$IÓJÈNó\ˆä×&Ò&Ð'>ÇÁÐY\Ô]×]ˆ÷ “Ñ@¹4Ó@——’Ñ@¹4Ó@Ó@ˆßð ×!Ñ! *Ô-Ü ×*Ò*Ð+BÇLÁLÐ]`Ôa×aˆDß‘2 TÒ)ˆCØ�8�} Ö(¨S°Õ-@×-KÑ-KÈL×-YÔ-YäÐ/×0Õ0Ø#×1Ñ1°%¸cÀ.Õ>QÓR×RÐR÷ 1Ñ0ñ *ð
 ×"Ñ" 3Ó'ˆØ×!Ñ! YÔ.äÐ+×,Õ,Ø×)Ñ)¨%°f×6QÑ6QÓR×RÐR÷ -Ñ,ñ /ò! ^ñ bñ
 S÷ 1×0Ð0úñ S÷ -×,Ð,üs¤   ‚A
I/ÁBI/ÃH>ÃI/Ã,I/Ä I/Ä6I/ÅIÅI/Å I/Å7I/ÆI/Æ*IÇI
ÇIÇAI/È IÈ-IÈ.IÈ2I/ÉI/ÉIÉIÉ	I/ÉIÉI,	É&	I/c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r"   r.   r	   r;   r   rÚ   r%   Úeffective_busy_input_moder$   r�   r&   )r'   s   "r(   r)   r=   �  s4   € ÷ ñ Ø!ðØ+8ðØFIðØfiðà	ñr*   c                óz  € \        \        P                  ! RR4      4      pV P                  V4      pV'       d   VP                  P
                  M^ pVP                  \        P                  8X  dP   VP                  \        P                  8X  d1   V^ 8”  d*   V'       d"   \        P                  ! 4       V,
          V8:  g   R# \        P                  R\        P                  ! 4       V,
          V4       VR8w  d   V P                  W#VRR7       R# V P!                  V4      pV'       d   V P#                  W1V4       R# )zNQueue a Telegram text follow-up that lands within the post-start grace window.Ú&HERMES_TELEGRAM_FOLLOWUP_GRACE_SECONDSz3.0FuV   Telegram follow-up arrived %.2fs after run start for %s â€” queueing without interruptÚqueueTr  )rH  ÚosÚgetenvr¯   rD  rE  rC   r   ÚTELEGRAMr“  r
   ÚTEXTrG  rF   r‹   r‚  rQ   Ú_enqueue_fifo)	rU   r.   r;   rÚ   rÅ  Ú_graceÚ_grace_stateÚ_started_atrY   s	   &&&&&    r(   Ú_hm_busy_telegram_grace_queueÚ1GatewayInboundMixin._hm_busy_telegram_grace_queue�  sî   € ô ”r—y’yÐ!IÈ5ÓQÓRˆØ×/Ñ/°
Ó;ˆß6B�l×'Ñ'×2Ò2Èˆà�O‰Oœx×0Ñ0Ô0°U×5GÑ5GÌ;×K[ÑK[Ô5[Ø˜”
Ÿ{´·	²	³¸kÕ0IÈfÔ/TáÜ�‰ØdÜ�IŠI‹K˜+Õ% zô	
ð %¨Ô/Ø×-Ñ-¨fÀ%ÐTXÐ-ÔYñ
 ð ×0Ñ0°Ó8ˆGßØ×"Ñ" :°gÔ>Ùr*   c               ó    € V ^8„  d   QhRRRR/# ©r"   r.   r	   r$   r�   r&   )r'   s   "r(   r)   r=   ¦  s   € ÷ iñ i˜\ð i¨dñ ir*   c                	ó    € V P                   \        P                  8H  ;'       d+    V P                  '       * ;'       d    V P                  '       * # r  )r“  r
   rÌ  Ú
media_urlsÚmedia_types)r.   s   &r(   Ú_hm_text_onlyÚ!GatewayInboundMixin._hm_text_only¥  s<   € à×!Ñ!¤[×%5Ñ%5Ñ5×hÐh¸e×>NÑ>NÔ:N×hÐhÐW\×WhÑWhÔShÐhr*   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r"   r.   r	   Úrunning_agentr   rÚ   r%   r$   r<   r&   )r'   s   "r(   r)   r=   ©  s0   € ÷ @ñ @ Lð @Àð @ÐRUð @ÐZ^ñ @r*   c                ó  € VP                   ;'       g    RP                  4       pRpV P                  V4      '       d<   V'       d4   \        VR4      '       d"    V P	                  W P                  WA4      4      pV'       d+   V P                  W#V4       \        P                  RV4       R# \        P                  RV4       V P                  W14       R#   \         d!   p\        P                  RY64        Rp?L�Rp?ii ; i)zYSteer mode: inject text mid-run via ``agent.steer()``, else fall back to queue semantics.r@   FÚsteerz(PRIORITY steer failed for session %s: %sNzPRIORITY steer for session %sz/PRIORITY steer-fallback-to-queue for session %s)rg   re   rØ  rI  Ú_steer_running_agentÚ_steer_text_with_originrf   rF   rP   Ú_fold_into_running_turnr‹   Ú_queue_or_replace_pending_event)rU   r.   rÛ  rÚ   Ú
steer_textÚsteeredÚexcs   &&&&   r(   Ú_hm_busy_steerÚ"GatewayInboundMixin._hm_busy_steer©  sÌ   € à—j‘j×&Ð& B×-Ñ-Ó/ˆ
ØˆØ×Ñ˜e×$Ò$¯¼ÀÈw×8WÒ8Wð\Ø×3Ñ3°M×C_ÑC_Ð`jÓCrÓs�÷ Ø×(Ñ(¨ÀEÔJÜ�L‰LÐ8¸*ÔEÙÜ�‰ÐFÈ
ÔSØ×,Ñ,¨ZÖ?øô ô \Ü—‘ÐIÈ:×[Ñ[ûð\ús   Á C ÃC?ÃC:Ã:C?c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r"   r.   r	   r;   r   rÛ  r   rÚ   r%   r$   r<   r&   )r'   s   "r(   r)   r=   ¹  s4   € ÷ 1ñ 1Ø!ð1Ø+8ð1ØILð1ØZ]ð1à	ñ1r*   c              ƒ  ó   "  € ^ RI Hp \        VRR4      RJ pV P                  V4      '       dm   V'       de   \	        VR4      '       dS   T P                  Y1P                  ;'       g    RP                  4       WA4      '       d   \        P                  RV4       R# \        P                  R	V4       VP                  pV P                  V4      '       dC   T P                  YP                  V4      Y!P                  ;'       g    RR
R7      G Rj  x€L
 w  rxM#V'       g   \        VRR4      '       d	   V! V4      pVP                  V4       R#  L=5i)zZInterrupt path: redirect text-only corrections when supported, else ``agent.interrupt()``.)Ú_build_media_placeholderÚ_supports_active_turn_redirectFTÚredirectr@   z PRIORITY redirect for session %sNz!PRIORITY interrupt for session %szVoice-priority-interrupt)Úlog_contextrÖ  )r‰   ré  r2   rØ  rI  Ú_redirect_active_turnrg   re   rF   r‹   r   Ú"_transcribe_and_echo_pending_voicerQ   rº  )	rU   r.   r;   rÛ  rÚ   ré  Ú_can_redirectÚ_interrupt_textÚ_s	   &&&&&    r(   Ú_hm_busy_interruptÚ&GatewayInboundMixin._hm_busy_interrupt¹  s  é € õ 	9ô   Ð/OÐQVÓWÐ[_Ð_ˆØ×Ñ˜e×$Ò$¯¼7À=ÐR\×;]Ò;]Ø×)Ñ)¨-¿*¹*×:JÐ:JÈ×9QÑ9QÓ9SÐU_×gÒgÜ—‘Ð?ÀÔLÙÜ�‰Ð8¸*ÔEØŸ*™*ˆØ×*Ñ*¨5×1Ò1Ø'+×'NÑ'NØ×1Ñ1°&Ó9¸6Ç:Á:×CSÐCSÐQSØ6ð (Oó (÷ "ÑˆO˜Q÷ !¤W¨U°LÀ$×%GÒ%GÙ6°uÓ=ˆOð 	×Ñ Ö0ñ"ùs/   ‚4E·/EÁ'A,EÃ-EÄEÄEÄEÄ/Ec               ó(   € V ^8„  d   QhRRRRRRRR/# )	r"   r.   r	   r;   r   rÚ   r%   r$   r�   r&   )r'   s   "r(   r)   r=   Ò  s*   € ÷ ;ñ ;¨Lð ;À-ð ;Ð]`ð ;Ðeiñ ;r*   c              ƒ  ó:  "  € ^ RI Hp V P                  V4      pV P                  V4      pV'       d   VP                  P
                  MRpV P                  V4      pV P                  '       gJ   VeF   VeB   WtJ g=   VP                  \        P                  8X  d    VR8w  d   V P                  V4      R8X  d   R# V P                  WWW4      G Rj  x€L
 p	V P                  WW†Wy4      G Rj  x€L
  \        V	P                  ;'       g    V	P                   4      #  LH L/5i)uÆ  busy_input_mode for a follow-up the durable FIFO is about to admit, through main's own busy
resolution (voice transcribed into steer/interrupt, steer folded into the turn, busy ack).
Returns True when the text already landed inside the running turn (steer / redirect), so it
must NOT also be admitted as its own turn; False when the caller should admit it (queue mode,
a demotion, or an interrupt â€” the ended turn lets the FIFO run the follow-up next).©r8  NrÝ  rÈ  F)r‰   r8  Ú_effective_busy_input_moder¯   rD  rF  rQ   Ú	_drainingr“  r
   rÌ  Ú_effective_busy_text_modeÚ_resolve_busy_steer_or_redirectÚ_busy_interrupt_and_ackr�   rã  Ú
redirected)
rU   r.   r;   rÚ   r8  ÚmodeÚstaterÛ  rY   Úoutcomes
   &&&&      r(   Ú_hm_busy_preemptÚ$GatewayInboundMixin._hm_busy_preemptÒ  sè   é € õ 	8Ø×.Ñ.¨vÓ6ˆØ×(Ñ(¨Ó4ˆß,1˜Ÿ
™
×(Ò(°tˆØ×,Ñ,¨VÓ4ˆØ�N�NˆN˜gšo°Ò1FÈ-ÓJrØ×&Ñ&¬+×*:Ñ*:Ô:¸tÀw¼Ø×6Ñ6°vÓ>À'ÔIÙØ×<Ñ<¸UÐPTÓd×dˆØ×*Ñ*¨5¸gÈmÓe×eÐeÜ�G—O‘O×9Ð9 w×'9Ñ'9Ó:Ð:ñ eÙeùs1   ‚A+DÁ.A DÃDÃDÃ)DÃ*DÄDÄDc               ó(   € V ^8„  d   QhRRRRRRRR/# rð   r&   )r'   s   "r(   r)   r=   å  s,   € ÷ ;ñ ;Ø!ð;Ø+8ð;ØFIð;à	ñ;r*   c              ƒ  óP  "  € ^ RI Hp \        VRR4      '       d*   VP                  4       '       g   V P	                  W14       R# V P                  WV4      G Rj  x€L
 w  rVV'       g   V P                  WV4      G Rj  x€L
 w  rVV'       d   V# V P                  V4      pV P                  WW74      '       d   R# V P                  V4      pV'       d   VP                  P                  MRp	W”J dg   VP                  4       R8X  d<   V P                  V4       \        P                  RV4       \        \!        R4      4      # V P#                  W#VRR	7       R# V P$                  '       di   V P'                  V4      p
V
'       d   V P	                  W14       V
'       d   \!        R
V P)                  4       R7      # \!        RV P)                  4       R7      # VR8X  d*   \        P+                  RV4       V P	                  W14       R# VR8X  d   V P-                  WV4       R# V P/                  V	4      '       d   RpM>V P1                  V4      G Rj  x€L
 '       d   RpMV P3                  WW“4      G Rj  x€L
  R# \        P                  RW;4       V P	                  W14       R#  ELB EL! LX L75i)zªFast-path while this session's agent is running: interrupt by default (minimal latency);
busy_input_mode queue/steer, subagent and compression protection demote to queue.rö  r}   FNrŠ  u7   HARD STOP (pending) for session %s â€” sentinel clearedz"gateway.stop.force_stopped_pendingTr  zgateway.busy.drain_queued)Úactionzgateway.busy.drain_rejectedrÈ  z'PRIORITY queue follow-up for session %srÝ  z7because the running agent has active subagents (#30170)z1because context compression is in flight (#56391)z5PRIORITY interrupt demoted to queue for session %s %s)r‰   r8  r2   r¬   rá  r™  Ú_busy_skill_turnr÷  rÑ  r¯   rD  rF  Ú_release_running_agent_staterF   r‘   r   r   r‚  rø  Ú_queue_during_drain_enabledÚ_status_action_gerundr‹   rå  Ú_agent_has_active_subagentsÚ"_session_has_compression_in_flightrò  )rU   r.   r;   rÚ   r8  Ú_handledÚ_resultrÅ  Ú	_ra_staterÛ  Úqueue_during_drainÚ_demotes   &&&&        r(   Ú"_hm_handle_running_session_messageÚ6GatewayInboundMixin._hm_handle_running_session_messageå  sK  é € õ
 	8Ü�5˜* e×,Ò,°U×5FÑ5F×5HÒ5Hð ×0Ñ0°ÔCÙØ"&×">Ñ">¸uÈjÓ"Y×YÑˆßØ&*×&;Ñ&;¸EÈ:Ó&V× VÑˆHßØˆNà$(×$CÑ$CÀFÓ$KÐ!Ø×-Ñ-¨e¸Z×cÒcÙà×,Ñ,¨ZÓ8ˆ	ß09˜	Ÿ™×,Ò,¸tˆØÓ3Ø× Ñ Ó" fÔ,Ø×1Ñ1°*Ô=Ü—‘ÐUÐWaÔbÜ%¤aÐ(LÓ&MÓNÐNØ×-Ñ-¨fÀ%ÐTXÐ-ÔYÙØ�>�>ˆ>Ø!%×!AÑ!AÐB[Ó!\Ðß!Ø×4Ñ4°ZÔG÷ &ô Ð-°d×6PÑ6PÓ6RÔSðô Ð4¸T×=WÑ=WÓ=YÔZðð
 %¨Ô/Ü�L‰LÐBÀJÔOØ×0Ñ0°ÔCÙØ$¨Ô/Ø×Ñ °jÔAÙð
 ×+Ñ+¨M×:Ò:ØO‰GØ×:Ñ:¸:ÓF×FÖFØI‰Gà×)Ñ)¨%¸ÓS×SÐSÙÜ�‰ÐKÈZÔaØ×,Ñ,¨ZÔ?Ùòa Zâ VñN Gñ Tùsy   ‚/J&²(J&ÁJÁ#J&Á>JÁ?J&ÂAJ&ÃBJ&Å(J&ÆJ&ÆBJ&È2J&É	J"É
	J&ÉJ&É,J$É-0J&ÊJ&Ê"J&Ê$J&c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r"   r.   r	   r;   r   rÚ   r%   r$   z8tuple[bool, Optional[str], Optional[str], Optional[str]]r&   )r'   s   "r(   r)   r=   "  s,   € ÷ ,/ñ ,/Ø!ð,/Ø+8ð,/ØFIð,/à	Añ,/r*   c              ƒ  ó&  a"  € ^ RI HpHo V3R lpVP                  4       pV! V4      w  rxV'       d_   Vf[   V P	                  4       P                  V4      p	V	e8   V	P                  R4      R8X  d"   V P                  W4      p
V
e   T
pV! V4      w  rxV'       d   V'       d   V! V4      '       g   RRWh3# V P                  W(4      pVe   RW¶V3# V P                  WW6V4      G Rj  x€L
 w  rÍp
V'       d   RWÖV3# V
e   T
pV! V4      w  rxRRWh3#  L)5i)uª   Resolve the slash command (aliases, access gate, hooks) â†’ ``(handled, result, command,
canonical)``; when ``handled`` the caller returns ``result`` as-is (may be None).)Úis_gateway_known_commandr§   c                óX   <€ V '       d	   S! V 4      MR pY'       d   VP                   3# T 3# r  )rå   )rè   Ú_defÚ_resolve_cmds   & €r(   Ú_canonÚ7GatewayInboundMixin._hm_resolve_command.<locals>._canon)  s*   ø€ ç(+‘< Ô$°ˆDØ¦t˜$Ÿ)™)Ð5Ð5°Ð5Ð5r*   Nr  ÚaliasFT)	r­   r  r§   r¬   Ú_hm_quick_commandsr“   Ú_hm_expand_alias_quick_commandr�  Ú_hm_command_hooks)rU   r.   r;   rÚ   r  r  Úcommandrë   Ú	canonicalÚqcmdÚnew_commandr˜  r  r  r  s   &&&&          @r(   Ú_hm_resolve_commandÚ'GatewayInboundMixin._hm_resolve_command"  s+  øé € ÷
 	bõ	6ð
 ×#Ñ#Ó%ˆÙ$ W›oÑˆ÷
 �xÒ'Ø×*Ñ*Ó,×0Ñ0°Ó9ˆDØÒ D§H¡H¨VÓ$4¸Ô$?Ø"×AÑAÀ%ÓN�ØÒ*Ø)�GÙ*0°«/Ñ'�HçŸIÑ*BÀ9×*MÒ*MØ˜$ Ð2Ð2ð
 ×*Ñ*¨6Ó=ˆØÒØ˜¨9Ð4Ð4à/3×/EÑ/EØ˜:°	ó0
÷ *
Ñ&ˆ˜;÷ Ø˜¨9Ð4Ð4ØÒ"Ø!ˆGÙ"(¨£/ÑˆHØ�d˜GÐ.Ð.ñ*
ùs$   ƒBDÂDÂ"DÂ05DÃ%DÃ&*Dc               ó$   € V ^8„  d   QhRRRRRR/# )r"   r  r%   Údetailr$   r†  r&   )r'   s   "r(   r)   r=   P  s"   € ÷ 
ñ 
¸Cð 
Èð 
ÐZtñ 
r*   c           	   ƒ  	ód   aa"  € VV3R  lpRV P                  SVRV 2W5R7      G Rj  x€L
 3#  L5i)c               “  ó0   <"  € S! S 4      G R j  x€L
 #  L5ir  r&   )r.   Úhandlers   €€r(   Ú_executeÚ=GatewayInboundMixin._hm_confirm_destructive.<locals>._executeQ  s   øé € Ù  ›×'Ð'Ñ'ùs   ƒ��Trü   )r.   r  Útitler%  ÚexecuteN)Ú _maybe_confirm_destructive_slash)rU   r.   r  r%  r(  r)  s   &f&&f r(   Ú_hm_confirm_destructiveÚ+GatewayInboundMixin._hm_confirm_destructiveP  sD   ùé € ö	(à˜4×@Ñ@Ø °!°G°9°Àfð Aó 
÷ 
ð 
ð 	
ñ 
ùs   „$0¨.©0c              ƒ  	óò   "  € \         P                  ! V P                  V4      G R j  x€L
 '       d   RV P                  4       3# V P	                  VR\        R4      V P                  4      G R j  x€L
 #  LK L5i)NTr‹  zgateway.confirm.detail_new)rJ   rK   Ú_is_telegram_topic_root_lobbyÚ _telegram_topic_root_new_messager.  r   Ú_handle_reset_command©rU   r.   r;   rÚ   s   &&&&r(   Ú_hm_cmd_newÚGatewayInboundMixin._hm_cmd_newW  sn   é € Ü×"Ò" 4×#EÑ#EÀvÓN×NÖNØ˜×>Ñ>Ó@Ð@Ð@Ø×1Ñ1Ø�5œ!Ð8Ó9Ø×&Ñ&ó
÷ 
ð 	
ñ Oñ
ùs&   ‚%A7§A3¨	A7²<A7Á.A5Á/A7Á5A7c              ƒ  	ó:   "  € \         P                  R V4       R# 5i)z,Ignoring /start platform ping for session %s)Tr@   )rF   r‘   r4  s   &&&&r(   Ú_hm_cmd_startÚ!GatewayInboundMixin._hm_cmd_start_  s   é € Ü�‰ÐBÀJÔOØˆùs   ‚c              ƒ  	ó(   "  € ^ RI Hp RV! 4       3# 5i)ro  )Úformat_status_textT)Úhermes_cli.proxy_clir;  )rU   r.   r;   rÚ   r;  s   &&&& r(   Ú_hm_cmd_egressÚ"GatewayInboundMixin._hm_cmd_egressc  s   é € Ý;ØÑ'Ó)Ð)Ð)ùs   ‚c               ó$   € V ^8„  d   QhRRRRRR/# )r"   rå   r%   Úackr$   r†  r&   )r'   s   "r(   r)   r=   g  s"   € ÷ ñ ÀCð Ècð Ð]wñ r*   c              ƒ  óÒ   "  € V P                  W$V4      G Rj  x€L
   \        P                  ! V4      G Rj  x€L
 Vn        R#  L* L  \         d    R\        RTR7      3u # i ; i5i)z¤Ack, then rewrite the turn to ``build()`` and fall through to the agent (keeps role
alternation; works on any backend). A failing builder replies with a retry hint.NTz#gateway.prompt_command.start_failed©r  r�  )Ú_send_command_ackrJ   rK   rg   rf   r   )rU   r.   r;   rå   r@  Úbuilds   &&&&&&r(   Ú_hm_rewrite_turn_to_promptÚ.GatewayInboundMixin._hm_rewrite_turn_to_promptg  sk   é € ð ×$Ñ$ V°$Ó7×7Ð7ð	PÜ&×0Ò0°Ó7×7ˆEŒJð Ðñ 	8á7øÜô 	PØœÐ@È$ÔOÐOÒOð	PüsB   ‚A'˜A™A'žA ·A¸	A ÁA'ÁA ÁA$Á!A'Á#A$Á$A'c              ƒ  	óØ   aa"  € ^ RI Ho VP                  4       P                  4       oS'       d   \	        R4      M
\	        R4      pV P                  WRVVV3R l4      G Rj  x€L
 #  L5i)ro  )Úbuild_learn_promptzgateway.learn.ack_describedzgateway.learn.ack_conversationÚlearnc                 ó   <€ S ! S4      # r  r&   )rH  Úreqs   €€r(   Ú<lambda>Ú3GatewayInboundMixin._hm_cmd_learn.<locals>.<lambda>w  s   ø€ Ñ[mÐnqÔ[rr*   N)Úagent.learn_promptrH  Úget_command_argsre   r   rE  )rU   r.   r;   rÚ   Ú_ackrH  rK  s   &&&& @@r(   Ú_hm_cmd_learnÚ!GatewayInboundMixin._hm_cmd_learnr  sS   ùé € Ý9à×$Ñ$Ó&×,Ñ,Ó.ˆß36ŒqÐ.Ô/¼AÐ>^Ó<_ˆØ×4Ñ4°UÀGÈTÕSrÓs×sÐsÑsùs   „AA*Á#A(Á$A*c              ƒ  	ó  aa"  € ^ RI Ho VP                  4       P                  4       oS'       d.   \	        RSR,          \        S4      ^P8”  d   RMR,           R7      M
\	        R4      pV P                  WRVVV3R	 l4      G R
j  x€L
 #  L5i)ro  )Úbuild_plan_promptzgateway.plan.ack_task:NéP   Nrß   r@   )Útaskzgateway.plan.ack_conversationÚplanc                 ó   <€ S ! S4      # r  r&   )rT  rV  s   €€r(   rL  Ú2GatewayInboundMixin._hm_cmd_plan.<locals>.<lambda>  s   ø€ ÑZkÐlpÔZqr*   N)Úagent.plan_promptrT  rO  re   r   ræ   rE  )rU   r.   r;   rÚ   rP  rT  rV  s   &&&& @@r(   Ú_hm_cmd_planÚ GatewayInboundMixin._hm_cmd_plany  ss   ùé € Ý7à×%Ñ%Ó'×-Ñ-Ó/ˆçô Ð)°°Sµ	ÄcÈ$ÃiÐRTÄn¹UÐZ\Õ0]Õ^ÜÐ>Ó?ð 	à×4Ñ4°UÀFÈDÕRqÓr×rÐrÑrùs   „BBÂB
ÂBc              ƒ  	óT  "  € ^ RI Hp  T! VP                  4       P                  4       T;'       g    V P	                  V4      R7      pRT9   d   \        R4      M
\        R4      pT P                  Y&R4      G R	j  x€L
  YQn        R
#   \
         d    R\        R4      3u # i ; i L*5i)ro  )Úbuild_init_prompt_for_cwd)ÚextraÚsession_keyTzgateway.init.start_failedzUPDATE the existing AGENTS.mdzgateway.init.ack_updatezgateway.init.ack_generateÚinitNr�  )	Úhermes_cli.init_commandr^  rO  re   r®   rf   r   rC  rg   )rU   r.   r;   rÚ   r^  Ú_init_promptrP  s   &&&&   r(   Ú_hm_cmd_initÚ GatewayInboundMixin._hm_cmd_init�  s±   é € åEð		8ñ 5Ø×,Ñ,Ó.×4Ñ4Ó6Ø&×NÐN¨$×*FÑ*FÀvÓ*NôˆLð /°,Ô>ô Ð'Ô(äÐ.Ó/ð 	ð
 ×$Ñ$ V°6Ó:×:Ð:Ø!Œ
ØÐøô ô 	8ØœÐ6Ó7Ð7Ò7ð	8úñ 	;ùs4   ‚B(Š?B Á	2B(Á;B&Á<B(ÂB#Â B(Â"B#Â#B(c              ƒ  	óL  "  € V P                  V4      G R j  x€L
 p\        VRR4      ;'       g    Rp\        VRR 4      pV'       g   RT;'       g    R 3# V'       d   V P                  W%R4      G R j  x€L
   Wan        R#  Li L  \         d    RT;'       g    R 3u # i ; i5i)Nrg   r@   Ú
agent_seedTÚ	blueprintr�  )Ú_handle_blueprint_commandr2   rC  rg   rf   )rU   r.   r;   rÚ   Ú_blueprint_resultÚ_textÚ_blueprint_seeds   &&&&   r(   Ú_hm_cmd_blueprintÚ%GatewayInboundMixin._hm_cmd_blueprint˜  s­   é € Ø"&×"@Ñ"@ÀÓ"G×GÐÜÐ)¨6°2Ó6×<Ð<¸"ˆÜ!Ð"3°\À4ÓHˆßØ˜Ÿ˜ $Ð&Ð&÷ Ø×(Ñ(¨¸ÓD×DÐDð	'Ø(ŒJð Ðñ Hñ Eøô ô 	'Ø˜Ÿ˜ $Ð&Ò&ð	'üs\   ‚B$—B˜B$°!B$ÁB$ÁB$Á3BÁ4B$Á9B Á?B$ÂB$ÂB!ÂB!ÂB$Â B!Â!B$c           	   ƒ  	óª  "  € ^pVP                  4       P                  4       pV'       dP   \        \        \        4      ;_uu_ 4        \        ^\        VP                  4       ^ ,          4      4      pRRR4       V^8X  d   \        R4      M\        RVR7      pV P                  VRW`P                  4      G Rj  x€L
 #   + '       g   i     LT; i L5i)é   Nzgateway.confirm.detail_undo_onez gateway.confirm.detail_undo_many)ÚcountÚundo)rO  re   r   Ú
ValueErrorÚ
IndexErrorrN  ÚintÚsplitr   r.  Ú_handle_undo_command)rU   r.   r;   rÚ   Ú_undo_nÚ	_undo_rawÚ_undo_details   &&&&   r(   Ú_hm_cmd_undoÚ GatewayInboundMixin._hm_cmd_undo¨  s¦   é € ØˆØ×*Ñ*Ó,×2Ñ2Ó4ˆ	ßÜœ*¤j×1Õ1Ü˜a¤ Y§_¡_Ó%6°qÕ%9Ó!:Ó;�÷ 2ð ˜!Œ|ô Ð/Ô0äÐ5¸WÔEð 	ð
 ×1Ñ1°%¸À×OhÑOhÓi×iÐi÷ 2×1úñ jùs+   ‚ACÁ+B>Á2ACÂ9CÂ:CÂ>C	Ã		Cc              ƒ  	ó@   "  € V P                  V\        R 4      4      # 5i)zgateway.queue.usage©Ú_hm_send_payload_as_turnr   r4  s   &&&&r(   Ú_hm_cmd_queueÚ!GatewayInboundMixin._hm_cmd_queue·  s   é € Ø×,Ñ,¨U´AÐ6KÓ4LÓMÐMùó   ‚c              ƒ  	ó@   "  € V P                  V\        R 4      4      # 5i)zgateway.steer.usage_idler~  r4  s   &&&&r(   Ú_hm_cmd_steerÚ!GatewayInboundMixin._hm_cmd_steerº  s   é € Ø×,Ñ,¨U´AÐ6PÓ4QÓRÐRùr‚  c               ó    € V ^8„  d   QhRRRR/# )r"   Úusager%   r$   r†  r&   )r'   s   "r(   r)   r=   ¾  s   € ÷ ñ ¨sð Ð7Qñ r*   c                	óÎ   € V P                  4       P                  4       pV'       g   R V3# \        \        4      ;_uu_ 4        W n        RRR4       R#   + '       g   i     R# ; i)TNr�  )rO  re   r   rf   rg   )r.   r‡  Úpayloads   && r(   r  Ú,GatewayInboundMixin._hm_send_payload_as_turn½  sP   € à×(Ñ(Ó*×0Ñ0Ó2ˆßØ˜�;ÐÜ”i× Õ Ø ŒJ÷ !àÐ÷ !Ö àÐús   ÁAÁA$	c           
   ƒ  	ó  "  € ^ RI HpHp ^ RIHp VP                  4       P                  4       pV'       g
   RV! 4       3#  V! 4       pT! \        V\        4      '       d   VP                  R4      M/ 4      p	 Wqn        V P                  V4      p
V P                  V4       RRRV	R,          RR	R
RRR/V
P                  n        V P!                  V4       R#   \         d    T! / 4      p	 Lsi ; i  \         d    R\#        R4      3u # i ; i5i)ro  )Ú	moa_usageÚnormalize_moa_config©Úload_configTÚmoaÚproviderÚmodelÚdefault_presetÚbase_urlzmoa://localÚapi_keyzmoa-virtual-providerÚapi_modeÚchat_completionszgateway.moa.prepare_failedr�  )Úhermes_cli.moa_configrŒ  r�  Úhermes_cli.configr�  rO  re   r3   rK  r“   rf   rg   Ú_session_stateÚ_claim_one_turn_restoreÚconversationÚmodel_overrideÚ_evict_cached_agentr   )rU   r.   r;   rÚ   rŒ  r�  r�  Úmoa_payloadÚcfgÚmoa_cfgÚ
_moa_states   &&&&       r(   Ú_hm_cmd_moaÚGatewayInboundMixin._hm_cmd_moaÆ  s  é € ÷ 	JÝ1à×,Ñ,Ó.×4Ñ4Ó6ˆßØ™›Ð$Ð$ð	/Ù“-ˆCÙ*¼ZÈÌT×=RÒ=R¨3¯7©7°5¬>ÐXZÓ[ˆGð	9Ø$ŒJØ×,Ñ,¨ZÓ8ˆJà×(Ñ(¨Ô4à˜E 7¨GÐ4DÕ,EÀzÐS`ØÐ1°:Ð?Qð6ˆJ×#Ñ#Ô2ð ×$Ñ$ ZÔ0ð Ðøô ô 	/Ù*¨2Ó.ŠGð	/ûô ô 	9ØœÐ7Ó8Ð8Ò8ð	9üsH   ‚>DÁ6C Á8AC. ÃDÃC+Ã(DÃ*C+Ã+DÃ.D	ÄDÄD	Ä	Dc          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r"   r.   r	   r;   r   rÚ   r%   r  r¿   r$   r†  r&   )r'   s   "r(   r)   r=   é  s6   € ÷ ñ Ø!ðØ+8ðØFIðà ðð 
$ñr*   c              ƒ  óÒ  "  € V P                  4       P                  V4      ;'       g     V P                  4       P                  V4      pVeG   V P                  V4      ;_uu_4       GRj  x€L
  RV! V4      G Rj  x€L
 3uuRRR4      GRj  x€L
  # W@P                  9   d   \        V RV 24      ! WV4      G Rj  x€L
 # R#  LX LI L9  + GRj  x€L 
 '       g   i     LO; i L(5i)uª   Dispatch built-in idle-path commands â†’ ``(handled, result)``; prompt-rewriting commands
mutate ``event.text`` and return ``(False, None)`` to fall through to the agent.NTÚ_hm_cmd_r�  )Ú_gateway_plain_command_handlersr“   Ú_gateway_idle_command_handlersÚ_async_profile_scope_for_sourceÚ_HM_CANONICAL_COMMANDSr2   )rU   r.   r;   rÚ   r  Úplain_handlers   &&&&& r(   Ú_hm_dispatch_canonical_commandÚ2GatewayInboundMixin._hm_dispatch_canonical_commandé  sÍ   é € ð ×0Ñ0Ó2×6Ñ6°yÓA÷ Dð DØ×2Ñ2Ó4×8Ñ8¸ÓCð 	ð Ò$Ø×;Ñ;¸F×C×CÕCØ¡=°Ó#7×7Ð7÷ D×CÒCà×3Ñ3Ô3Ü  ¨°)°Ð'=Ô>¸uÈjÓY×YÐYØÐñ	 DÙ7÷ D×C×CÒCúñ Zùsl   ‚A(C'Á*CÁ+C'Á.C	Á;C
Á<C	Â C'ÂCÂ.C'Â<C%Â=C'ÃC	ÃC'Ã	C"	ÃCÃ
C"	ÃC"	Ã	C'c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r"   r.   r	   r;   r   rÚ   r%   r  r$   r�   r&   )r'   s   "r(   r)   r=   ú  s4   € ÷ ñ Ø!ðØ+8ðØFIðØTWðà	ñr*   c                ó´  €  ^ RI HpHp V! V4      pVf   R# T! YqP                  4       P	                  4       TVP
                  '       d   VP
                  P                  MRR7      pV'       g   R# Vw  Vn        ršV
'       d'   \        P                  RVRP                  V
4      4       R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)	zŸRewrite ``/<bundle>`` to the bundle invocation message; True when handled.
Skill bundles take precedence over individual skill commands (mirrors CLI dispatch).)Úbuild_bundle_invocation_messageÚresolve_bundle_command_keyNF)Útask_idrC   z$Bundle %s skipped missing skills: %sú, TzBundle dispatch failed: %s)Úagent.skill_bundlesr±  r²  rO  re   rC   rD   rg   rF   r‘   Újoinrf   rP   )rU   r.   r;   rÚ   r  r±  r²  Ú
bundle_keyÚbundle_resultÚ_loadedÚmissingrä  s   &&&&&       r(   Ú_hm_bundle_slash_rewriteÚ,GatewayInboundMixin._hm_bundle_slash_rewriteú  sµ   € ð
	÷ñ 4°GÓ<ˆJØÒ!Ùñ
 <Ø×2Ñ2Ó4×:Ñ:Ó<ÀjØ28·/·/°/˜Ÿ™×.Ò.ÀtôˆM÷ !ÙØ+8Ñ(ˆEŒJ˜ßÜ—‘ÐBÀJÐPT×PYÑPYÐZaÓPbÔcÙøÜô 	Ü�N‰NÐ7¸Ô=Ýûð	ús#   ‚B+ ˜AB+ Á18B+ Â+CÂ6CÃCc               ó$   € V ^8„  d   QhRRRRRR/# )r"   r  r%   r;   r   r$   r¿   r&   )r'   s   "r(   r)   r=     s!   € ÷ =ñ =¨ð =°mð =Èñ =r*   c                ó  € ^ RI Hp ^ RIHp V P	                  RR4      V9   d   R# V! V 4      pV'       d   V# \
        P                  RYP                  '       d   VP                  P                  MR4       \        RV R	7      # )
zNReply for a /command that is not built-in/plugin/skill; None when it is known.)Ú_check_unavailable_skill)ÚGATEWAY_KNOWN_COMMANDSrñ  Ú-NuO   Unrecognized slash command /%s from %s â€” replying with unknown-command noticeÚ?zgateway.unknown_commandrB  )
r‰   r¿  r­   rÀ  rÑ   rF   rP   rC   rD   r   )r  r;   r¿  rÀ  Ú_unavail_msgs   &&   r(   Ú_hm_unknown_slash_replyÚ+GatewayInboundMixin._hm_unknown_slash_reply  sl   € õ 	9Ý>à�?‰?˜3 Ó$Ð(>Ô>Ùá/°Ó8ˆßØÐô 	�‰Ø]Ø¯o¯o¨o�V—_‘_×*Ò*À3ô	
ô Ð*°GÔ<Ð<r*   c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# )
r"   r.   r	   r;   r   rÚ   r%   r  r¿   r$   r&   )r'   s   "r(   r)   r=   -  s4   € ÷ ;ñ ;Ø!ð;Ø+8ð;ØFIð;ØTað;à	ñ;r*   c                óR  € V'       d   V P                  WW44      '       d   R#  ^ RIHpHpHp V! 4       pV! V4      p	V	f   V P                  WB4      # VP                  '       d   VP                  P                  MRp
VP                  4       P                  4       p ^ RIH
pHp V! V4      w  rïW‰,          P                  RR4      pV
'       d¼   V'       g	   V'       d¬   ^ RIHp V! V
R7      pV'       d   VV9   d   \!        RVV
R	7      # V Uu. uFN  pVP                  V/ 4      P                  RR4      V9   g   K,  VP                  V/ 4      P                  RR4      NKP  	  ppV'       d   \!        R
RP#                  V4      V
R7      # V'       d4   Ve0   V! V	.VOWóR7      pV'       g   \!        RVR7      # Vw  Vn        ppR# V! W›VR7      pV'       d   VVn        R#   \         d
    Rp. Trþ ELDi ; iu upi   \         d"   p\&        P)                  RT4        Rp?R# Rp?ii ; i)a  Rewrite ``/<bundle>`` / ``/<skill>`` invocations into the skill prompt on ``event.text``;
returns a reply string when the command is disabled/unknown/failed, else None.
resolve_skill_command_key() handles the Telegram underscore/hyphen round-trip (/claude_code).N)Úget_skill_commandsÚbuild_skill_invocation_messageÚresolve_skill_command_key)Ú&build_stacked_skill_invocation_messageÚsplit_stacked_skill_commandsrå   r@   )Úget_disabled_skill_names)rC   z$gateway.skills.disabled_for_platform)rå   rC   zgateway.skills.stacked_disabledr´  )ÚnamesrC   )r³  z"gateway.skills.stacked_load_failedrB  z*Skill command check failed (non-fatal): %s)r»  Úagent.skill_commandsrÈ  rÉ  rÊ  rÄ  rC   rD   rO  re   rË  rÌ  rf   r“   Úagent.skill_utilsrÍ  r   r¶  rg   rF   r‹   )rU   r.   r;   rÚ   r  rÈ  rÉ  rÊ  Ú
skill_cmdsÚcmd_keyÚ_platÚuser_instructionÚ_build_stackedrÌ  Ú
extra_keysÚstacked_instructionÚ_skill_nameÚ_get_plat_disabledÚ_plat_disabledÚkÚ_disabled_extraÚstacked_resultr¹  Ú_missingÚmsgrÕ   s   &&&&&                     r(   Ú_hm_skill_slash_rewriteÚ+GatewayInboundMixin._hm_skill_slash_rewrite-  s  € ÷ ˜$×7Ñ7¸Àz×[Ò[Ùð2	J÷ñ ñ ,Ó-ˆJÙ/°Ó8ˆGØŠØ×3Ñ3°GÓDÐDØ-3¯_¯_¨_�F—O‘O×)Ò)À$ˆEØ$×5Ñ5Ó7×=Ñ=Ó?ÐðG÷ñ 3OÐO_Ó2`Ñ/�
ð %Õ-×1Ñ1°&¸"Ó=ˆKßŸ+¯õ ]Ù!3¸UÔ!C�ß ;°.Ô#@ÜÐCÈ+Ð`eÔfÐfñ (ó#á'˜Ø!—~‘~ a¨Ó,×0Ñ0°¸Ó<ÀÑNô :�J—N‘N 1 bÓ)×-Ñ-¨f°bÖ9Ù'ð  ð #÷
 #ÜÐ>ÀdÇiÁiÐP_ÓF`ÐkpÔqÐqß˜nÒ8Ù!/ØÐ*˜zÐ*Ð,?ô"�÷ &ÜÐAÈ7ÔSÐSØ0>Ñ-�”
˜G Xñ ñ 5°WÐXbÔc�ßØ!$�E”Jñ øôC ô GØ!%�Ø24Ð6FÓ/ðGüò#øô& ô 	JÜ�L‰LÐEÀq×IÐIÙûð	Jús‰   ¤-G: ÁG: Á$6G: ÂG Â-'G: ÃG: ÃG: Ã4G: Ä	G: Ä)G5Ä;&G5Å!&G: ÆG: Æ%G: Æ6G: ÇG: ÇG2Ç.G: Ç1G2Ç2G: Ç:H&ÈH!È!H&c               ó(   € V ^8„  d   QhRRRRRRRR/# rð   r&   )r'   s   "r(   r)   r=   j  s,   € ÷ ñ Ø!ðØ+8ðØFIðà	ñr*   c              ƒ  ó4  "  € ^ RI Hp VP                  '       d*   \        VRR4      '       g   VP	                  4       '       d   R# V P                  W4      pVf   V P                  WV4      G Rj  x€L
 pVf   V P                  W4      G Rj  x€L
 pV#  L# L5i)a  Replies owned by in-flight work: pending /update prompt, clarify, slash-confirm.
Only events that may control the gateway (``allow_gateway_control``) can answer them, never
an admitted turn: it was offered here before its commit, or a slash command queued it.r~   r‚   FN)r’   r   Úallow_gateway_controlr2   r“   rí   r  r3  )rU   r.   r;   rÚ   r   Ú_replys   &&&&  r(   Ú_hm_pending_reply_interceptsÚ0GatewayInboundMixin._hm_pending_reply_interceptsj  s‡   é € õ 	@Ø×*×*Ð*¬g°e¸\È5×.QÒ.QÐUh×UlÑUl×UnÒUnÙØ×-Ñ-¨eÓ@ˆØŠ>Ø×1Ñ1°%ÀÓL×LˆFØŠ>Ø×7Ñ7¸ÓJ×JˆFØˆñ MáJùs*   ‚ABÁ,BÁ0BÁ1BÂBÂBÂBc               ó(   € V ^8„  d   QhRRRRRRRR/# r…  r&   )r'   s   "r(   r)   r=   z  s,   € ÷ !ñ !Ø!ð!Ø+8ð!ØFIð!à	#ñ!r*   c              ƒ  óÌ  "  € V P                  V4      pV P                  WV4      G Rj  x€L
 w  rVrxV'       g   V P                  WW84      G Rj  x€L
 w  rVV'       g   V P                  WV4      G Rj  x€L
 w  rVpV'       g*   V P	                  V P
                  WW74      G Rj  x€L
 pVRJpV'       g%   V'       d   V P                  WW44      G Rj  x€L
 w  rVWV3#  L° L� Lk L= L5i)a  Idle path: resolve + dispatch slash commands; rewriting commands fall through to the agent.
A command rewritten into a turn keeps the /stop and /new epoch it arrived under, read before
the (slow, off-loop) rewrite, so a reset during it drops the command, as on the busy path.N)Ú_route_stop_epochr"  r­  Ú&_hm_dispatch_quick_and_plugin_commandsÚ_run_in_executor_with_contextrà  Ú_admit_command_turn)	rU   r.   r;   rÚ   Ú
stop_epochr  r  r  r  s	   &&&&     r(   Ú_hm_dispatch_idle_commandsÚ.GatewayInboundMixin._hm_dispatch_idle_commandsz  sÞ   é € ð ×+Ñ+¨JÓ7ˆ
Ø6:×6NÑ6NÈuÐ^hÓ6i×0iÑ-ˆ˜7ßØ&*×&IÑ&IÈ%ÐYcÓ&o× oÑˆHßØ/3×/ZÑ/ZÐ[`ÐjqÓ/r×)rÑ&ˆH˜wßð
 !×>Ñ>Ø×,Ñ,¨e¸ZóR÷ RˆGà dÐ*ˆHßŸGØ&*×&>Ñ&>¸uÈjÓ&e× eÑˆHØÐ Ð ñ 1já oá)rñRñ !fùso   ‚'C$©Cª$C$ÁCÁC$ÁC$Á2CÁ3C$Â C$Â"C Â#C$Â3C$Â;C$ÃC"Ã
C$ÃC$ÃC$Ã C$Ã"C$c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r"   r.   r	   r;   r   r�   r�   rÚ   r%   r$   z(tuple[MessageEvent, SessionSource, bool]r&   )r'   s   "r(   r)   r=   ’  s4   € ÷ .ñ .Ø!ð.Ø+8ð.ØGKð.ØY\ð.à	1ñ.r*   c           	     ó’  €  V P                  V4      pVe*   \        VRR4      '       g   VP                  4       '       d   WV3# V P                  WE4      pVf   WV3# V P	                  WAV4       \        VRR4      pVe   TMTpWb\        \        VRR4      4      3#   \         d     \        P                  RTRR7       YT3u # i ; i)a6  FIFO orphan rescue: a session that went idle with a populated overflow (post-turn drain
never promoted, e.g. a compression-demoted follow-up) silently orphaned those events. The
oldest orphan runs as THIS turn and the incoming event is parked behind the chain. Skipped
for control commands and internal events.Nr}   Fr;   z*FIFO orphan rescue pre-claim failed for %sTrA   )	rQ   r2   r¬   Ú_rescue_orphaned_overflowrÍ  r�   rf   rF   r‹   )rU   r.   r;   r�   rÚ   Ú_orphan_adapterÚ_rescuedÚ_rescued_sources   &&&&&   r(   Ú_hm_rescue_orphaned_fifoÚ,GatewayInboundMixin._hm_rescue_orphaned_fifo’  sÜ   € ð	.ð #×8Ñ8¸Ó@ˆOØÒ&¬'°%¸ÀU×*KÒ*KÈu×O`ÑO`×ObÒObØ kÐ1Ð1Ø×5Ñ5°jÓRˆHØÒØ kÐ1Ð1ð ×Ñ˜z°/ÔBô & h°¸$Ó?ˆOØ(7Ò(C‘_ÈˆFØ¤T¬'°(¸JÈÓ*NÓ%OÐOÐOøÜô 	.Ü�L‰LÐEÀzÐ\`ˆLÔaØ +Ð-Ò-ð	.ús#   ‚=B Á B ÁB Á>B Â'CÃCc          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r"   r.   r	   r;   r   rÚ   r%   r�   r�   r$   r†  r&   )r'   s   "r(   r)   r=   ³  s4   € ÷ %ñ %Ø!ð%Ø+8ð%ØFIð%ØX\ð%à	#ñ%r*   c              ƒ  óð  "  € ^ RI Hp V! V 4      pVEe   VP                  4       '       Eg   V'       gù   ^ RIHpHp VP                  4       '       gÛ   V P                  V4      '       dU   \        VRR4      '       gB   V P                  W4      G Rj  x€L
 '       g!   V P                  WV4      G Rj  x€L
 '       d   R
# V P                  WV4      G Rj  x€L
 w  ršV	'       d   RV
3# \        VRR4      '       d#   VP                  V P                  V4      8w  d   R
# RV! Wa4      G Rj  x€L
 3# Vf<   V'       g4   VP                  4       '       g   \        V RR4      e   ^ RIHp V! R	4      hR#  LÜ L¾ Lž LL5i)a  ``(True, reply)`` when the routed profile's session authority owned this message
(preempted, plugin-consumed or admitted to its durable FIFO); ``(False, None)`` to continue
on the in-process path. Raises ``RuntimeStoreError('profile_mismatch')`` for a scope this
process does not serve.r�  N)Úadmit_messager   r‚   FTÚsession_authority)r¡  Úprofile_mismatchrŒ  r�  )r­  rž  r¬   r’   rû  r   r“   r²   r2   Ú$_route_plaintext_approval_while_busyr   Ú_hm_post_admission_consumeÚ_stop_epochrê  r²  r¡  )rU   r.   r;   rÚ   r�   rž  r¼  rû  r   Ú	_consumedÚ_consumer_replyr¡  s   &&&&&       r(   Ú_hm_authority_admissionÚ+GatewayInboundMixin._hm_authority_admission³  sH  é € õ 	AÙ$ TÓ*ˆ	ØÓ ¨×):Ñ):×)<Ó)<Ç[ßRØ&×*Ñ*×,Ò,ð ×+Ñ+¨J×7Ò7ÄÈÈ|Ð]b×@cÒ@cØ"×GÑGÈÓZ×ZÖZØ!%×!6Ñ!6°uÀjÓ!Q×QÖQØ%Ð%Ø37×3RÑ3RÐSXÐblÓ3m×-mÑ*�	ßØ Ð0Ð0Ü˜5 ,°×6Ò6¸5×;LÑ;LÐPT×PfÑPfÐgqÓPrÔ;rØ%Ð%ð ¡=°Ó#B×BÐBÐBØÒ§k¸%×:KÑ:K×:MÒ:MÜ˜DÐ"5°tÓ<ÒHå>Ù#Ð$6Ó7Ð7ØÐñ! [ÙQá-mñ Cùsv   ‚*E6­E6µE6ÁE6Á*'E6ÂE.Â	E6ÂE6Â1E0Â2	E6Â<E6ÃE2ÃAE6Ä'E4Ä(E6Ä9E6Å E6Å0E6Å2E6Å4E6c               ó    € V ^8„  d   QhRRRR/# )r"   r.   r	   r$   r¿   r&   )r'   s   "r(   r)   r=   Ú  s"   € ÷ zBñ zB¨<ð zB¸Mñ zBr*   c              ƒ  ó¢
  "  € ^ RI Hp V P                  V4      G Rj  x€L
 pVf   R# Vw  rpV'       g   ^ RIHp V! V4       V P                  WV4      pVe   V# V P                  V4      pV'       d   RMV P                  WV4      G Rj  x€L
 p	V	e   V	# V P                  WW…4      G Rj  x€L
 w  r«V
'       d   V# V P                  V4       V P                  V4      '       d   V P                  V4       V P                  V4      '       d   V P                  WV4      G Rj  x€L
 # V P                  WV4      G Rj  x€L
 w  rÍV'       d   V# V'       gŒ   \        P                  ! V P                   V4      G Rj  x€L
 '       d*   V P#                  V4      '       d   V P%                  4       # R# V P&                  '       d"   \(        P+                  RV4       \-        R4      # V P/                  W„4      w  rïVe   \(        P+                  RV4       V# V P1                  WWX4      w  rpV P3                  V4      pVe   VVP4                  n        TVP4                  n        VVP4                  n        \<        P<                  ! 4       VP4                  n        ^ RI H!p V! WER7       V PE                  4        V PG                  V4      p V'       g‹   V PI                  WV4      G Rj  x€L
 w  ppV'       df   TV PK                  VV4       \M        VR	R
4      '       g   V PO                  V4      G Rj  x€L
  V PQ                  VVR7       V PS                  VV4       #  V PU                  WVV4      G Rj  x€L
 p T P]                  TYETR7      G Rj  x€L
  TT PK                  TT4       \M        TR	R
4      '       g   T PO                  T4      G Rj  x€L
  T PQ                  TTR7       T PS                  TT4       #  ELÓ ELh ELK ELØ ELÁ EL‡ EL% LÝ L�  \V         d›   p\(        PY                  RTTPZ                  4       \-        R4      u Rp?T PK                  TT4       \M        TR	R
4      '       g   T PO                  T4      G Rj  x€L 
  T PQ                  TTR7       T PS                  TT4       # Rp?ii ; i EL+  \^         d"   p\(        Pa                  RT4        Rp?ELPRp?ii ; i EL  T PK                  TT4       \M        TR	R
4      '       g   T PO                  T4      G Rj  x€L 
  T PQ                  TTR7       T PS                  TT4       i ; i5i)u¬   Handle an incoming message from any platform: auth â†’ command check â†’ running-agent
interrupt â†’ get/create session â†’ build context â†’ run agent â†’ return response.rö  N)Úrecord_gateway_slash_commandu;   Refusing new turn for session %s â€” external drain active.z!gateway.busy.draining_maintenancez@Rejecting new active session %s: max_concurrent_sessions reached)Ústart_reply_clock)r}   Ú_turn_marker_handoffFru  z‚Rejecting turn for routing key %s on session %s after turn-lease timeout; transcript load was not started and the user must resendz!gateway.busy.another_turn_running)Úagent_resultr;   r�   r.   zpost-turn hook failed: %s)1r‰   r8  r¢   Ú.hermes_cli.observability.shared_metrics_eventsr  rÇ   r®   ræ  r  r^  r²   rj  r  rï  rJ   rK   r1  Ú$_should_send_telegram_lobby_reminderÚ"_telegram_topic_root_lobby_messageÚ_external_drain_activerF   r‘   r   Ú_claim_active_session_slotr÷  rš  rD  ÚleaserF  r.   rG  rE  Ú/hermes_cli.observability.shared_metrics_gatewayr  Ú_persist_active_agentsÚ_begin_session_run_generationrÿ  Ú(_restore_pending_one_turn_model_overrider2   Ú_clear_durable_active_turnr  Ú_release_turn_leaseÚ_handle_message_with_agentr   rG   r£  Ú_run_post_turn_hooksrf   r‹   )rU   r.   r8  Ú	_admittedr;   r�   r  rÆ   rÚ   rå  Ú_ownedÚ_authority_replyr  r  Ú_active_session_leaseÚ_limit_messageÚ_claim_stater  Ú_run_generationr  r  Ú_agent_resulträ  Ú	_goal_excs   &&                      r(   Ú_handle_messageÚ#GatewayInboundMixin._handle_messageÚ  sù  é € õ 	8Ø×.Ñ.¨uÓ5×5ˆ	ØÒÙØ%.Ñ"ˆ�{ßÝcÙ(¨Ô/ð ×,Ñ,¨U¸KÓHˆØÒ%Ø!Ð!à×1Ñ1°&Ó9ˆ
ß$‘°×0QÑ0QÐRWÐakÓ0l×*lˆØÒØˆMà)-×)EÑ)EÀeÐU_Ó)m×#mÑ ˆßØ#Ð#ð 	×'Ñ'¨
Ô3Ø×#Ñ# J×/Ò/Ø×'Ñ'¨
Ô3Ø×#Ñ# J×/Ò/Ø×@Ñ@ÀÐPZÓ[×[Ð[à"&×"AÑ"AÀ%ÐQ[Ó"\×\ÑˆßØˆN÷ Ü×&Ò& t×'IÑ'IÈ6ÓR×RÖRà×<Ñ<¸V×DÒDØ×BÑBÓDÐDÙð ×*×*Ð*Ü—‘ÐYÐ[eÔfÜÐ<Ó=Ð=ð
 15×0OÑ0OÐPZÓ0cÑ-ÐØÒ%Ü�K‰KÐZÐ\fÔgØ!Ð!à%)×%BÑ%BÀ5ÐR]Ó%jÑ"ˆ�{à×*Ñ*¨:Ó6ˆØ Ò,Ø&;ˆL×ÑÔ#Ø"9ˆ×ÑÔØ"'ˆ×ÑÔÜ'+§y¢y£{ˆ×ÑÔ$ÝUÙ˜&Õ7Ø×#Ñ#Ô%Ø×<Ñ<¸ZÓHˆð*	BçØ37×3RÑ3RÐSXÐblÓ3m×-mÑ*�	˜?ßØ*ð. ×9Ñ9¸*ÀoÔVô
 ˜5Ð"8¸%×@Ò@Ø×5Ñ5°eÓ<×<Ð<ð
 ×-Ñ-¨jÈÐ-ÔYð ×$Ñ$ Z°ÕAðI>Ø&*×&EÑ&EÀeÐU_ÐapÓ&q× q�ðEØ×/Ñ/Ø!.°vÐ^cð 0ó ÷ ð ð
 !ð ×9Ñ9¸*ÀoÔVô
 ˜5Ð"8¸%×@Ò@Ø×5Ñ5°eÓ<×<Ð<ð
 ×-Ñ-¨jÈÐ-ÔYð ×$Ñ$ Z°ÕAòm 6ò* +mò $nò \â\ò SòH .nñ> =ñ7 !røÜ(ô 	>ô —‘ð+ð  §¡ô	ô Ð<Ó=Ô=ð ×9Ñ9¸*ÀoÔVô
 ˜5Ð"8¸%×@Ò@Ø×5Ñ5°eÓ<×<Ñ<ð
 ×-Ñ-¨jÈÐ-ÔYð ×$Ñ$ Z°ÕAûðE	>úòøô ô EÜ—‘Ð8¸)×DÒDûðEúò =øð ×9Ñ9¸*ÀoÔVô
 ˜5Ð"8¸%×@Ò@Ø×5Ñ5°eÓ<×<Ñ<ð
 ×-Ñ-¨jÈÐ-ÔYð ×$Ñ$ Z°ÕAüs…  ‚U�O0žAUÁ4UÂO3ÂUÂ+O6Â,7UÃ$'UÄUÄ!O9Ä"UÄ;O<Ä<UÅ$UÅ8O?Å9	UÆUÆ#UÆ>DUË S& ËPËS& Ë-S& Ë.9UÌ'PÌ(*UÍP	 Í)PÍ*P	 Í/R4 ÎR1ÎR4 ÎS& Î9UÏS#Ï+UÏ3UÏ6UÏ9UÏ<UÏ?UÐS& ÐUÐP	 Ð	R.Ð+R)Ð?R.Ñ S& Ñ9UÑ=R Ñ>+UÒ)R.Ò.S& Ò1R4 Ò4S Ò?SÓS& ÓS Ó S& Ó#UÓ&:UÔ T#Ô!+UÕUNc               ó$   € V ^8„  d   QhRRRRRR/# )r"   r`  r%   rv  z
int | Noner$   r<   r&   )r'   s   "r(   r)   r=   V  s(   € ÷ Uñ UÀCð UÐYcð UÐosñ Ur*   c                ó~  € V'       g   R#  V P                  V4      pVe   VP                  P                  '       g   R# Ve   V P                  W4      '       g   R# VP                  P                  pRVP                  n        V P	                  W4       R#   \
         d    \        P                  RRR7        R# i ; i)aœ  Restore the per-session model override captured by ``/model --once`` or ``/moa``.

With ``run_generation`` (the turn finalizer) the restore happens only while that generation
is still current; a stop/reset/eviction has already settled the snapshot itself (see
``_invalidate_session_run_generation``), so the displaced finalizer finds nothing to do.
Without it (the settlement paths) the restore is unconditional.Nz)Failed to restore one-turn model overrideTrA   )r¯   rœ  Úone_turn_restoreÚ_is_session_run_currentÚ_restore_session_model_overriderf   rF   r‹   )rU   r`  rv  Ú
_otr_stateÚsnapshots   &&&  r(   r  Ú<GatewayInboundMixin._restore_pending_one_turn_model_overrideV  s¢   € ÷ Ùð
	UØ×1Ñ1°+Ó>ˆJØÒ!¨×)@Ñ)@×)Q×)QÐ)QÙØÒ)°$×2NÑ2NÈ{×2kÒ2kÙØ!×.Ñ.×?Ñ?ˆHØ7;ˆJ×#Ñ#Ô4Ø×0Ñ0°ÖGøÜô 	UÜ�L‰LÐDÈtˆL×Tð	Uús   Œ0B ¿B Á8B Â"B<Â;B<c               ó(   € V ^8„  d   QhRRRRRRRR/# ©r"   r.   r	   r;   r   r/   r%   r$   r&   )r'   s   "r(   r)   r=   k  s*   € ÷ ñ °Lð È-ð Ðgjð Ðorñ r*   c           	     ó²  € \        V\        V P                  RR4      \        V P                  RR4      R7      pV'       ds   VP                  '       da   \	        VP                  4      pVP
                  \        P                  8X  d%   VP                  '       d   V RVP                   R2pRV R	V 2p\        VR
R4      '       d   VP                   RV 2pV# )z`Attribute the sender in shared multi-user sessions and prepend history-backfill channel context.Úgroup_sessions_per_userTÚthread_sessions_per_userF)r/  r0  z | Slack user <@Ú>Ú[z] Úchannel_contextNz

[New message]
)
r   r2   r`   rM   r   rC   r   r�   rI   r3  )rU   r.   r;   r/   Ú_is_shared_multi_userÚ_safe_user_names   &&&&  r(   Ú_prefix_inbound_sender_contextÚ2GatewayInboundMixin._prefix_inbound_sender_contextk  sÊ   € ä <Ø¬G°D·K±KÐAZÐ\`Ó,aÜ%,¨T¯[©[Ð:TÐV[Ó%\ô!
Ð÷ ! V×%5×%5Ð%5ô ?¸v×?OÑ?OÓPˆOð �‰¤(§.¡.Ô0°V·^·^°^Ø%4Ð$5Ð5EÀfÇnÁnÐEUÐUVÐ"W�Ø˜Ð/¨r°,°Ð@ˆLä�5Ð+¨T×2Ò2Ø#×3Ñ3Ð4Ð4GÈÀ~ÐVˆLØÐr*   c               ó$   € V ^8„  d   QhRRRRRR/# )r"   r.   r	   Úpending_stt_preparedr�   r$   ztuple[list, list, list, list]r&   )r'   s   "r(   r)   r=   �  s)   € ÷ Gñ GØðGØ37ðGà	&ñGr*   c                ó´  € ^ RI HpHpHp . . . . 3w  rVrx\	        V P
                  ;'       g    . 4       EF  w  ršV	\        V P                  4      8  d   V P                  V	,          MRpV! W	4      '       d   VP                  V
4       V! W	4      '       di   V P                  \        P                  \        P                  09   d   VP                  V
4       M'V'       g    V! W	4      '       d   VP                  V
4       VP                  R4      '       g-   V'       d   Kë  V P                  \        P                  8X  g   EK  VP                  V
4       EK!  	  WVWx3# )a  Split ``event.media_urls`` into (image, STT-voice, audio-file, video) paths. Per-attachment
MIME wins over the message-level type (a document sent alongside an image must not be routed
as an image). MessageType.AUDIO / mixed DOCUMENT audio is a file attachment, never STT.)Ú_event_media_is_audioÚ_event_media_is_imageÚ_event_media_is_stt_inputr@   zvideo/)r‰   r;  r<  r=  Ú	enumeraterÖ  ræ   r×  Úappendr“  r
   ÚAUDIOÚDOCUMENTr  ÚVIDEO)r.   r9  r;  r<  r=  Úimage_pathsÚaudio_pathsÚaudio_file_pathsÚvideo_pathsÚiÚpathÚmtypes   &&          r(   Ú_classify_inbound_mediaÚ+GatewayInboundMixin._classify_inbound_media€  s  € ÷ 	hÑgØBDÀbÈ"ÈbÀ.Ñ?ˆÐ"2Ü  ×!1Ñ!1×!7Ð!7°R×8‰GˆAØ,-´°E×4EÑ4EÓ0FÔ,F�E×%Ñ% aÖ(ÈBˆEÙ$ U×.Ò.Ø×"Ñ" 4Ô(Ù$ U×.Ò.Ø×%Ñ%¬+×*;Ñ*;¼[×=QÑ=QÐ)RÔRØ$×+Ñ+¨DÕ1ß-Ñ2KÈE×2UÒ2UØ×&Ñ& tÔ,Ø×Ñ ×)Ò)·%±%¸E×<NÑ<NÔR]×RcÑRc×<cØ×"Ñ" 4×(ñ 9ð Ð)9ÐFÐFr*   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r"   r;   r   r`  r%   r/   rC  ú	list[str]r$   r&   )r'   s   "r(   r)   r=   –  s;   € ÷ "Uñ "UØ#ð"UØ25ð"UØEHð"UØW`ð"Uà	ñ"Ur*   c              ƒ  ó†  "  € \         P                  ! V P                  WR7      G Rj  x€L
 pVR8X  dK   \        V4      V P	                  V4      P
                  n        \        P                  R\        V4      4       V# \        P                  RV\        V4      4       Rp V P                  WR7      w  rx/ T;'       g    / CRV/Cp^ R
IHp	 V	! V4      ;_uu_ 4        V P                  W44      G Rj  x€L
 uuRRR4       #  LØ  \         d    \        P                  RRR	7        L`i ; i L8  + '       g   i     R# ; i5i)zXRoute images natively (attach pixels at run_conversation) or pre-analyze them into text.)r;   r`  NÚ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 failedTrA   )Úscoped_runtime_main)rJ   rK   Ú_decide_image_input_modeÚlistrš  r°   Únative_image_pathsrF   r‘   ræ   Ú_resolve_session_agent_runtimerf   r‹   Úagent.auxiliary_clientrP  Ú_enrich_message_with_vision)
rU   r;   r`  r/   rC  Ú	_img_modeÚvision_runtimeÚ
turn_modelÚruntime_kwargsrP  s
   &&&&&     r(   Ú_enrich_inbound_imagesÚ*GatewayInboundMixin._enrich_inbound_images–  s1  é € ô "×+Ò+Ø×)Ñ)°&ô
÷ 
ˆ	ð ˜Ô ÜMQÐR]ÓM^ˆD×Ñ Ó,×7Ñ7ÔJÜ�K‰KØeÜ�KÓ ôð  ÐÜ�‰ØZØ”s˜;Ó'ô	
ð ˆð	`Ø)-×)LÑ)LØð *Mó *Ñ&ˆJð M ×!5Ð!5°2ÐL¸ÀÑLˆNõ 	?á  ×0Õ0Ø×9Ñ9¸,ÓT×T÷ 1Ò0ñ7
øô, ô 	`Ü�L‰LÐOÐZ^ˆLÖ_ð	`úñ U÷ 1×0Ð0üs^   ‚&E¨D©A7EÂ!&D ÃEÃD-Ã2D+Ã3D-Ã6EÄ"D(Ä%EÄ'D(Ä(EÄ+D-Ä-D>	Ä8	EÚmetadatarì  Ú
Transcriptc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r"   r;   r   ÚtranscriptsrM  rì  r%   r$   r<   r&   )r'   s   "r(   r)   r=   º  s2   € ÷ Vñ VØ,ðVØ;DðVØehðVà	ñVr*   c          	   ƒ  óæ   "  € V F5  p VP                  VP                  \        RVR7      VR7      G Rj  x€L
  K7  	  R#  L
  \         d"   p\        P                  RYW4        Rp?Kd  Rp?ii ; i5i)u`   Send each transcript back as ``ðŸŽ™ï¸� "â€¦"`` (best-effort; failures are logged, never raised).z#gateway.voice.transcript_echo_short)rg   ©r]  Nz%s echo failed (non-fatal): %s)rR   rS   r   rf   rF   r‹   )rU   rY   r;   r`  r]  rì  ÚtxÚecho_excs   &&&&$$  r(   Ú_echo_stt_transcriptsÚ)GatewayInboundMixin._echo_stt_transcriptsº  sc   é € ó ˆBðVØ—l‘l 6§>¡>´1Ð5ZÐacÔ3dÐow�lÓx×xÒxó áxøÜô VÜ—‘Ð=¸{×UÒUûðVüs=   ‚A1‰,AµA ¶AºA1Á AÁA.ÁA)Á#A1Á)A.Á.A1c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# )
r"   r.   r	   r;   r   r/   r%   rD  rM  r$   r&   )r'   s   "r(   r)   r=   Ä  s4   € ÷ ñ Ø!ðØ+8ðØHKðØZcðà	ñr*   c              ƒ  	ó0  "  € V P                  W44      G R j  x€L
 w  r5V'       dk   V P                  4       '       dU   V P                  V4      pV'       d<   V P                  W P	                  V4      4      pV P                  WbWWR7      G R j  x€L
  V#  Lz L5i)Nrb  )Ú"_enrich_message_with_transcriptionÚ_should_echo_stt_transcriptsrQ   Ú_thread_metadata_for_sourceÚ_reply_anchor_for_eventre  )rU   r.   r;   r/   rD  Ú_successful_transcriptsÚ_echo_adapterÚ
_echo_metas   &&&&&   r(   Ú_enrich_inbound_voiceÚ)GatewayInboundMixin._enrich_inbound_voiceÄ  s�   é € ð 7;×6]Ñ6]Øó7
÷ 1
Ñ-ˆ÷ # t×'HÑ'H×'JÒ'JØ ×6Ñ6°vÓ>ˆMßØ!×=Ñ=¸f×FbÑFbÐchÓFiÓj�
Ø×0Ñ0°ÐH_Ð0Óu×uÐuØÐñ1
ñ vùs,   ‚B—B˜#B¼BÁ6BÂBÂBÂBc               ó    € V ^8„  d   QhRRRR/# )r"   rH  r%   r$   ztuple[str, str]r&   )r'   s   "r(   r)   r=   Õ  s   € ÷ wñ w¨sð w°ñ wr*   c                óâ   € ^ RI Hp \        P                  P	                  V 4      pVP                  R^4      p\        P                  ! RR\        V4      ^8¼  d
   V^,          MT4      V! V 4      3# )zœ``(display_name, agent_visible_path)``: cache filename is ``<id>_<id>_<original>``; the
path is translated to the in-container mount under a Docker backend.)Úto_agent_visible_cache_pathrñ  z	[^\w.\- ])	Útools.credential_filesrt  rÉ  rH  Úbasenamerv  ÚreÚsubræ   )rH  rt  rv  Úpartss   &   r(   Ú _inbound_attachment_display_nameÚ4GatewayInboundMixin._inbound_attachment_display_nameÔ  s[   € õ 	GÜ—7‘7×#Ñ# DÓ)ˆØ—‘˜s AÓ&ˆÜ�vŠv�l C´S¸³ZÀ1´_¨¨q®È(ÓSÑUpÐquÓUvÐvÐvr*   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r"   r/   r%   rE  rM  rF  r$   r&   )r'   s   "r(   r)   r=   Þ  s+   € ÷ ñ ¸Sð ÐT]ð Ðluð Ðz}ñ r*   c                óž   € RRRRV3RRRRV33 F:  w  rErgpV F-  p	V P                  V	4      w  r«R	V R
V
 RV RV RV RV RV 2pK/  	  K<  	  V# )zXPrepend a path-pointing note per audio-file / video attachment (content is not inlined).zan audio file attachmentÚaudioztranscribe or processza transcription or media toolza video attachmentÚvideozinspect or processza video analysis or media toolz[The user sent z: 'z'. It is saved at: zK. Its content is not inlined here. If the user's request involves what the z contains, u4    it yourself â€” for example by passing the path to ut    â€” instead of asking the user to describe it. Only ask what to do with it if their intent is genuinely unclear.]

)rz  )Úclsr/   rE  rF  ÚkindÚnounÚverbÚtoolÚpathsÚ_pathÚ_displayÚ_agent_paths   &&&&        r(   Ú!_prepend_inbound_media_file_notesÚ5GatewayInboundMixin._prepend_inbound_media_file_notesÝ  s§   € ð (¨Ð2IÐKjÐl|Ð}Ø! 7Ð,@ÐBbÐdoÐpó.
Ñ)ˆD˜ Eó �Ø(+×(LÑ(LÈUÓ(SÑ%�à% d V¨3¨x¨jð 9'Ø'2 mð 4 à $˜v [°°ð 76Ø6:°Vð <ð (˜.ð*ò ó ñ	.
ð  Ðr*   c               ó$   € V ^8„  d   QhRRRRRR/# )r"   r.   r	   r/   r%   r$   r&   )r'   s   "r(   r)   r=   ó  s#   € ÷ ñ °Lð ÐPSð ÐX[ñ r*   c                ó  aa€ ^ RI HpHpHpHp SP
                  '       g   V# ^ RIp0 Rmp\        SRR4      ;'       g    . p	\        SP
                  4       EF)  w  op
\        ;QJ d"    VV3R lWTV3 4       F  '       g   K   RM	  RM! VV3R lWTV3 4       4      '       d   KO  S\        SP                  4      8  d   SP                  S,          MRpVR9   dd   \        P                  P                  V
4      ^,          P                  4       V9   pV'       d   R	M!VP!                  V
4      ^ ,          ;'       g    RpV P#                  V
4      w  rÞS\        V	4      8  d
   V	S,          MRpV! WÞW¿RJR
7      pV RV 2pEK,  	  V# )z[Prepend a context note per non-media attachment (anything not routed as image/audio/video).)Ú_build_document_context_noter;  r<  Ú_event_media_is_videoNÚmedia_text_inlinedc              3  ó4   <"  € T F  q! SS4      x € K  	  R # 5ir  r&   )r¥  Úfr.   rG  s   & €€r(   r§  ÚFGatewayInboundMixin._prepend_inbound_document_notes.<locals>.<genexpr>  s   øé € ÐnÑ(m 1�1�U˜A—;�;Ó(mùs   ƒTFr@   úapplication/octet-streamz
text/plain)Úcontent_inlinedr1   >   ú.mdú.cfgú.csvú.iniú.logú.txtú.xmlú.ymlú.jsonú.tomlú.yaml>   r@   r“  )r‰   r�  r;  r<  rŽ  rÖ  Ú	mimetypesr2   r>  r¶  ræ   r×  rÉ  rH  Úsplitextr*  Ú
guess_typerz  )r€  r.   r/   r�  r;  r<  rŽ  Ú
_mimetypesÚ_TEXT_EXTENSIONSÚinline_flagsrH  rI  Ú_is_textÚdisplay_nameÚ
agent_pathÚinline_flagÚcontext_noterG  s   &f&              @r(   Ú_prepend_inbound_document_notesÚ3GatewayInboundMixin._prepend_inbound_document_notesò  sa  ù€ ÷	
ó 	
ð ××ÐØÐÛ&âuÐÜ˜uÐ&:¸DÓA×GÐGÀRˆÜ  ×!1Ñ!1×2‰GˆAˆt÷ ‹sÕnÐ)>ÐWlÑ(mÓn�s�sŠsÕnÐ)>ÐWlÑ(mÓn×nÒnÙØ,-´°E×4EÑ4EÓ0FÔ,F�E×%Ñ% aÖ(ÈBˆEØÐ8Ô8ÜŸ7™7×+Ñ+¨DÓ1°!Õ4×:Ñ:Ó<Ð@PÑP�ß(0™°z×7LÑ7LÈTÓ7RÐSTÕ7U×7sÐ7sÐYs�ð (+×'KÑ'KÈDÓ'QÑ$ˆLØ-.´°\Ó1BÔ-B˜, qž/ÈˆKÙ7Ø¨%ÐTYÐAYôˆLð +˜^¨4°¨~Ð>‹Lñ! 3ð" Ðr*   c               ó(   € V ^8„  d   QhRRRRRRRR/# r-  r&   )r'   s   "r(   r)   r=     s*   € ÷ ñ ¨lð ÀMð Ðadð Ðilñ r*   c                ót  € \        V RR4      '       dA   V P                  '       d/   V P                  p\        V RR4      '       d   RMRpRV RV R	V 2pVea   \        VR
R4      \        P                  8X  dA   \        V RR4      '       d.   ^ RIHp V! 4       '       d   \        V P                  4       RV 2pV# )zSPrepend the reply-to pointer, then the Discord triggering-message note (outermost).Úreply_to_textNÚreply_to_is_own_messageFz your previous messager@   z[Replying toz: "z"]

rC   r#   )Ú_discord_tools_loadedr1   )	r2   Úreply_to_message_idr¯  r   ÚDISCORDÚgateway.sessionr±  r,   r#   )r.   r;   r/   Ú
reply_textÚ_whoÚ_disc_tools_loadeds   &&&   r(   Ú_prepend_inbound_reply_contextÚ2GatewayInboundMixin._prepend_inbound_reply_context  sº   € ô �5˜/¨4×0Ò0°U×5N×5NÐ5Nð
 ×,Ñ,ˆJÜ/6°uÐ>WÐY^×/_Ò/_Ñ+ÐegˆDØ)¨$¨¨s°:°,¸fÀ\ÀNÐSˆLð ÒÜ˜ 
¨DÓ1´X×5EÑ5EÔEÜ˜˜|¨T×2Ò2åSÙ!×#Ò#Ü"9¸%×:JÑ:JÓ"KÐ!LÈDÐQ]ÐP^Ð_�ØÐr*   c               ó$   € V ^8„  d   QhRRRRRR/# )r"   r;   r   r`  r%   r$   ru  r&   )r'   s   "r(   r)   r=   ,  s#   € ÷ 9
ñ 9
¸-ð 9
ÐVYð 9
Ð^añ 9
r*   c           
   ƒ  óÄ  "  € ^ RI Hp ^ RIHp RpRp/ p. p\	        \
        4      ;_uu_ 4        V! 4       pVP                  R/ 4      p\        V\        4      '       d!   VP                  R4      p	V	e   \        V	4      p ^ RI
Hp
 V
! V4      pRRR4       V P                  WVR7      w  r¼VP                  R	4      ;'       g    R
p\        V\        4      '       d,   VP                  R4      ;'       g    VP                  R4      pMTpW¾8w  d   RpVeR    ^ RIHp V! RRVP                  R	4      VVP                  R4      VP                  R4      4      G Rj  x€L
 '       d   RpV'       dC   V'       d;   \	        \
        4      ;_uu_ 4        ^ RI
Hp V! W½VR7      ;'       g    TpRRR4       T! Y½VP                  R4      ;'       g    R
Y\P                  R4      ;'       g    R
VR7      G Rj  x€L
 #   \
         d     TP                  R4      ;'       g    . p EL‘i ; i  + '       g   i     ELž; i LÝ  \
         d    Rp Lâi ; i  + '       g   i     L¬; i Lm5i)z³Context length of the model this turn runs on. A global ``model.context_length`` pin
belongs to the configured model, not a /model or channel override; custom-provider limits win.)Ú_load_gateway_config)Úget_model_context_length_asyncNr’  Úcontext_length)Úget_compatible_custom_providersÚcustom_providers©r;   r`  Úuser_configr”  r@   Údefault)Úshould_clear_context_pin_asyncr‘  )Ú"get_custom_provider_context_length)r’  r”  rÀ  r•  )r”  r•  Úconfig_context_lengthr‘  rÀ  )r‰   r¼  Úagent.model_metadatar½  r   rf   r“   r3   rK  ru  r™  r¿  rT  Úhermes_cli.route_identityrÄ  rÅ  )rU   r;   r`  r¼  r½  Ú_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Å  s   &&&              r(   Ú_inbound_model_context_lengthÚ1GatewayInboundMixin._inbound_model_context_length,  sB  é € õ 	5ÝGàˆØˆØˆØ "ÐÜ”i× Õ Ù+Ó-ˆHØ%Ÿ\™\¨'°2Ó6ˆNÜ˜.¬$×/Ò/Ø-×1Ñ1Ð2BÓC�ØÒ+Ü&)¨,Ó&7�OðOÝMá(GÈÓ(QÐ%÷ !ð $(×#FÑ#FØÀð $Gó $
Ñ ˆ
ð %×(Ñ(¨Ó4×:Ð:¸ˆÜ�n¤d×+Ò+Ø$2×$6Ñ$6°yÓ$A×$`Ð$`À^×EWÑEWÐX_ÓE`Ñ!à$2Ð!ØÔ.Ø"ˆOØÒ&ð
'ÝTá7Ø˜$Ø"×&Ñ& zÓ2°MØ"×&Ñ& zÓ2°L×4DÑ4DÀZÓ4Pó÷ ö ð
 '+�O÷ !§]Üœ)×$Õ$ÝPá"DØ$ÐOdô#÷ #%ð #%à$ð  ÷ %ñ 4Ø¸×8HÑ8HÈÓ8S×8YÐ8YÐWYØ"1×<LÑ<LÈZÓ<X×<^Ð<^Ð\^Ø2ô
÷ 
ð 	
øôA ô OØ(0¯©Ð5GÓ(H×(NÐ(NÈBÓ%ðOú÷ !× Ð úñ8øô ô 'Ø"&’ð'ú÷ %×$úñ
ùsÆ   ‚,I ®AH"Á?G5Â4I Ã0I Ã3!I ÄAH8 ÅH6Å	H8 Å#H8 Å%I Å-I Å5I ÆIÆ'"I Ç
I Ç$I Ç0IÇ1I Ç5"HÈHÈH"ÈHÈH"È"H3	È-	I È6H8 È8IÉI ÉIÉI ÉI	É	I c               ó(   € V ^8„  d   QhRRRRRRRR/# )r"   r;   r   r`  r%   r/   r$   r¿   r&   )r'   s   "r(   r)   r=   g  s,   € ÷ ñ Ø#ðØ25ðØEHðà	ñr*   c              ƒ  óÎ   "  € ^ RI Hp V! WW#4      G Rj  x€L
 w  rVVf   V# V P                  V4      pV'       d%   VP                  VP                  V4      G Rj  x€L
  R#  LK L5i)z]Expand ``@`` context references; returns None when the injection was refused (user notified).)Úinbound_referencesN)Úgateway.session_context_refsrÖ  rQ   rR   rS   )rU   r;   r`  r/   rÖ  ÚexpandedÚrefusalÚ_adapters   &&&&    r(   Ú"_expand_inbound_context_referencesÚ6GatewayInboundMixin._expand_inbound_context_referencesg  s`   é € õ 	DÙ"4°TÀ;Ó"]×]ÑˆØŠ?ØˆOØ×-Ñ-¨fÓ5ˆßØ—-‘- §¡°Ó8×8Ð8Ùñ ^ñ
 9ùs&   ‚A%•A!–$A%»A%ÁA#ÁA%Á#A%r`  c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# ©
r"   r.   r	   r;   r   Úhistoryzlist[dict[str, Any]]r`  r¿   r$   r&   )r'   s   "r(   r)   r=   t  s=   € ÷ Pñ PØ$ðPØ.;ðPØFZðPà"ðPð 
ñPr*   c             ƒ  ój  "  € \        V4       \        VR4      pV'       d   VP                  MVP                  ;'       g    RpT;'       g    V P	                  V4      pV P                  V4       V P                  WV4      pV P                  W4      w  rxršV'       d   V P                  W$Wg4      G Rj  x€L
 pV'       d   V P                  WWh4      G Rj  x€L
 pT P                  WiV
4      pV P                  W4      p^ RIHp V! WW$V4      G Rj  x€L
 pVf   R# V P                  WV4      #  Ly LY L 5i)a\  Prepare inbound event text for the agent. Shared by the normal inbound and queued
follow-up paths so attribution, image enrichment, STT, document notes, reply context and
@ references behave the same. Side effect: buffers per-session native image paths when the
model supports native vision; the caller consumes that buffer at ``run_conversation``.Ú_gateway_pending_stt_textr@   N)Úturn_references)r   rI  rá  rg   r®   Ú#_consume_pending_native_image_pathsr6  rJ  r[  rp  r‰  r«  r×  râ  r¸  )rU   r.   r;   rß  r`  Ú_pending_stt_preparedr/   rC  rD  rE  rF  râ  s   &$$$$       r(   Ú_prepare_inbound_message_textÚ1GatewayInboundMixin._prepare_inbound_message_textt  s"  é € ô 	˜UÔ#Ü '¨Ð/JÓ KÐß;P˜×7Ò7ÐV[×V`ÑV`×gÐgÐegˆð "×IÐI T×%AÑ%AÀ&Ó%Iˆà×0Ñ0°Ô=à×:Ñ:¸5È,ÓWˆØBF×B^ÑB^Ð_dÓB|Ñ?ˆÐ"2ßØ!%×!<Ñ!<¸VÐR^Ó!l×lˆLßØ!%×!;Ñ!;¸EÈ<Ó!e×eˆLØ×=Ñ=¸lÐ^iÓjˆØ×;Ñ;¸EÓPˆÝ@Ù,¨T¸&È|Ó\×\ˆØÒÙð ×2Ñ2°5À,ÓOÐOñ máeñ ]ùsH   ‚>D3ÁD3ÁA&D3Â3D-Â4D3Ã D3ÃD/Ã:D3ÄD1ÄD3Ä/D3Ä1D3c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# rÞ  r&   )r'   s   "r(   r)   r=   •  s=   € ÷ 
Bñ 
BØ$ð
BØ.;ð
BØFZð
Bà"ð
Bð 
ñ
Br*   c             ƒ  ó�  "  € ^ RI Hp \        WW4R7      p\        \        V RR4      RR4      '       dU   V! V P	                  V4      4      ;_uu_4       GRj  x€L
  V P
                  ! R/ VB G Rj  x€L
 uuRRR4      GRj  x€L
  # V P
                  ! R/ VB G Rj  x€L
 #  LJ L2 L#  + GRj  x€L 
 '       g   i     L9; i L&5i)zDRun inbound preprocessing under the routed profile when multiplexed.)Ú_async_profile_runtime_scope)r.   r;   rß  r`  r`   Nrz   Fr&   )r‰   ré  rK  r2   Ú _resolve_profile_home_for_sourcerå  )rU   r.   r;   rß  r`  ré  Úkwargss   &$$$$  r(   Ú,_prepare_profile_scoped_inbound_message_textÚ@GatewayInboundMixin._prepare_profile_scoped_inbound_message_text•  sœ   é € õ
 	=Ü˜E¸'Ô[ˆÜ”7˜4 ¨4Ó0Ð2FÈ×NÒNÙ3°D×4YÑ4YÐZ`Ó4a×b×bÕbØ!×?Ò?ÑIÀ&ÑI×I÷ c×bÒbà×7Ò7ÑA¸&ÑA×AÐAñ cÙI÷ c×b×bÒbúáAùsl   ‚ACÁB"ÁCÁB(Á1B$Á2B(Á5CÂB&ÂCÂCÂCÂ$B(Â&CÂ(C	Â.B1Â/
C	Â:C	Â<	Cc               ó   € V ^8„  d   QhRR/# )r"   r$   r%   r&   )r'   s   "r(   r)   r=   ¡  s   € ÷ Sñ S¸#ñ Sr*   c              ƒ  óì   "  € V P                  V4      '       g%   VP                  ;'       g    RP                  4       # V P                  VR4      G Rj  x€L
 w  r#RP	                  R V 4       4      #  L5i)zDReturn raw text or successful voice transcripts for a clarify reply.r@   Nr1   c              3  ót   "  € T F.  qP                   ! 4       '       g   K  VP                   ! 4       x € K0  	  R # 5ir  )re   )r¥  r   s   & r(   r§  ÚBGatewayInboundMixin._prepare_clarify_reply_text.<locals>.<genexpr>¦  s"   é € ÐRÑ.D¨ÏÊÏ	œ9˜1Ÿ7š7Ÿ9˜9Ó.Dùs   ‚8Ÿ8)r   rg   re   Ú$_transcribe_pending_audio_event_oncer¶  )rU   r.   rñ  Úsuccessful_transcriptss   &&  r(   r  Ú/GatewayInboundMixin._prepare_clarify_reply_text¡  sg   é € à×.Ñ.¨u×5Ò5Ø—J‘J×$Ð$ "×+Ñ+Ó-Ð-Ø*.×*SÑ*SÐTYÐ[]Ó*^×$^Ñ!ˆØ�{‰{ÑRÑ.DÓRÓRÐRñ %_ùs   ‚*A4­&A4ÁA2ÁA4c               ó    € V ^8„  d   QhRRRR/# )r"   r`  r%   r$   rM  r&   )r'   s   "r(   r)   r=   ¨  s   € ÷ ñ ¸sð Àyñ r*   c                	ó¸   € V P                  V4      pVe*   \        VP                  P                  ;'       g    . 4      M. pV'       d   . VP                  n        V# r  )r¯   rR  r°   rS  )rU   r`  rþ  r…  s   &&  r(   rã  Ú7GatewayInboundMixin._consume_pending_native_image_paths¨  sN   € Ø×(Ñ(¨Ó5ˆØCHÒCT”�U×%Ñ%×8Ñ8×>Ð>¸BÔ?ÐZ\ˆßØ24ˆE×ÑÔ/Øˆr*   c               ó$   € V ^8„  d   QhRRRRRR/# )r"   r.   r	   r`  r%   r$   r�   r&   )r'   s   "r(   r)   r=   ¯  s#   € ÷ ñ °\ð ÐPSð ÐX\ñ r*   c              ƒ  óä   "  €  V P                   P                  V4      G Rj  x€L
 pT'       g   R# Y!n        Y1n        R#  L  \         d"   p\        P	                  RY$4        Rp?R# Rp?ii ; i5i)z=Persist the exact resolved routing key for this running turn.Nz/Could not persist active-turn marker for %s: %sFT)Úasync_session_storeÚmark_turn_activerf   rF   rP   Ú _gateway_active_turn_session_keyÚ_gateway_active_turn_token)rU   r.   r`  Útokenrä  s   &&&  r(   Ú_mark_durable_active_turnÚ-GatewayInboundMixin._mark_durable_active_turn¯  sc   é € ð	Ø×2Ñ2×CÑCÀKÓP×PˆE÷ Ùð 2=Ô.Ø+0Ô(Ùñ QøÜô 	Ü�N‰NÐLÈkÔ_Ýûð	üs@   ‚A0„A ¢?£A §A0¯A0¿A ÁA-ÁA(Á"A0Á(A-Á-A0c               ó    € V ^8„  d   QhRRRR/# rÔ  r&   )r'   s   "r(   r)   r=   ¾  s   € ÷ )ñ )°lð )Àtñ )r*   c           
   ƒ  óî  "  € \        VRR4      p\        VRR4      p V'       d	   V'       g8    R F.  p\        \        4      ;_uu_ 4        \        W4       RRR4       K0  	  R# Rp\	        ^^4       Fd  p \        V P                  P                  W#4      G Rj  x€L
 4      u R F.  p\        \        4      ;_uu_ 4        \        W4       RRR4       K0  	  # 	  \        P                  RW%4        R F.  p\        \        4      ;_uu_ 4        \        W4       RRR4       K0  	  R#   + '       g   i     EK	  ; i L¢  + '       g   i     Kª  ; i  \         d4   pTpT^8  d   \        P                  RY&T4        Rp?EK   Rp?EK  Rp?ii ; i  + '       g   i     K±  ; i  R FB  p\        \        4      ;_uu_ 4        \        Y4       RRR4       K0    + '       g   i     KA  ; i	  i ; i5i)u¯   Best-effort CAS clear of the marker owned by *event* (3 attempts; never blocks agent/lease
release â€” a stale marker is bounded by the agent timeout and clean-start discard).rü  Nrý  Fz5Retrying active-turn marker cleanup for %s (%d/3): %sz>Could not clear active-turn marker for %s after 3 attempts: %s)rü  rý  )r2   r   ÚAttributeErrorÚdelattrÚranger�   rú  Úclear_turn_activerf   rF   r‹   rP   )rU   r.   r`  rþ  ÚattrÚ
last_errorÚattempträ  s   &&      r(   r  Ú.GatewayInboundMixin._clear_durable_active_turn¾  s’  é € ô ˜eÐ%GÈÓNˆÜ˜Ð;¸TÓBˆð	)ß§eØó" [�Üœn×-Õ-Ü˜EÔ(÷ .Ñ-ó [ð! /3ˆJÜ   Až;�ðÜ d×&>Ñ&>×&PÑ&PÐQ\Ó&d× dÓeÑeó [�Üœn×-Õ-Ü˜EÔ(÷ .Ñ-ò [ñ 'ô �N‰NØPÐR]ôð ãZ�Üœn×-Õ-Ü˜EÔ(÷ .Ñ-ó [ß-×-Ñ-úñ !e÷ .×-Ð-ûô !ô Ø!$�JØ ”{ÜŸ™ØSØ'°#÷ó ö #ûðú÷ .×-Ð-ûó [�Üœn×-Õ-Ü˜EÔ(÷ .×-×-Ò-úò [üsÏ   ‚G5žF( ®G5ÁD(ÁG5Á%F( Á7#EÂD=
ÂEÂ"F( Â$G5Ã D?	ÃG5ÃF( Ã1G5ÄFÄG5Ä(D:Ä3
G5Ä=EÄ?EÅ
	G5ÅFÅ FÅ>F( ÆFÆF( ÆF%Æ	G5Æ(G2ÇGÇ
G2ÇG,Ç&G2Ç2G5r;   rÂ  r‘  r’  c               ó0   € V ^8„  d   QhRRRRRRRRRRR	R
/# )r"   r;   zOptional[SessionSource]r`  r¿   rÂ  zOptional[dict]r‘  r’  r$   r%   r&   )r'   s   "r(   r)   r=   Ú  s@   € ÷ +ñ +Ø0ð+ØFSð+à#ð+à6Cð+ð ð+ð 
ñ	+r*   c               óÖ  €  ^ RI Hp ^ RIHpHp ^ RIHp	 \        V\        4      '       d   TMV	! 4       p
T;'       g    RP                  4       pT;'       g    RP                  4       pRpV'       d	   V'       gë   Vf	   V'       dß    V P                  WV
R7      w  rï\        V\        4      '       d   TM/ pV'       g'   \        V\        4      '       d   VP                  4       pV'       g=   \        VP                  R4      \        4      '       d   VR,          P                  4       p\        VP                  R4      \        4      '       d   VR,          P                  4       pT! T;'       g    V! 4       T;'       g    V! 4       W­R
7      #   \         d!   p\        P                  R	T4        Rp?LORp?ii ; i  \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)aI  Resolve image-input routing (``"native"`` / ``"text"``) for the effective model this turn
(see agent/image_routing.py). Sessions can carry /model overrides and this runs before AIAgent
sets the auxiliary_client runtime globals, so resolve the per-session runtime bundle the
upcoming turn will use, not just the persisted default.)Údecide_image_input_mode)Ú_read_main_modelÚ_read_main_providerrŽ  r@   NrÁ  r‘  Úrequested_provideruO   image_routing: session runtime resolution failed, falling back to config â€” %s)r  u;   image_routing: decision failed, falling back to text â€” %srg   )Úagent.image_routingr  rU  r  r  r™  r�  r3   rK  re   rT  r%   r“   rf   rF   r‹   )rU   r;   r`  rÂ  r‘  r’  r  r  r  r�  r   Úresolved_providerÚresolved_modelÚresolved_requested_providerrY  rZ  Úrkrä  s   &$$$$$            r(   rQ  Ú,GatewayInboundMixin._decide_image_input_modeÚ  s‹  € ð"	ÝCßTÝ5ä!+¨K¼×!>Ò!>‘+ÁKÃMˆCØ!)§ ¨R× 6Ñ 6Ó 8ÐØ#Ÿk˜k r×0Ñ0Ó2ˆNØ*,Ð'ç%¯^À&ÒBT×XcðØ15×1TÑ1TØ%ÈCð 2Uó 2Ñ.�Jô ,6°nÄd×+KÒ+K™ÐQS�Bß)¬j¸ÄS×.IÒ.IØ)3×)9Ñ)9Ó);˜ß,´¸B¿F¹FÀ:Ó<NÔPS×1TÒ1TØ,.¨z­N×,@Ñ,@Ó,BÐ)Ü! "§&¡&Ð)=Ó">Ä×DÒDØ68Ð9MÕ6N×6TÑ6TÓ6VÐ3ñ +Ø!×:Ð:Ñ%8Ó%:¸N×<`Ð<`ÑN^ÓN`Øôð øô !ô Ü—L‘LØiØ÷ñ ûðûô ô 	Ü�L‰LÐVÐX[Ô\Ýûð	úsq   ‚;F< ¾F< ÁF< Á3F< Á;F< Â6F Â?-F Ã-A8F Å%
F< Å0F< Æ F< ÆF9ÆF4Æ/F< Æ4F9Æ9F< Æ<G(ÇG#Ç#G(c               ó$   € V ^8„  d   QhRRRRRR/# )r"   Ú	user_textr%   rC  rM  r$   r&   )r'   s   "r(   r)   r=     s'   € ÷ +Cñ +C¸3ð +CÈYð +CÐ[^ñ +Cr*   c              ƒ  ó  "  € ^ RI Hp ^ RIHp Rp. pV F�  p \        P                  RV4       \        P                  ! V! WuR7      G Rj  x€L
 4      pVP                  R4      '       d#   V! VP                  RR	4      4      p	R
V	 RV R2p
MRV R2p
 VP                  V
4       K’  	  V'       g   V# RP                  V4      pV'       d   V RV 2# T#  L‰  \         d'   p\        P                  RT4       RT R2p
 Rp?LoRp?ii ; i5i)zæAuto-analyze user-attached images with the vision tool and prepend the descriptions.
Description *and* local cache path are injected so the model understands the image without
a tool call and can re-examine it with vision_analyze.)Ú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)Ú	image_urlÚuser_promptNÚsuccessÚ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: Ú]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: r1   )Útools.vision_toolsr  Úagent.memory_contextr  rF   r‹   ÚjsonÚloadsr“   rf   rG   r?  r¶  )rU   r  rC  r  r  Úanalysis_promptÚenriched_partsrH  ÚresultÚdescriptionÚnoterÕ   r5   s   &&&          r(   rV  Ú/GatewayInboundMixin._enrich_message_with_vision  s,  é € õ 	;Ý9ðGð 	ð ˆÛˆDðÜ—‘Ð<¸dÔCÜŸšÑ*=ÈÔ*j×$jÓk�Ø—:‘:˜i×(Ò(Ù"2°6·:±:¸jÈ"Ó3MÓ"N�KàKÈKÈ=ð Y&à&* V¨3ð0ñ ð@à@D¸vÀQðHñ ð ×!Ñ! $Ö'ñ1  ÷2 ØÐØ—‘˜^Ó,ˆß-6�&�˜˜i˜[Ð)ÐB¸FÐBñ3 %køô ô Ü—‘Ð=¸qÔAð<à<@¸6ÀðDõ ûðüs^   ‚D™2CÁC
ÁCÁ+!CÂDÂCÂDÂ1DÃ	DÃCÃDÃ"DÃ>DÄDÄD)rn   ))Úconfirm_oncer  )Úconfirm_alwaysr  )Úconfirm_cancelr  >   r�  r‹  ra  rW  rr  rI  rÈ  ÚstartrÝ  Úegressrh  r  )OÚ__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r[   rh   rt   r¢   r¼   rÇ   ÚstaticmethodrÖ   rí   r  r+  r  r$  r3  r^  rj  rO  r‚  r™  r‘  rÑ  rØ  rå  rò  r   r  r"  r.  r5  r8  r=  rE  rQ  r[  rd  rm  r{  r€  r„  r  r£  r´  r«  r­  r»  rÄ  rà  ræ  rï  r÷  r  r"  r  r6  rJ  r[  re  rp  rz  Úclassmethodr‰  r«  r¸  rÒ  rÛ  rå  rì  r  rã  rÿ  r  rQ  rV  Ú__static_attributes__r&   r*   r(   r8   r8   G   s¹  † ñ HõLõ:lõ26õe$õNõ6ð4 ôó ðõ+õZMðd 	�6˜5 &¨$°¸	À6Ø�(˜J¨Ø�(˜D (¨F°H¸kÈ8ð"Ðð &|Ð"õõõ<3UõjQõ4RðmØaf÷mõ õD&SõPð0 ôió ðiõ@õ 1õ2;õ&;õz,/õ\
ò
òò*õòtòsòò.ò jòNòSð ôó ðòñ> 'ò (ó Ðõõ"ð< ô=ó ð=õ(;õzõ !õ0.õB%õNzB÷xUõ*ð* ôGó ðGõ*"UðHVØRVðVØkw÷Võð  ôwó ðwð ôó ðð( ôó ðð> ôó ðõ29
õvðPà%)÷PðB
Bà%)÷
BõSõõõ)ð8+Ø37ð+ØVZð+à&*ð+àFJð+ð  $÷+÷Z+Cñ +Cr*   r8   )@r4  Ú
__future__r   ÚloggingÚtypingr   rJ   Úconcurrent.futuresÚ
concurrentÚdataclassesr#  rÉ  rw  rG  Ú
contextlibr   Úpathlibr   Ú
agent.i18nr   rb   r   r€  r   Úgateway.platforms.eventr	   r
   Úgateway.run_busyr   Úgateway.run_inbound_mediar   Úgateway.run_inbound_hooksr   Ú!gateway.run_inbound_transcriptionr   Úgateway.run_plugin_injectionr   Ú gateway.run_inbound_unauthorizedr   r   r   r   r   r´  r   r   r   r   Úgateway.turn_leaser   r   r   r   r   r   r‰   r   Úgateway.run_turn_runnerr    Ú	getLoggerrF   r,   r6   r8   r&   r*   r(   Ú<module>rK     s¦   ðñõ #ã Ý  Û Û Û Û Û 	Û 	Û Ý Ý å Ý #Ý 1ß =Ý 1Ý :Ý >Ý NÝ D÷õ ÷ó õ 5ß 3Õ 3çÝ)Ý2ð 
×	Ò	˜=Ó	)€õõ
-ôkCÐ2Ð4TÐVqö kCr*   