+
    jHàjªH  ã            	       óî   € R t ^ RIt^ RIH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 tR	 tR
 tR tR tR tR tR tR tRRR0R0 RmR0 RmRRR0/tRtR tR tR tR tR tR# )a¡  Ink's session utilities on the shared owner: ``/save`` (``session.save``), ``/reload``
(``reload.env``), ``/agents pause|resume`` (``delegation.pause``) and ``/rollback``
(``rollback.list`` / ``rollback.diff`` / ``rollback.restore``), plus the classic CLI's ``/diff session``
(``rollback.session_diff``).

Main's per-TUI sidecar served these from its own session table, which never holds a shared-gateway
session, so the canonical TUI refused them. Each verb reuses main's helpers rather than re-deriving
them. ``dispatch`` already runs every handler under the owning profile's scope (``owner_scope``) and
``asyncio.to_thread`` carries that context into the worker thread.
N)Údatetime)Úpartial)ÚPath)Ú	authorize)Úcontext_breakdown)ÚRuntimeStoreErrorc                 óV  € R \        \        V 4      R\        \        V 4      R\        \        V 4      R\        \        V 4      R\        \
        V RR7      R\        \
        V RR7      R	\        \
        V R
R7      R\        \
        V RR7      R\        \        V 4      R\        \        V 4      /
# )zsession.savezsession.exportz
reload.envzdelegation.pausezrollback.listÚlist)Úkindzrollback.diffÚdiffzrollback.restoreÚrestorezrollback.session_diffÚsession_diffzsession.context_breakdownzsession.history)r   Úsave_sessionÚexport_sessionÚ
reload_envÚpause_delegationÚrollbackr   Úsession_history)Ú
connections   &Ú</home/ubuntu/.hermes/hermes-agent/gateway/session_tui_ops.pyÚhandlersr      s�   € ØœG¤L°*Ó=Øœg¤n°jÓAØœ'¤*¨jÓ9Ø¤Ô(8¸*Ó EØœW¤X¨zÀÔGØœW¤X¨zÀÔGØ¤¬°*À9Ô MØ#¤W¬X°zÈÔ%WØ'¬Ô1BÀJÓ)OØœw¤¸
ÓCð	Eð 	Eó    c                ó´   € \        \        V P                  4      4      pVP                  4       '       d   VP	                  4       '       d   V# ^ RIHp V! 4       # )zRThe owning profile's home (a symbolic test-peer id falls back to the scoped home).)Úget_hermes_home)r   ÚstrÚ
profile_idÚis_absoluteÚis_dirÚhermes_constantsr   )Ú	authorityÚhomer   s   &  r   Ú_profile_homer!   %   sA   € ä”�I×(Ñ(Ó)Ó*€DØ×Ñ×Ò˜dŸk™kŸmšmØˆÝ0ÙÓÐr   c           	     óX   € \        \        \        V P                  RR4      RR4      4      # )zSEvery turn runs under a per-profile secret scope (``owner_scope``'s own predicate).ÚconfigNÚmultiplex_profilesF)ÚboolÚgetattrÚrunner)r   s   &r   Ú_multiplexedr(   .   s'   € ä”œ 	× 0Ñ 0°(¸DÓAÐCWÐY^Ó_Ó`Ð`r   c                 ó  € \        V4      V,
          '       g3   \        VP                  \        4      '       d   VP                  '       g   \	        R 4      h\        WW$4       V P                  P                  VP                  ,          # )Úinvalid_params)ÚsetÚ
isinstanceÚ
session_idr   r   r   r   Úsessions)r   ÚrefÚparamsÚfieldsÚ
capabilitys   &&&&&r   Ú	_live_refr3   3   sZ   € Ü
ˆ6ƒ{�V×Ô¤:¨c¯n©n¼c×#BÒ#BÈ#Ï.Ï.È.ÜÐ 0Ó1Ð1Üˆj˜vÔ2Ø×Ñ×(Ñ(¨¯©Õ8Ð8r   c              ƒ  ó²   aa"  € \        WVRR0R4       V P                  o^ RIHp V! SV4      oVV3R lp\        P
                  ! V4      G Rj  x€L
 #  L5i)u  ``/save``: main's ``session.save`` â€” the stored transcript as a ``/save json`` snapshot in the
profile's ``sessions/saved/``. Reads the conversation's CURRENT physical row (a local session's
reset/compression child), like main's ``_submit_row_target_key``.r-   Úprofileúsession:read©Úphysical_targetc                  óÞ  <€ ^ RI Hp Hp ^ RIHp  V ! SP
                  SR4      pT'       g   \        R4      h\        S4      R,          R,          R	\        P                  ! 4       R
 R2,          p TP                  P                  RRR7       TP                  T! TR4      RR7       R\        T4      /#   T d   p\        R4      ThRp?ii ; i  \         d   p\        R4      ThRp?ii ; i)é    ©Úload_save_snapshotÚrender_session_for_save©ÚSessionExportTooLargeErrorÚjsonÚexport_too_largeNÚ	not_foundr.   ÚsavedÚhermes_conversation_z%Y%m%d_%H%M%Sz.jsonT)ÚparentsÚexist_okúutf-8)ÚencodingÚstorage_unavailableÚfile)Úhermes_cli.session_exportr<   r=   Úhermes_stater?   Údbr   r!   r   ÚnowÚparentÚmkdirÚ
write_textÚOSErrorr   )r<   r=   r?   ÚdataÚexcÚpathr   Útargets         €€r   ÚwriteÚsave_session.<locals>.writeC   sé   ø€ ßYÝ;ð	AÙ% i§l¡l°F¸FÓCˆD÷ Ü# KÓ0Ð0Ü˜iÓ(¨:Õ5¸Õ?Ø(¬¯ª«¸Ð(FÀeÐLõMˆð	DØ�K‰K×Ñ d°TÐÔ:Ø�O‰OÑ3°D¸&ÓAÈGˆOÔTð œ˜D›	Ð"Ð"øð *ô 	AÜ#Ð$6Ó7¸SÐ@ûð	Aûô ô 	DÜ#Ð$9Ó:ÀÐCûð	Dús/   ‘B5 Á17C Â5CÂ<CÃCÃC,ÃC'Ã'C,N)r3   r   Úgateway.session_ancillaryr8   ÚasyncioÚ	to_thread)r   r/   r0   r8   rW   r   rV   s   &&&  @@r   r   r   :   sS   ùé € ô ˆj˜v¨°iÐ'@À.ÔQØ×$Ñ$€IÝ9Ù˜Y¨Ó,€Fö#ô" ×"Ò" 5Ó)×)Ð)Ñ)ùó   „AAÁAÁAc              ƒ  óè  aa	a
a"  € \        WV0 RmR4       VP                  RR4      VP                  RR4      uo	o
\        S	\        4      '       d   \        S
\        4      '       g   \        R4      h^ RIHpHp  V! S	4      o	T P                  o^ R	IHp T! ST4      oTT	T
T3R
 lp\        P                  ! T4      G Rj  x€L
 pRS	RT! SS	4      RT/#   \         d    \        R4      Rhi ; i L.5i)zï``session.export``: the ``/save`` transcript rendered for the CLIENT to write (json/md/html,
optional force-redaction). Nothing is written on the gateway host, so a remote Desktop and a
local Ink both save to the user's own disk (T10/T11).ÚformatÚredactr6   r@   Fr*   )Údefault_save_filenameÚnormalize_save_formatNr7   c                  óä   <€ ^ RI Hp Hp ^ RIHp  V ! SP
                  S	S4      pT'       g   \        R4      hS'       d   ^ RIHp T! T4      pT! TS4      #   T d   p\        R4      ThRp?ii ; i)r:   r;   r>   rA   NrB   )Úredact_session_data)	rK   r<   r=   rL   r?   rM   r   Úhermes_cli.session_export_mdrc   )
r<   r=   r?   rS   rT   rc   r   Úfmtr_   rV   s
         €€€€r   ÚrenderÚexport_session.<locals>.renderh   sp   ø€ ßYÝ;ð	AÙ% i§l¡l°F¸CÓ@ˆD÷ Ü# KÓ0Ð0ßÝHÙ& tÓ,ˆDÙ& t¨SÓ1Ð1øð *ô 	AÜ#Ð$6Ó7¸SÐ@ûð	Aús   ‘A ÁA/ÁA*Á*A/ÚfilenameÚcontent>   r^   r_   r5   r-   )r3   Úgetr,   r   r%   r   rK   r`   ra   Ú
ValueErrorr   rY   r8   rZ   r[   )r   r/   r0   r`   ra   r8   rf   ri   r   re   r_   rV   s   &&&     @@@@r   r   r   W   së   ûé € ô ˆj˜vÒ'TÐVdÔeØ—*‘*˜X vÓ.°·
±
¸8ÀUÓ0K€K€CˆÜ�cœ3×Ò¤z°&¼$×'?Ò'?ÜÐ 0Ó1Ð1ßVð<Ù# CÓ(ˆð ×$Ñ$€IÝ9Ù˜Y¨Ó,€F÷2ð 2ô ×%Ò% fÓ-×-€GØ�c˜:Ñ'<¸VÀSÓ'IÈ9ÐV]Ð^Ð^øô) ô <ÜÐ 0Ó1°tÐ;ð<úñ& .ùs*   †A5C2Á<C Â=C2ÃC0ÃC2ÃC-Ã-C2c              ƒ  ó²   aa"  € \        WVRR0R4       V P                  o^ RIHp V! SV4      oVV3R lp\        P
                  ! V4      G Rj  x€L
 #  L5i)zéMain's ``session.history``: the display transcript of the conversation's current physical row (compression tip or local receipt entry), ancestors included, each row with its durable ``row_id``; Desktop's edit resolves its turn by it.r-   r5   r6   )Útranscript_targetc                  óŒ   <€ ^ RI Hp  SP                  P                  SRRR7      pR\	        V4      RV ! VSP
                  4      /# )r:   )Údisplay_projectionT)Úinclude_ancestorsÚinclude_row_idsÚcountÚmessages)Úgateway.session_controlsro   rM   Úget_messages_as_conversationÚlenr   )ro   Úrowsr   rV   s     €€r   ÚreadÚsession_history.<locals>.read�   sD   ø€ Ý?Ø�|‰|×8Ñ8¸ÐSWÐimÐ8ÓnˆØœ˜T› JÑ0BÀ4È×I]ÑI]Ó0^Ð_Ð_r   N)r3   r   Úgateway.session_local_recoveryrm   rZ   r[   )r   r/   r0   rm   rx   r   rV   s   &&&  @@r   r   r   y   sR   ùé € äˆj˜v¨°iÐ'@À.ÔQØ×$Ñ$€IÝ@á˜y¨#Ó.€Fö`ô ×"Ò" 4Ó(×(Ð(Ñ(ùr\   c              ƒ  ó¦   a"  € \        WVRR0R4       V P                  oV3R lpR\        \        P                  ! V4      G Rj  x€L
 4      /#  L	5i)uÍ  ``/reload``: re-read the profile's ``.env`` (main's ``reload.env`` / CLI ``/reload``).

Single-profile owner: main's ``hermes_cli.config.reload_env()`` verbatim â€” the owner's
``os.environ`` is what its turns read, exactly as the TUI's own sidecar process was. Built agents
keep their credential pool until ``/new`` (main's documented behaviour).

Multiplexed owner: ``os.environ`` is shared by every served profile and turns never read profile
secrets from it, so it is left alone. Each turn already re-reads ``.env`` into its own scope; what
can be stale is the profile's external secret-source snapshot, which is re-pulled here. The count
is the number of keys whose value in this profile's secret scope changed.
r-   r5   úsession:controlc                  óJ  <aa€ \        S4      '       g   ^ RIHp  V ! 4       # ^ RIHpHp ^ RIHpHp \        S4      pV! V4      oV! VR,          4       V! V4       V! V4       V! V4      o\        VV3R lSP                  4       SP                  4       ,           4       4      # )r:   )r   )Úbuild_profile_secret_scopeÚinvalidate_env_file_cache)Úhydrate_profile_secret_sourcesÚreset_secret_source_cachez.envc              3   ój   <"  € T F(  pSP                  V4      SP                  V4      8g  x € K*  	  R # 5i)N)rj   )Ú.0ÚkeyÚafterÚbefores   & €€r   Ú	<genexpr>Ú-reload_env.<locals>.reload.<locals>.<genexpr>¥   s(   øé € Ð]Ñ@\¸�6—:‘:˜c“? e§i¡i°£nÖ4Ó@\ùs   ƒ03)r(   Úhermes_cli.configr   Úagent.secret_scoper~   r   Úhermes_cli.env_loaderr€   r�   r!   ÚsumÚkeys)	Úreload_process_envr~   r   r€   r�   r    r…   r†   r   s	         @@€r   ÚreloadÚreload_env.<locals>.reload™   s€   ú€ Ü˜I×&Ò&ÝJÙ%Ó'Ð'ß\ßcÜ˜YÓ'ˆÙ+¨DÓ1ˆÙ! $¨¥-Ô0Ù! $Ô'Ù& tÔ,Ù*¨4Ó0ˆÜÕ]ÀÇÁÃÐPU×PZÑPZÓP\Ö@\Ó]Ó]Ð]r   ÚupdatedN)r3   r   ÚintrZ   r[   )r   r/   r0   r�   r   s   &&& @r   r   r   ˆ   sP   øé € ô ˆj˜v¨°iÐ'@ÐBSÔTØ×$Ñ$€Iõ^ð ”s¤×!2Ò!2°6Ó!:×:Ó;Ð<Ð<Ñ:ùs   ƒAAÁA
Á
Ac              ƒ  ó@  "  € VP                  RR4      p\        V4      0 R
m,
          '       g   \        V4      \        Jd   \	        R4      hVP
                  '       d   \        WVR4       M¡RV P                  P                  9  d   \	        R4      hVP                  R4      pVe"   \        V\        4      '       g   \	        R4      hV'       d>   ^ RIHp V! V\        V P                  P                  4      4      '       g   \	        R4      h^ R	IHp RV! V4      /# 5i)uþ  ``/agents pause|resume`` and the overlay's ``p``: main's ``delegation.pause`` â€” block or
unblock NEW ``delegate_task`` spawns; running children keep going.

The gate (``tools.delegate_tool_registry``) is process-wide, as it was in main's sidecar (a
TUI's sidecar served one TUI, but its gate covered every agent in that process). On the shared
owner it therefore covers every chat this gateway runs, which is what an operator's kill switch
is for; ``delegation.status`` reports the same flag to every client.ÚpausedTr5   r*   r|   Úpermission_denied)Úprofile_matches_homeÚprofile_mismatch)Úset_spawn_paused>   r”   r5   r-   )rj   r+   Útyper%   r   r-   r   ÚactorÚcapabilitiesr,   r   Úhermes_cli.profilesr–   r   r   r   Útools.delegate_tool_registryr˜   )r   r/   r0   r”   r5   r–   r˜   s   &&&    r   r   r   ©   så   é € ð �Z‰Z˜ $Ó'€FÜ
ˆ6ƒ{Ò8×8Ô8¼DÀ»LÔPTÓ<TÜÐ 0Ó1Ð1Ø
‡~‡~€~Ü�* 6Ð+<Õ=à J×$4Ñ$4×$AÑ$AÔAÜ#Ð$7Ó8Ð8Ø—*‘*˜YÓ'ˆØÒ¤z°'¼3×'?Ò'?Ü#Ð$4Ó5Ð5ßÝ@Ù'¨´°j×6JÑ6J×6UÑ6UÓ1V×WÒWÜ'Ð(:Ó;Ð;Ý=ØÑ& vÓ.Ð/Ð/ùs   ‚ADÁA1DÃADr	   r-   r5   r   r   r   c             ƒ  ó  aaaaaaa"  € \         S,          p\        ;QJ d    V3R lR 4       F  '       g   K   RM	  RM! V3R lR 4       4      '       g?   SR9   d   RS9  g1   SP                  R4      e)   \        SR,          \        4      '       g   \        R	4      h\        YSTSR8w  d   R
MR4      pV P                  p^ RIH	p V! VP                  VP                  4      oSf   \        R4      hSP                  R4      ;'       g    RoSR8X  d4   S'       g,   VP                  V4      P                  R8w  d   \        R4      h^ RIHp V! Wa4      o^ RIHp	 V	! SP%                  VRR7      4      o\&        P(                  ! SP*                  4      oR VVVVVVV3R llp
\,        P.                  ! V
4      G Rj  x€L
 pSR8X  d6   VP                  R4      '       d   S'       g   \1        W4      G Rj  x€L
 VR&   V#  LB L5i)a¥  ``/rollback [list] | diff <n|hash> | <n|hash> [file]`` and ``/diff session``: main's ``rollback.*`` over this
session's checkpoints (the shared ``<profile>/checkpoints`` store, keyed by the frozen launch cwd).

The manager is built from the session's frozen ``checkpoints`` policy rather than read off the
resident agent (main's ``agent._checkpoint_mgr``, built from the same config): it carries no
per-session state these reads need, and a restarted owner or a just-rewound session has no
resident agent. A whole-tree restore also rewinds the transcript to before the newest user turn
(main's ``_rewind_active_session_history``) through the owner's fenced ``rewind`` mutation.c              3   ó¼   <"  € T FQ  pVS9   ;'       d@    \        SV,          \        4      '       * ;'       g    VR 8H  ;'       d    SV,          '       * x € KS  	  R# 5i)ÚhashN)r,   r   )rƒ   r„   r0   s   & €r   r‡   Úrollback.<locals>.<genexpr>×   sS   øé € ð -Ù+ˆsð �&‰=×fÐf¤*¨V°C­[¼#Ó">Ô>×eÐeÀ3È&Á=×CdÐCdÐY_Ð`cÕYdÔUdÔfÛ+ùs   ƒA”#A¸AÁAr    Ú	file_pathTFr   ÚallNr*   r6   r|   )Úpolicy_for_sourcer•   Ú ÚidleÚsession_busyr7   )Ú_checkpoint_agent_kwargs)Úsecretsc                ó$   € V ^8„  d   QhR\         /# )é   Úreturn)Údict)r^   s   "r   Ú__annotate__Úrollback.<locals>.__annotate__ë   s   € ÷ +Iñ +I”ñ +Ir   c                  óÞ  <€ ^ RI Hp  ^ RIHp T ! RR\	        SR,          4      /SP                  4        UUu/ uF-  w  r#VP                  R4      '       g   K  V\        R4      R VbK/  	  uppB pSP                  pVP                  '       g   SR9   d   SR8X  d   RR	R
. /# RR	/# SR8X  d\   RRR
VP                  V4       Uu. uF;  pRVP                  RR4      RVP                  RR4      RVP                  RR4      /NK=  	  up/# ^ RIHpHp V! S4      p	 VP                  S4      p
V! V	4       SR8X  d   \!        WEV
4      #  V! WESR,          4      pSR8X  dr   T
'       d   \%        R4      h^ RIHp TP-                  Y[4      pTP                  RR4      R,          pRTP                  RR4      RT/pT! T^P4      ;p'       d   TTR&   T# T
'       d   RR	RT
/# TP/                  Y[S;'       g    RS'       * ;'       d    SP                  R4      '       * R7      # u uppi u upi   T! T	4       i ; i  \"         d-   pSR8X  d   \%        R4      ThRR	R\'        T4      /u Rp?# Rp?ii ; i)r:   )ÚCheckpointManager)Ú_resolve_checkpoint_hashÚenabledÚcheckpoints_enabledÚcheckpoint_Nr	   r   FÚcheckpointsTr    r¥   Ú	timestampÚmessageÚreason)Úreset_terminal_scopeÚset_terminal_scoper   Úinvalid_checkpointÚsuccessÚerrorÚunsupported_terminal_backend)Úrender_diff:Ni   NÚstatÚrenderedr£   )r¢   Úsafe© )r	   r   )Útools.checkpoint_managerr±   Útui_gateway.checkpointsr²   r%   ÚitemsÚ
startswithrv   Úcwdr³   Úlist_checkpointsrj   Útools.terminal_scoperº   r»   Úunsupported_backend_reasonÚ_session_diffrk   r   r   Útui_gateway.renderrÀ   r   r   )r±   r²   r„   ÚvalueÚmgrrÉ   Úcrº   r»   ÚtokenÚrefusalrV   rT   rÀ   ÚresultÚrawÚpayloadrÂ   r¢   r
   Úkwargsr0   ÚpolicyÚtask_idÚterminals                     €€€€€€€r   ÚrunÚrollback.<locals>.runë   s‘  ø€ Ý>ÝDÙñ p¬¨VÐ4IÕ-JÓ(Kð pØ>D¿l¹l¼nôPoÙ>L±
°ÐPS×P^ÑP^Ð_l×PmÔ+ˆC”�MÓ"Ð#Ð$ eÒ+¹nòPoñ pˆà�j‰jˆØ�{�{ˆ{˜tÐ'?Ô?Ø<@ÀF¼N�I˜u m°RÐ8ÐbÐQZÐ\aÐPbÐbØ�6Œ>à˜t ]à×-Ñ-¨cÔ2ó54á2�Að ˜Ÿ™˜v rÓ*¨K¸¿¹¸{ÈBÓ9OÐQZÐ\]×\aÑ\aÐbjÐlnÓ\oÓpÙ2ñ54ð 5ð 5÷
 	RÙ" 8Ó,ˆð	(Ø×4Ñ4°WÓ=ˆGá  Ô'Ø�>Ô!Ü  ¨7Ó3Ð3ð	9Ù-¨c¸¸v½ÓGˆFð
 �6Œ>ßÜ'Ð(FÓGÐGÝ6Ø—X‘X˜cÓ*ˆFØ—*‘*˜V RÓ(¨Õ/ˆCØ˜vŸz™z¨&°"Ó5°v¸sÐCˆGÙ& s¨BÓ/Ð/ˆxÖ/Ø&.�˜
Ñ#ØˆNßØ˜u g¨wÐ7Ð7à�{‰{˜3°)×2CÐ2C¸tØ$-¤× GÐ G°f·j±jÀÓ6GÔ2Gð ó Ið 	IùóOPoùò54øñ ! Õ'ûô
 ô 	9Ø�vŒ~Ü'Ð(<Ó=À3ÐFØ˜u g¬s°3«xÐ8Õ8ûð	9ús<   ·HÁHÃAH#
ÄH( ÅH5 È(
H2È5I,É !I'É!I,É'I,r½   Úhistory_removed)r    r¢   )r   r   )Ú_ROLLBACK_FIELDSÚanyrj   r,   r%   r   r3   r   Úgateway.session_policyr¤   r'   ÚsourceÚ_handleÚexecution_staterY   r8   Úgateway.runr¨   r#   r@   ÚloadsÚterminal_jsonrZ   r[   Ú_rewind_last_turn)r   r/   r0   r
   r1   Úliver   r¤   r8   r¨   rÛ   rÔ   r¢   r×   rØ   rÙ   rÚ   s   &&fd        @@@@@r   r   r   Í   s§  þé € ô ˜dÕ#€Fß
ƒsô -Ù+ó-‡s‡s‚sô -Ù+ó-÷ -ò -Ø15Ð9LÔ1LÐQWÐ_eÔQeØ�z‰z˜%Ó Ò,´ZÀÀuÅÌt×5TÒ5TÜÐ 0Ó1Ð1Ü�Z f¨fÈÐPYÔHY±nÐ_pÓq€DØ×$Ñ$€IÝ8Ù˜y×/Ñ/°·±Ó=€FØ‚~ÜÐ 3Ó4Ð4Ø—
‘
˜;Ó'×-Ð-¨2€IØˆyÔ§¨y×/@Ñ/@ÀÓ/E×/UÑ/UÐY_Ô/_ä Ó/Ð/Ý9Ù˜iÓ-€GÝ4Ù% f§m¡m°IÀu mÓ&MÓN€FÜ�zŠz˜&×.Ñ.Ó/€H÷+Iö +IôX ×$Ò$ SÓ)×)€FØˆyÔ˜VŸZ™Z¨	×2Ò2¿9Ü*;¸JÓ*L×$LˆÐ Ñ!Ø€Mñ *á$LùsH   ‰-H¹HÁB5HÄHÄB HÆ?HÇ !HÇ"HÇ*HÇ8HÇ9
HÈHc                óä  € V'       d	   RRRRRV/# V P                  V4      pVP                  R4      '       g+   RRRRR\        VP                  R4      ;'       g    R4      /# VP                  RR4      p\        VP                  RR4      \        4      p\        V\        \        V4      ,
          4      pRRRRRVRVR	\        VP                  4       4      R
\        VP                  R
4      4      /# )z·``/diff session``: main's ``session_diff`` (earliest retained checkpoint vs the tree) as data,
so the classic CLI renders it with its own terminal renderer instead of chat-sized text.r³   Tr½   Fr¾   r¥   r   rÁ   Ú
diff_linesÚempty)	r   rj   r   Ú
_fit_frameÚ_SESSION_DIFF_BYTESÚ_wire_bytesrv   Ú
splitlinesr%   )rÐ   rÉ   rÓ   rÔ   r   rÁ   Úbodys   &&&    r   rÍ   rÍ     sâ   € ÷ Ø˜4 ¨E°7¸GÐDÐDØ×Ñ˜cÓ"€FØ�:‰:�i× Ò Ø˜4 ¨E°7¼CÀÇ
Á
È7Ó@S×@YÐ@YÐWYÓ<ZÐ[Ð[Ø�:‰:�f˜bÓ!€DÜ�f—j‘j ¨Ó,Ô.AÓB€DÜ�dÔ/´+¸dÓ2CÕCÓD€DØ�t˜Y¨¨f°d¸FÀDØœ#˜dŸo™oÓ/Ó0°'¼4ÀÇ
Á
È7Ó@SÓ;TðVð Vr   c                ór   € \        \        P                  ! V RR7      P                  RR4      4      ^,
          # )z_Bytes ``text`` takes inside a frame: JSON-escaped as ``serialize_frame`` writes it, then UTF-8.F)Úensure_asciirG   Úsurrogatepass)rv   r@   ÚdumpsÚencode)Útexts   &r   rî   rî   ,  s+   € äŒt�zŠz˜$¨UÔ3×:Ñ:¸7ÀOÓTÓUÐXYÕYÐYr   c                ó`  € \        V 4      ^,          V8:  g!   \        V 4      V8:  d   \        V 4      V8:  d   V # . ^ r2\        P                  ! RV RV^,            4       F.  pV\        V4      ,          pW18”  d    MVP	                  V4       K0  	  RP                  V4      P                  R4      # )z¿The longest whole-line prefix of ``text`` whose wire size fits ``budget`` bytes. The caller
reports the uncut line count, so the client names the cut instead of the frame dropping the socket.z(?<=\n)Nr¥   Ú
)rv   rî   ÚreÚsplitÚappendÚjoinÚremovesuffix)rö   ÚbudgetÚkeptÚusedÚlines   &&   r   rì   rì   1  s–   € ô ˆ4ƒy�1…}˜Ô¤3 t£9°Ô#6¼;ÀtÓ;LÐPVÔ;VØˆØ�Qˆ$ä—’˜ T¨+¨6°A­:Ð%6Ö7ˆØ”˜DÓ!Õ!ˆØŒ=ÙØ�‰�DÖñ	 8ð
 �7‰7�4‹=×%Ñ% dÓ+Ð+r   c              ƒ  óV  a"  € V P                   p^ RIHo ^ RIHp \
        P                  ! W2V4      G Rj  x€L
 p\        V3R l\        V4       4       R4      pVf   ^ # ^ RI	H
p ^ RIHp VP                  V4      p V! W P                  VRVP                  RR	\         P"                  ! 4       P$                   2R
VP&                  RVP(                  RRRRV//4      G Rj  x€L
 p	\-        T	P/                  R4      ;'       g    ^ 4      #  LÓ L*  T d   p
\+        R4      T
hRp
?
ii ; i5i)z²Drop the newest user turn and everything after it (main's full ``/rollback`` restore) via the
owner's revision-fenced ``rewind`` mutation; 0 when the transcript has no user turn.)Úuser_originated_turn_view)Úlocal_historyNc              3   óÎ   <"  € T FZ  p\        VP                  R 4      \        4      '       g   K*  VP                  R4      '       d   KC  S! V4      f   KO  VR ,          x € K\  	  R# 5i)Úrow_idÚarchivedN)r,   rj   r’   )rƒ   Úrowr  s   & €r   r‡   Ú$_rewind_last_turn.<locals>.<genexpr>G  sN   øé € ð _©N S¼jÈÏÉÐQYÓIZÔ\_×>`”=ØŸ7™7 :×.ô !Ù3LÈSÓ3Qô !�3�x—=’=«Nùs   ƒ'A%¯A%ÁA%ÁA%)Úmutate_session)ÚMUTATION_GUARD_REFUSALSr-   Ú
request_idz	rollback:Úexpected_revisionÚexpected_generationÚ	operationÚrewindrÖ   Útarget_message_idr§   Úrewound_count)r   Úagent.context_compressorr  rz   r  rZ   r[   ÚnextÚreversedÚgateway.session_mutationsr
  Úhermes_state_mutation_guardsr  râ   rš   r-   ÚuuidÚuuid4ÚhexÚrevisionÚexecution_generationr   r’   rj   )r   r/   r   r  rw   rV   r
  r  ÚhandlerÔ   rT   r  s   &&         @r   rç   rç   @  s  øé € ð ×$Ñ$€IÝBÝ<Ü×"Ò" =¸SÓA×A€DÜô _¬H°T¬Nó _Ø`dóf€Fà‚~ÙÝ8ÝDØ×Ñ˜sÓ#€Fð9Ù% i×1AÑ1AÀ3Ø˜#Ÿ.™.¨,¸)ÄDÇJÂJÃL×DTÑDTÐCUÐ8VØ §¡Ð2GÈ×IdÑIdØ˜ 9Ð/BÀFÐ.KðIMó N÷ Nˆô ˆv�z‰z˜/Ó*×/Ð/¨aÓ0Ð0ñ BñNøð #ô 9Ü Ó/°SÐ8ûð9üsM   ƒ3D)¶D
·AD)Á>A#D Ã!DÃ"D Ã&D)ÄD)ÄD ÄD&ÄD!Ä!D&Ä&D)>   r    r5   r-   >   r£   r    r5   r¢   r-   i  @ ) Ú__doc__rZ   r   r@   rù   r  Ú	functoolsr   Úpathlibr   Úgateway.session_busy_controlsr   Úgateway.session_tui_readsr   Úhermes_state_runtimer   r   r!   r(   r3   r   r   r   r   r   rÞ   rí   r   rÍ   rî   rì   rç   rÄ   r   r   Ú<module>r$     sª   ðñ	ó Ý Û Û 	Û Ý Ý å 3Ý 7Ý 2ò
Eòòaò
9ò*ò:_òD)ò=òB0ð6 ˜\¨9Ð5°vÒ?`ØÒTØ" \°9Ð$=ð?Ð ð &Ð òMò`VòZò
,ô1r   