Ë
    âß²j�   ã                  ó”   — d Z ddlmZ ddlmZ ddlmZmZmZm	Z	 dZ
 G d„ de«      Ze G d„ d	«      «       Zdd
„Zdd„Z G d„ d«      Zy)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                  ó   — e Zd ZdZy)Ú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__Ú__doc__© ó    ú8/home/ubuntu/.hermes/hermes-agent/hermes_state_rewind.pyr
   r
      s   „ ò`r   r
   c                  ó@   — e Zd ZU ded<   ded<   ded<   ded<   ded	<   y
)ÚRewindOutcomeúList[Dict[str, Any]]ÚprefixúDict[str, Any]Ú	live_viewÚstrÚ	live_textÚintÚrewound_countÚturns_undoneN)r   r   r   Ú__annotations__r   r   r   r   r      s   … à Ó ØÓØƒNØÓØÔr   r   c                óh   — ddl m} t        | «      D ��cg c]  \  }} ||«      €Œ|‘Œ c}}S c c}}w )Nr   )Úuser_originated_turn_view)Úagent.context_compressorr   Ú	enumerate)Úmessagesr   ÚiÚms       r   Ú_user_indicesr%      s-   € ÝBÜ# HÓ-×Z‘$�!�QÑ1JÈ1Ó1MÑ1YŠAÓZÐZùÓZs   •.¦.c                ó†   — ddl m} ddlm} |j	                  | j                  d«       || j                  d«      «      «      S )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.r   )Ú_durable_content)ÚSessionMessagesMixinÚroleÚcontent)Úagent.session_persistencer'   Úhermes_state_messagesr(   Ú_loaded_view_contentÚget)Úmessager'   r(   s      r   Ú_comparison_contentr0   "   s9   € õ ;Ý:Ø×4Ñ4°W·[±[ÀÓ5HÑJZÐ[b×[fÑ[fÐgpÓ[qÓJrÓsÐsr   c                  ó>   — e Zd ZdZdddddœ	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zy)ÚSessionRewindMixinz_``SessionDB`` mixin: soft-delete from one user turn onward, validated against the warm history.NF)Úwarm_historyÚrequire_retryableÚrequire_compositeÚadopt_row_idsc               ó6  ‡#‡$— ddl m}m}m}	m}
mŠ$ ddlm} ddlm	} | j                  |«      }| j                  |d¬«      }| j                  |dd¬«      }t        |«      }|dk  rt        t        |«      |z   d«      }|t        |«      k\  rt        d«      ‚||   }||   } |||«      \  }} |
|«      \  }}|r|€t        d
«      ‚|}|�~|D �cg c]  } ||«      rŒ|‘Œ }}t        |«      }t        |«      t        |«      k7  rt!        t"        «      ‚ ||||   «      \  }}t%        |«      t%        |«      k7  rt!        t"        «      ‚|r |	|j'                  d«      «      nd	}|j'                  d«      Š#t)        ‰#t*        «      st!        d«      ‚t-        ˆ#ˆ$fd„|D «       d	«      }|€t!        t"        «      ‚	 | j/                  |‰#|d	u||j'                  d«      ¬«      }|�N|j'                  d«      } t)        | t*        «      r|st!        d«      ‚|d   j5                  d| |di«       |d   |d<   |rr||urnt        |«      t        |«      k(  rWt7        d„ t9        ||«      D «       «      r;t9        ||«      D ],  \  }}!t)        |!j'                  d«      x}"t*        «      sŒ(|"|d<   Œ. t;        |||�|n ||j'                  d«      «      t+        |j'                  dd«      «      t        |«      |z
  ¬«      S c c}w # t0        $ r}t        t3        |«      «      |‚d	}~ww xY w)aš  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`.r   )Ú_DB_PERSISTED_MARKERÚ#history_before_user_originated_turnÚretryable_user_textÚsplit_user_originated_turnr   )Úflatten_message_text)Ú_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*   Ú_row_idz)rewind target has no durable row identityc              3  óX   •K  — | ]!  }|j                  d «      ‰k(  sŒ ‰|«      –— Œ# y­w)r@   N)r.   )Ú.0r$   Útarget_row_idr   s     €€r   ú	<genexpr>z6SessionRewindMixin.rewind_user_turn.<locals>.<genexpr>e   s(   øè ø€ Ò_¨a¸Q¿U¹UÀ9Ó=MÐQ^Ó=^Ñ& q×)Ñ_ùs   ƒ*�*)Úpreserve_compaction_handoffÚexpected_active_idsÚexpected_target_contentÚreplacement_message_idz,rewind did not retain its compaction handofféÿÿÿÿc              3  ó  K  — | ]z  \  }}|j                  d «      |j                  d «      k(  xrN t        |j                  d«      «      t        |j                  d«      «      k(  xr t        |«      t        |«      k(  –— Œ| y­w)r)   Údisplay_kindN)r.   Úboolr0   )rB   ÚwarmÚdurable_messages      r   rD   z6SessionRewindMixin.rewind_user_turn.<locals>.<genexpr>t   s„   è ø€ ò i
ñ &��oð �H‰H�VÓ × 3Ñ 3°FÓ ;Ñ;ò RÜ�T—X‘X˜nÓ-Ó.´$°×7JÑ7JÈ>Ó7ZÓ2[Ñ[òRä# DÓ)Ô-@ÀÓ-QÑQóRñi
ùs   ‚B Br   )r   r   r   r   r   )r    r8   r9   r:   r;   r   Úagent.message_contentr<   r+   r=   Úget_active_message_idsÚget_messages_as_conversationr%   ÚmaxÚlenr
   ÚRuntimeErrorÚ_HISTORY_CHANGEDr0   r.   Ú
isinstancer   ÚnextÚrewind_to_messageÚ
ValueErrorr   ÚupdateÚallÚzipr   )%ÚselfÚ
session_idÚuser_ordinalr3   r4   r5   r6   r8   r9   r:   r;   r<   r=   rF   ÚstoredÚdurableÚdurable_userÚtarget_indexÚtargetÚdurable_prefixr   ÚscaffoldÚ_r   r$   rM   Ú	warm_userÚwarm_live_viewr   Ústored_viewÚresultÚexcÚreplacement_idrN   Úrow_idrC   r   s%                                      @@r   Úrewind_user_turnz#SessionRewindMixin.rewind_user_turn-   sa  ù€ ÷	Cõ 	Cõ 	?ÝGà"×9Ñ9¸*ÓEÐØ×2Ñ2°:ÈtÐ2ÓTˆð
 ×3Ñ3°JÐPTÐimÐ3ÓnˆÜ$ WÓ-ˆØ˜!ÒÜœs <Ó0°<Ñ?ÀÓCˆLØœ3˜|Ó,Ò,Ü.Ð/dÓeÐeØ# LÑ1ˆØ˜Ñ&ˆÙ$GÈÐQ]Ó$^Ñ!ˆ˜	Ù0°Ó8‰ˆ�!Ù Ð!1Ü.Ð/`ÓaÐaàˆØÐ#Ø+ÖP˜!Ñ3LÈQÕ3O’AÐPˆ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ð	BØ×+Ñ+Ø˜MÀxÐW[ÐG[Ø$7ÐQ\×Q`ÑQ`ÐajÓQkð ,ó mˆFð
 ÐØ#ŸZ™ZÐ(@ÓAˆNÜ˜n¬cÔ2¹.Ü"Ð#QÓRÐRØ˜2Ñ×%Ñ% y°.ÐBVÐX\Ð&]Ô^Ø'¨Ñ+ˆF�2‰JÙ˜V¨>Ñ9¼cÀ&»kÌSÐQ_ÓM`Ò>`Ôehñ i
ô *-¨V°^Ó)Dô	i
ô f
ô *-¨V°^Ó)Dò -Ñ%��oÜ¨×(;Ñ(;¸IÓ(FÐF˜fÌÕLØ&,�D˜’Oð-ô Ø YØ#,Ð#8‘iÑ>RÐS\×S`ÑS`ÐajÓSkÓ>lÜ˜fŸj™j¨¸!Ó<Ó=ÌCÐP\ÓL]Ð`lÑLlônð 	nùòS Qøô. ò 	BÜ.¬s°3«xÓ8¸cÐAûð	Bús$   ÃK0ÃK0Æ7'K5 Ë5	LË>LÌL)r^   r   r_   r   r3   zOptional[List[Dict[str, Any]]]r4   rL   r5   rL   r6   rL   Úreturnr   )r   r   r   r   ro   r   r   r   r2   r2   *   sc   „ Ùið eiØ"'À5Ð`eñTnØðTnØ-0ðTnØCaðTnàðTnà<@ðTnàY]ðTnð 
ôTnr   r2   N)r"   r   rp   z	List[int])r/   r   rp   r   )r   Ú
__future__r   Údataclassesr   Útypingr   r   r   r   rU   rY   r
   r   r%   r0   r2   r   r   r   ú<module>rt      s`   ðñ[õ
 #å !ß ,Ó ,àQÐ ô` :ô `ð ÷ð ó ðó[ó
t÷Wnò Wnr   