+
    „WÝj)  ã                  ó¼   € R t ^ RIHt ^ RIHt ^ RIHtHtHtH	t	 Rt
 ! R R]4      t] ! R R4      4       t] ! R	 R
4      4       tR R ltR R lt ! R R4      tR# )u…  Carrier-aware user-turn rewind (``/undo``, ``/retry``) â€” the ONE implementation behind the CLI, the
gateway and the TUI. Rewind is a persisted-history operation: the durable transcript is the authority,
the warm (in-memory) history only has to agree with it. A composite compaction carrier (retained
summary + live human ask in one row) keeps its hidden handoff scaffold as the new head.)Úannotations)Ú	dataclass)ÚAnyÚDictÚListÚOptionalz<session history changed before the rewind could be persistedc                  ó   € ] tR t^tRtRtR# )ÚRewindTargetUnavailableErrora  The requested user turn is not a rewindable target of the active transcript: no user turns, an
ordinal past the newest one, a row that is not user-originated, or a plain turn where the caller
required a compaction carrier. Surfaces map this to their own "nothing to undo" message.© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__static_attributes__r
   ó    ÚGC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_state_rewind.pyr	   r	      s   † õ`r   r	   c                  ó|   € ] tR t^t$ R]R&   R]R&   R]R&   R]R&   R	]R
&   R	]R&   R]R&   R]R&   R]R&   R]R&   RtR# )Ú
RewindPlanÚintÚtarget_row_idú	list[int]Úexpected_active_idsr   Úexpected_target_contentzOptional[dict[str, Any]]Úscaffoldúlist[dict[str, Any]]ÚprefixÚdurable_prefixúdict[str, Any]Ú	live_viewzOptional[str]Ú	live_textÚdurable_userÚuser_ordinalr
   N©r   r   r   r   Ú__annotations__r   r
   r   r   r   r      s>   ‡ àÓØ"Ó"Ø Ó Ø&Ó&Ø Ó Ø(Ó(ØÓØÓØÓØ×r   r   c                  óJ   € ] tR t^"t$ R]R&   R]R&   R]R&   R]R&   R]R	&   R
tR# )ÚRewindOutcomer   r   r   r   Ústrr    r   Úrewound_countÚturns_undoner
   Nr#   r
   r   r   r&   r&   "   s   ‡ à Ó ØÓØƒNØÓØ×r   r&   c               ó    € V ^8„  d   QhRRRR/# )é   Úmessagesr   Úreturnr   r
   )Úformats   "r   Ú__annotate__r/   +   s   € ÷ [ñ [Ð0ð [°Yñ [r   c                óp   € ^ RI Hp \        V 4       UUu. uF  w  r#V! V4      f   K  VNK  	  upp# u uppi )é    )Úuser_originated_turn_view)Úagent.context_compressorr2   Ú	enumerate)r,   r2   ÚiÚms   &   r   Ú_user_indicesr7   +   s0   € ÝBÜ# HÔ-ÔZÑ-‘$�!Ñ1JÈ1Ó1M�AˆAÑ-ÒZÐZùÓZs   •2¨2c               ó    € V ^8„  d   QhRRRR/# )r+   Úmessager   r-   r   r
   )r.   s   "r   r/   r/   0   s   € ÷ tñ t ð t°Cñ tr   c                ó†   € ^ RI Hp ^ RIHp VP	                  V P                  R4      V! V P                  R4      4      4      # )z“Project content the way the durable row stores it (flush projection, then the read-side sanitize) so a
warm row and its durable twin compare equal.)Ú_durable_content)ÚSessionMessagesMixinÚroleÚcontent)Úagent.session_persistencer;   Úhermes_state_messagesr<   Ú_loaded_view_contentÚget)r9   r;   r<   s   &  r   Ú_comparison_contentrC   0   s9   € õ ;Ý:Ø×4Ñ4°W·[±[ÀÓ5HÑJZÐ[b×[fÑ[fÐgpÓ[qÓJrÓsÐsr   c                  óV   € ] tR t^8tRtRRRRRRRR/R R	 lltRRRRRR/R
 R lltRtR# )ÚSessionRewindMixinz_``SessionDB`` mixin: soft-delete from one user turn onward, validated against the warm history.Úwarm_historyNÚrequire_retryableFÚrequire_compositeÚadopt_row_idsc               ó4   € V ^8„  d   QhRRRRRRRRR	RR
RRR/# )r+   Ú
session_idr'   r"   r   rF   úOptional[list[dict[str, Any]]]rG   ÚboolrH   rI   r-   r&   r
   )r.   s   "r   r/   ÚSessionRewindMixin.__annotate__;   sO   € ÷ 4nñ 4nØð4nØ-0ð4nØCað4nàð4nà<@ð4nàY]ð4nð 
ñ4nr   c               ó  € ^ RI Hp ^ RIHp ^ RIHp	Hp
 V P                  WVWER7      pVP                  VP                  VP                  VP                  VP                  VP                  VP                  3w  rÍrïppp V P                  WP                   VRJVP"                  VP$                  R7      pTeˆ   TP-                  R4      p\/        T\0        4      '       d	   T'       g   \3        R4      hTR,          P5                  R	TTR
/4       TP-                  R4      ;p'       d   TTR,          T	&   TR,          TR&   T'       dÃ   YÍJd¾   \7        T4      \7        T4      8X  d¥   \8        ;QJ d%    R \;        YÍ4       4       F  '       d   K   RM	  R
M! R \;        YÍ4       4       4      '       dY   \;        YÍ4       FI  w  pp\/        TP-                  R	4      ;p\0        4      '       d   TTR	&   T
! T4      ;p'       g   KD  TTT	&   KK  	  \=        YÎTe   TMT! TP-                  R4      4      \1        TP-                  R^ 4      4      \7        T4      T,
          R7      #   \&         d   p\)        \+        T4      4      ThRp?ii ; i)aZ  Rewind the active transcript to just before user turn ``user_ordinal`` (0 = oldest; negative counts
back from the newest and clamps to the oldest, so ``-n`` is ``/undo n``). ``warm_history`` (CLI/TUI):
the in-memory view must have the same user turns and the same live target text as the durable
transcript, else ``RuntimeError`` and nothing changes; its (richer) prefix is what gets installed.
``require_retryable``: the live payload must be losslessly replayable as text (``ValueError`` from
:func:`retryable_user_text` before any write). ``require_composite``: the target must be a compaction
carrier. ``adopt_row_ids`` (TUI): copy durable ``_row_id`` identities onto the installed warm prefix so
clients can address follow-ups by row; the CLI leaves its history shape alone. Out-of-range /
wrong-shape targets raise :class:`RewindTargetUnavailableError`.)Ú_DB_PERSISTED_MARKER)Úflatten_message_text)ÚMESSAGE_UIDÚmessage_uid_or_none)rF   rG   rH   N)Úpreserve_compaction_handoffr   r   Úreplacement_message_idz,rewind did not retain its compaction handoffÚ_row_idTÚreplacement_message_uidc              3  ó$  "  € T F†  w  rVP                  R 4      VP                  R 4      8H  ;'       dU    \        VP                  R4      4      \        VP                  R4      4      8H  ;'       d    \        V4      \        V4      8H  x € Kˆ  	  R# 5i)r=   Údisplay_kindN)rB   rM   rC   )Ú.0ÚwarmÚdurable_messages   &  r   Ú	<genexpr>Ú6SessionRewindMixin.rewind_user_turn.<locals>.<genexpr>`   s‘   é € ð i
ñ *EÑ%�ð �H‰H�VÓ × 3Ñ 3°FÓ ;Ñ;÷ Rð RÜ�T—X‘X˜nÓ-Ó.´$°×7JÑ7JÈ>Ó7ZÓ2[Ñ[÷Rð Rä# DÓ)Ô-@ÀÓ-QÑQôRó *Eùs   ‚0B³<BÁ0 BFr>   r(   )r   r   r    r(   r)   éÿÿÿÿ)r3   rP   Úagent.message_contentrQ   Úagent.message_metadatarR   rS   Úplan_user_turn_rewindr   r   r   r    r   r!   r"   Úrewind_to_messager   r   r   Ú
ValueErrorr	   r'   rB   Ú
isinstancer   ÚRuntimeErrorÚupdateÚlenÚallÚzipr&   )ÚselfrK   r"   rF   rG   rH   rI   rP   rQ   rR   rS   Úplanr   r   r   r    r   r!   ÚresultÚexcÚreplacement_idÚreplacement_uidr[   r\   Úrow_idÚuids   &&&$$$$                   r   Úrewind_user_turnÚ#SessionRewindMixin.rewind_user_turn;   sk  € õ 	BÝ>ßKà×)Ñ)¨*ÐQ]Ø<Mð *ó tˆð Ÿ+™+ t×':Ñ':¸D¿N¹NÈDÏNÉNÐ\`×\iÑ\iØ×+Ñ+¨T×->Ñ->ð@ñ	ˆ °xÀØ	ð	BØ×+Ñ+Ø×.Ñ.ÈHÐ\`ÐL`Ø$(×$<Ñ$<ÐVZ×VrÑVrð ,ó tˆFð
 ÒØ#ŸZ™ZÐ(@ÓAˆNÜ˜n¬c×2Ò2¿.Ü"Ð#QÓRÐRà˜2Õ×%Ñ% y°.ÐBVÐX\Ð&]Ô^Ø"(§*¡*Ð-FÓ"GÐGˆÖGØ2A�˜rÕ" ;Ñ/Ø'¨Õ+ˆF�2‰Jß˜VÓ9¼cÀ&»kÌSÐQ_ÓM`Ô>`×ehÓehñ i
ô *-¨VÔ)Dó	i
×eh×ehÒehñ i
ô *-¨VÔ)Dó	i
÷ f
ò f
ô *-¨VÖ)DÑ%��oÜ¨×(;Ñ(;¸IÓ(FÐF˜fÌ×LÒLØ&,�D˜‘OÙ-¨oÓ>Ð>�3×>Ð>Ø(+�D˜Ó%ñ	 *Eô
 ØØ#,Ò#8‘iÑ>RÐS\×S`ÑS`ÐajÓSkÓ>lÜ˜fŸj™j¨¸!Ó<Ó=ÌCÐP\ÓL]Ð`lÕLlônð 	nøô/ ô 	BÜ.¬s°3«xÓ8¸cÐAûð	Bús   Á?5I ÉJÉ'I<É<Jc               ó0   € V ^8„  d   QhRRRRRRRRR	RR
R/# )r+   rK   r'   r"   r   rF   rL   rG   rM   rH   r-   r   r
   )r.   s   "r   r/   rN   q   s>   € ÷ 8'ñ 8'Øð8'Ø-0ð8'ØCað8'àð8'à<@ð8'ð 
ñ8'r   c               ó  aa€ ^ RI HpHpHpHo ^ RIHp	 V P                  V4      p
V P                  VRR7      pV P                  VRRR7      p\        V4      pV^ 8  d   \        \        V4      V,           ^ 4      pV\        V4      8¼  d   \        R4      hWÒ,          pWÎ,          pV! WÎ4      w  ppV! V4      w  ppV'       d   Vf   \        R4      hTpVe�   V Uu. uF  pV	! V4      '       d   K  VNK  	  pp\        V4      p\        V4      \        V4      8w  d   \        \        4      hV! VVV,          4      w  pp\        V4      \        V4      8w  d   \        \        4      hV'       d   V! VP!                  R	4      4      MRpVP!                  R
4      o\#        S\$        4      '       g   \        R4      h\'        VV3R lV 4       R4      pVf   \        \        4      h\)        SV
VP!                  R	4      VVVVVVVR7
      # u upi )a  Every read and check :meth:`rewind_user_turn` makes before its write, with no write: the
gateway ``/retry`` commits the planned rewind inside its re-send's admission transaction
(``rewind_in_transaction`` with the plan's pins), so a refused re-send leaves it unapplied.)Ú#history_before_user_originated_turnÚretryable_user_textÚsplit_user_originated_turnr2   )Ú_is_ephemeral_scaffoldingT)Úinclude_row_ids)r{   Úrepair_alternationz3target user message is no longer in session historyNz/target user message is not a compaction carrierr>   rV   z)rewind target has no durable row identityc              3  ób   <"  € T F$  qP                  R 4      S8X  g   K  S! V4      x € K&  	  R# 5i)rV   N)rB   )rZ   r6   r   r2   s   & €€r   r]   Ú;SessionRewindMixin.plan_user_turn_rewind.<locals>.<genexpr>¢   s,   øé € Ð_±6¨a¿U¹UÀ9Ó=MÐQ^Ñ=^Ô)Ñ& q×)Ð)³6ùs   ƒ/Ÿ/)
r   r   r   r   r   r   r   r    r!   r"   )r3   rw   rx   ry   r2   r?   rz   Úget_active_message_idsÚget_messages_as_conversationr7   Úmaxrh   r	   rf   Ú_HISTORY_CHANGEDrC   rB   re   r   Únextr   )rk   rK   r"   rF   rG   rH   rw   rx   ry   rz   r   ÚstoredÚdurabler!   Útarget_indexÚtargetr   r   r   Ú_r   r6   r[   Ú	warm_userÚwarm_live_viewr    Ústored_viewr   r2   s   &&&$$$                     @@r   rb   Ú(SessionRewindMixin.plan_user_turn_rewindq   s  ù€ ÷	Có 	Cõ 	Hà"×9Ñ9¸*ÓEÐØ×2Ñ2°:ÈtÐ2ÓTˆð
 ×3Ñ3°JÐPTÐimÐ3ÓnˆÜ$ WÓ-ˆØ˜!ÔÜœs <Ó0°<Õ?ÀÓCˆLØœ3˜|Ó,Ô,Ü.Ð/dÓeÐeØ#Õ1ˆØÕ&ˆÙ$GÈÓ$^Ñ!ˆ˜	Ù0°Ó8‰ˆ�!ß Ò!1Ü.Ð/`ÓaÐaàˆØÒ#Ù+ÓP™|˜!Ñ3LÈQ×3O—A�A™|ˆDÐPÜ% dÓ+ˆIÜ�9‹~¤ \Ó!2Ô2Ü"Ô#3Ó4Ð4Ù%HÈÈyÐYeÕOfÓ%gÑ"ˆF�NÜ" 9Ó-Ô1DÀ^Ó1TÔTÜ"Ô#3Ó4Ð4÷ FWÑ'¨	¯©°iÓ(@ÔAÐ\`ˆ	ØŸ
™
 9Ó-ˆÜ˜-¬×-Ò-ÜÐJÓKÐKô Ý_±6Ó_ÐaeógˆàÒÜÔ/Ó0Ð0ÜØ'Ð=PØ$/§O¡O°IÓ$>ÈÐZ`Ø)°YÈ)ÐbnØ%ô	'ð 	'ùò' Qs   ÃH	Ã2H	r
   )r   r   r   r   r   rs   rb   r   r
   r   r   rE   rE   8   sR   † Ùið4nØdhð4nà"'ð4nàCHð4nà`e÷4nðl8'Ødhð8'à"'ð8'àCH÷8'ó 8'r   rE   N)r   Ú
__future__r   Údataclassesr   Útypingr   r   r   r   r‚   rd   r	   r   r&   r7   rC   rE   r
   r   r   Ú<module>r�      sw   ðñ[õ
 #å !ß ,Ó ,àQÐ ô` :ô `ð ÷
ð 
ó ð
ð ÷ð ó ðõ[õ
t÷q'ó q'r   