+
    iHàj  ã                  óX  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIH	t	H
t
 ^ RIHt ^ RIHtHtHtHtHtHtHtHtHt ^ RIHt ]P2                  ! ]4      tRt. tR]R	&   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t%R R lt&R R lt'R R lt(R R lt)R  R! lt*R# )"a«  Where a first-run onboarding run lives: one ``onboarding_run`` key in the session's
``sessions.model_config`` (no schema change; a compression rotation carries it, see
``hermes_state_compression._CONVERSATION_MODEL_CONFIG_KEYS``).

``advance`` is the one writer after ``start``: load, ``onboarding_flow.apply``, save, and when the
run ends write the install-level flag in the root config so the next launch does not reopen it.
)ÚannotationsN)ÚCallableÚMapping)ÚAny)	ÚAppliedÚEndÚEventÚFactsÚStepÚ
applies_toÚapplyÚ	is_activeÚ
new_record)ÚreminderÚonboarding_runzlist[Callable[[dict], None]]Ú_ended_listenersc               ó    € V ^8„  d   QhRRRR/# )é   ÚlistenerzCallable[[dict], None]ÚreturnÚNone© )Úformats   "Ú</home/ubuntu/.hermes/hermes-agent/agent/onboarding_record.pyÚ__annotate__r       s   € ÷ &ñ &Ð-ð &°$ñ &ó    c                ó0   € \         P                  V 4       R # ©N)r   Úappend)r   s   &r   Úon_endedr       s   € Ü×Ñ˜HÖ%r   c               ó    € V ^8„  d   QhRRRR/# )r   Ú
session_idÚstrr   zdict | Noner   )r   s   "r   r   r   $   s   € ÷ 8ñ 8˜ð 8 ñ 8r   c                ó~   € V e   V'       d   V P                  V\        4      MR p\        V\        4      '       d   V# R # r   )Úget_session_model_config_valueÚKEYÚ
isinstanceÚdict)Údbr!   Úrecords   && r   Úloadr*   $   s5   € ØCEÂ>×V`ˆR×.Ñ.¨z¼3Ô?Ðfj€FÜ ¬×-Ò-ˆ6Ð7°4Ð7r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úrun_idú
str | Noner!   r"   Úoutcomer   r   r   )r   s   "r   r   r   )   s(   € ÷ ñ �jð ¨cð ¸Cð ÀDñ r   c                óT   € R T ;'       g    RRVRV/p\          F  pV! V4       K  	  R# )r,   Ú Ústored_session_idr.   N)r   )r,   r!   r.   Úendedr   s   &&&  r   Ú	_announcer3   )   s-   € Ø�v—|�| Ð%8¸*ÀiÐQXÐY€Eß$ˆÙ�Žó %r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r!   r"   Úeventr   r   zStep | Noner   )r   s   "r   r   r   /   s!   € ÷ ñ  ð ¨Eð °kñ r   c                ó¦  aa€ / oR VV3R llpV P                  V\        V4       SP                  R4      pVea   SR,          '       dR   \        VP                  4      '       g7   \        VP                  P                  R4      WP                  R,          4       Ve3   \        VP                  4      '       g   \        V 4      f   \        4        V# )aØ  Apply *event* and write the result in one database transaction at the compression tip, so Skip
setup pressed while a card answer is being applied is never overwritten by the older copy, and an id
read before a rotation published still lands on the copy the chat reads. An ended run then closes the
install flag (a Skip or Done retried after a failed config write repairs it), unless another run
is still open: the flag belongs to that run, and an old chat must not end it.c               ó    € V ^8„  d   QhRRRR/# ©r   Úcurrentr   r   r   )r   s   "r   r   Ú!_transition.<locals>.__annotate__7   s   € ÷ %ñ %˜ð % ñ %r   c                ó  <€ SP                  4        \        V \        4      '       g   V # \        V 4      SR &   \	        V S\
        P                  ! V R,          4      \        P                  ! 4       R7      SR&   SR,          P                  # )Ú
was_activeÚfacts©ÚnowÚstep)	Úclearr&   r'   r   r   r	   Úfrom_storedÚtimer)   )r9   r5   Úholders   &€€r   ÚupdateÚ_transition.<locals>.update7   sk   ø€ Ø�‰ŒÜ˜'¤4×(Ò(ØˆNÜ(¨Ó1ˆˆ|ÑÜ˜w¨¬u×/@Ò/@ÀÈÕAQÓ/RÔX\×XaÒXaÓXcÔdˆˆv‰Ø�f�~×$Ñ$Ð$r   r@   r<   r,   Úended_by)Ú&update_conversation_model_config_valuer%   Úgetr   r)   r3   Úactive_session_idÚ_close_install_flag)r(   r!   r5   rE   r@   rD   s   &&f  @r   Ú_transitionrL   /   sž   ù€ ð  €F÷%ñ %ð ×-Ñ-¨j¼#¸vÔFØ�:‰:�fÓ€DàÒ˜F <×0Ô0¼À4Ç;Á;×9OÒ9OÜ�$—+‘+—/‘/ (Ó+¨Z¿¹ÀZÕ9PÔQØÒ¤	¨$¯+©+× 6Ò 6Ô;LÈRÓ;PÒ;XÜÔØ€Kr   c               ó   € V ^8„  d   QhRR/# )r   r   r   r   )r   s   "r   r   r   I   s   € ÷ 2ñ 2˜Tñ 2r   c                 ó¢  € ^ RI Hp  ^ RIHp ^ RIHp ^ RIHp V P                  V! 4       R,          4      P                  R4      p\        V\        4      '       d   TM/ p\        VP                  R4      \        4      '       d   VP                  R4      M/ pVP                  R4      R	Jg   VP                  V4      '       g   V! R	R
R7       R# R# )é    )Úconfig©Úset_run)Úget_default_hermes_root)ÚPROFILE_BUILD_FLAGzconfig.yamlÚ
onboardingÚseenÚrunFT)Úmark_profile_offeredN)Ú
hermes_clirP   Úhermes_cli.onboarding_runrR   Úhermes_constantsrS   Úagent.onboardingrT   Úread_user_config_rawrI   r&   r'   )Ú
config_modrR   rS   rT   ÚsectionrV   s         r   rK   rK   I   s›   € Ý/Ý1Ý8å3à×-Ñ-Ñ.EÓ.GÈ-Õ.WÓX×\Ñ\Ð]iÓj€GÜ# G¬T×2Ò2‰g¸€GÜ",¨W¯[©[¸Ó-@Ä$×"GÒ"Gˆ7�;‰;�vÔÈR€DØ‡{�{�5Ó Ó&¨d¯h©hÐ7I×.JÒ.JÙ�¨D×1ñ /K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   W   s!   € ÷ 	ñ 	˜#ð 	 eð 	°ñ 	r   c                óÎ   € ^ RI Hp \        V\        P                  ! 4       \        P
                  ! 4       P                  R7      pV P                  V\        V/4       V! R4       V# )zãWrite a fresh run record (the row must exist) and mark the install as mid-onboarding, so a
crash or a quit before the end runs onboarding again on the next launch (which starts over:
``onboarding.start`` with ``fresh_launch``).rQ   )r?   r,   T)	rZ   rR   r   rC   ÚuuidÚuuid4ÚhexÚpatch_session_model_configr%   )r(   r!   r=   rR   r)   s   &&&  r   Ústartrf   W   sG   € õ 2ä˜¤4§9¢9£;´t·z²z³|×7GÑ7GÔH€FØ×!Ñ! *¬s°F¨mÔ<ÙˆD„MØ€Mr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r!   r"   r5   r   r   r
   r   )r   s   "r   r   r   c   s!   € ÷ ñ ˜Cð ¨ð °$ñ r   c                ó`   € V e   V'       d   \        WV4      MRpVf   \        RV R24      hV# )zLApply one event to the stored run; LookupError when this session has no run.Nzsession z has no onboarding run)rL   ÚLookupError)r(   r!   r5   r@   s   &&& r   Úadvancerj   c   s6   € à13²ÇJŒ;�r uÔ-ÐTX€DØ‚|Ü˜H Z LÐ0FÐGÓHÐHØ€Kr   c               ó   € V ^8„  d   QhRR/# )r   r   z	list[str]r   )r   s   "r   r   r   k   s   € ÷ ñ ˜Iñ r   c                ó  € \        4       p. pV P                  \        4       Fd  pV P                  V4      ;'       g    TpWA9  g   K&  VP	                  V4       \        \        W4      4      '       g   KS  VP                  V4       Kf  	  V# )z�The chats whose run is still in progress, newest first. Rotation leaves the active copy on the
compression parent, so each id is read at its compression tip.)ÚsetÚ!session_ids_with_model_config_keyr%   Úresolve_resume_session_idÚaddr   r*   r   )r(   ÚtipsÚopen_idsÚsidÚtips   &    r   Úopen_session_idsru   k   so   € ô “U€DØ€HØ×3Ñ3´CÖ8ˆØ×*Ñ*¨3Ó/×6Ð6°3ˆØŽ?Ø�H‰H�SŒMÜœ˜b›×'Ô'Ø—‘ Ö$ñ 9ð €Or   c               ó   € V ^8„  d   QhRR/# )r   r   r-   r   )r   s   "r   r   r   y   s   € ÷ 2ñ 2˜Zñ 2r   c                ó>   € \        \        \        V 4      4      R 4      # r   )ÚnextÚiterru   )r(   s   &r   rJ   rJ   y   s   € Ü”Ô% bÓ)Ó*¨DÓ1Ð1r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r!   r"   ÚdeletezCallable[[], bool]r   Úboolr   )r   s   "r   r   r   }   s"   € ÷ ñ  ð Ð-?ð ÀDñ r   c                óP  a€ ^ RI Hp \        V S4      p\        V4      ;'       d    V P	                  S4      ;'       g    SS8H  pT;'       dM    \
        ;QJ d(    V3R l\        V 4       4       F  '       d   K   RM	  RM! V3R l\        V 4       4       4      pV'       d   \        4        Rp V! 4       pV'       d   V'       g	   V! R4       T'       g   R# T'       d§   TP                  R4      '       d   T P                  \        4      MR FX  p\        Y4      ;p	;'       g    / P                  R4      TR,          8X  g   K7  T P                  T\        \        T	4      /4       KZ  	  \        TP                  R4      SR4       R#   T'       d   T'       g
   T! R4       i i i ; i)a|  Run *delete*; when it removed the chat holding the live run, end that run (``deleted``) on every
compression copy and tell windows once. Only the compression tip holds the live run, so deleting an
older copy ends nothing. The install flag closes before the delete when no other run is open: a
failed flag write keeps the chat for a retry, and a refused delete sets the flag again.rQ   c              3  ó,   <"  € T F	  qS8H  x € K  	  R # 5ir   r   )Ú.0rs   r!   s   & €r   Ú	<genexpr>Údelete_chat.<locals>.<genexpr>†   s   øé € ÐJÑ5I¨c˜zÖ)Ó5Iùs   ƒFTr,   Údeletedr   )rZ   rR   r*   r   ro   Úallru   rK   rI   rn   r%   re   Ú_end_deletedr3   )
r(   r!   r{   rR   r)   ÚliveÚlastr‚   rs   Úolders
   &f&       r   Údelete_chatrˆ   }   sD  ø€ õ
 2ä�"�jÓ!€FÜ�VÓ×gÐg "×">Ñ">¸zÓ"J×"XÐ"XÈjÐ]gÑ!g€DØ×JÐJ—C“CÔJÔ5EÀbÔ5IÓJ—C—C’CÔJÔ5EÀbÔ5IÓJÓJ€DßÜÔØ€GðÙ“(ˆçŸÙ�DŒMßÙßð AGÇ
Á
È8×@TÒ@T�2×7Ñ7¼Ô<ÐZ\Ò\ˆCÜ˜r›-Ð'�×.Ð.¨B×3Ñ3°HÓ=ÀÈÕAQÖQØ×-Ñ-¨c´C¼ÀeÓ9LÐ3MÖNñ ]ô 	�&—*‘*˜XÓ&¨
°IÔ>Ùø÷ ŸÙ�D�Mð  ˆ4ús   Â0F	 Æ	F%ÆF%c               ó    € V ^8„  d   QhRRRR/# r8   r   )r   s   "r   r   r   ›   s   € ÷ gñ g˜#ð g #ñ gr   c                óÈ   € \        V 4      '       g   V # \        V \        R 4      \        P                  ! V R,          4      \
        P
                  ! 4       R7      P                  # )r‚   r=   r>   )r   r   r   r	   rB   rC   r)   )r9   s   &r   r„   r„   ›   sG   € Ü�W×ÒØˆÜ�œ#˜i›.¬%×*;Ò*;¸GÀGÕ<LÓ*MÔSW×S\ÒS\ÓS^Ô_×fÑfÐfr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Únamer"   ÚargszMapping[str, Any]Úresultr   r   r   )r   s   "r   r   r   ¡   s*   € ÷ ñ  Sð Ð0Að È3ð ÐSVñ r   c                óú  € \        V4      '       d   R\        V RR4      ;'       g    R9  d   V# \        V RR4      \        V RR4      ;'       g    RrT \        V\        4      '       d   \        P
                  ! V4      MTp\        V\        4      '       dº   \        WE4      e­   \        YE\        T\        T;'       g    / 4      V4      4      p\        VP                  VP                  \        P                  ! VP                  R,          4      4      pV'       d5   \        V\        4      '       d   \        P                  ! / VCRV/CR	R
7      # V#   \         d    \         P#                  RTRR7        T# i ; i)a$  Settle a beat from a general tool's result (``set_theme``, ``manage_connections`` display,
``gui_tour``). Runs for every tool result; only an onboarding chat (one whose agent carries
``setup_beat``) reads its record. Returns *result*, with the next-step reminder added when it
settled a beat.Ú
setup_beatÚvalid_tool_namesNÚ_session_dbr!   r0   r=   r   F)Úensure_asciiz3onboarding: %s result did not update the run recordT)Úexc_infor   )r   Úgetattrr&   r"   ÚjsonÚloadsr'   r*   rj   r   r   r)   r	   rB   ÚdumpsÚ	ExceptionÚloggerÚwarning)	ÚagentrŒ   r�   rŽ   r(   r!   Úparsedr@   Útexts	   &&&&     r   Úobserve_tool_resultrŸ   ¡   s6  € ô
 �d×Ò˜|´G¸EÐCUÐW[Ó4\×4bÐ4bÐ`bÔcØˆÜ˜U M°4Ó8¼'À%ÈÐWYÓ:Z×:`Ð:`Ð^`ˆ
ðcÜ'1°&¼#×'>Ò'>”—’˜FÔ#ÀFˆÜ�fœd×#Ò#¬¨RÓ(<Ò(HÜ˜2¬7°4¼¸d¿j¸jÀbÓ9IÈ6Ó+RÓSˆDÜ˜DŸM™M¨4¯;©;¼×8IÒ8IÈ$Ï+É+ÐV]ÕJ^Ó8_Ó`ˆDßœ
 6¬3×/Ò/Ü—z’zÐ"> VÐ">¨Z¸Ñ">ÈUÔSÐSð €Møô ô cÜ�‰ÐLÈdÐ]aˆÕbØ€Mðcús   ÁC<E Å#E:Å9E:)+Ú__conditional_annotations__Ú__doc__Ú
__future__r   r–   ÚloggingrC   rb   Úcollections.abcr   r   Útypingr   Úagent.onboarding_flowr   r   r   r	   r
   r   r   r   r   Úagent.onboarding_textr   Ú	getLoggerÚ__name__rš   r%   r   Ú__annotations__r   r*   r3   rL   rK   rf   rj   ru   rJ   rˆ   r„   rŸ   )r    s   @r   Ú<module>r«      s–   øðôõ #ã Û Û Û ß -Ý ÷÷ õ õ +à	×	Ò	˜8Ó	$€à€ð 24Ð Ð.Ó 3õ&õ8õ
õõ42õ	õõõ2õõ<g÷r   