+
    iHàj›  ã                  óØ  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIHt ^ RIH	t	 ^ RI
Ht ^ RIHtHtHt ]	! RRR7      tR	]R
&   ^@t^ t]P(                  ! 4       t]P,                  ! ]4      tRt]! RR7       ! R R4      4       t]! 4       tR]R&   / tR]R&   ]P8                  R R l4       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%]3R& R' llt&R( R) lt'. R*Ot(R# )+az  LSP diagnostics for a write, delivered after the write's tool result instead of inside it.

``write_file`` / ``patch`` return as soon as the bytes are on disk and verified; the language server
check runs on the LSP loop (``agent.lsp.edit_check``).  Its verdict is queued here under the session
that made the edit (bound by ``tools.file_tools`` around the write) and handed to that session's agent
at its next tool result, or its next user turn when no tool runs again
(``agent.plugin_live_notes``: a new row not yet flushed, so no cached byte moves).

A later edit of the same file takes over an undelivered verdict: the newer check diffs against the
older baseline, so an error the first edit introduced is still reported unless the second fixed it.

A verdict must not be lost when the edit was the turn's last tool call (a one-shot ``-q`` run has no
next turn): checks still running are tracked per session (:func:`track_pending`), and before the turn's
final answer is accepted :func:`settle_for_agent` waits for them (bounded) and returns every verdict
still undelivered, which ``agent.turn_stop_gates`` hands to the model as a new message.
)ÚannotationsN)ÚOrderedDict)Ú
ContextVar)Ú	dataclass)ÚAnyÚIteratorÚOptionalÚhermes_lsp_deferred_owner)ÚdefaultzContextVar[Optional[str]]Ú_OWNERg      @T)Úfrozenc                  ó,   € ] tR t^#t$ R]R&   R]R&   RtR# )Ú_NoteÚstrÚtextúOptional[str]Úbaseline_text© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotations__Ú__static_attributes__r   ó    Ú7/home/ubuntu/.hermes/hermes-agent/agent/lsp/deferred.pyr   r   #   s   ‡ à
ƒIØ × r   r   z)OrderedDict[str, OrderedDict[str, _Note]]Ú_QUEUEDzdict[str, set[object]]Ú_PENDINGc               ó    € V ^8„  d   QhRRRR/# )é   Úownerr   ÚreturnzIterator[None]r   )Úformats   "r   Ú__annotate__r#   0   s   € ÷ ñ �mð ¨ñ r   c              #  ó´   "  € \         P                  T ;'       g    R4      p Rx € \         P                  V4       R#   \         P                  T4       i ; i5i)zOAttribute writes in this block to ``owner`` (the session id, else the task id).N)r   ÚsetÚreset©r    Útokens   & r   Ú
bind_ownerr)   /   s;   é € ô �J‰J�u—}�} Ó%€EðÛä�‰�UÖøŒ�‰�UÕüs   ‚ A£> §A¾AÁAc               ó   € V ^8„  d   QhRR/# )r   r!   r   r   )r"   s   "r   r#   r#   9   s   € ÷ ñ �}ñ r   c                 ó*   € \         P                  4       # ©N)r   Úgetr   r   r   Úcurrent_ownerr.   9   s   € Ü�:‰:‹<Ðr   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   r    r   Úpathr   r   r   r!   ÚNoner   )r"   s   "r   r#   r#   =   s/   € ÷ (ñ (�ð (˜3ð ( cð (¸-ð (ÈDñ (r   c                ó  € \         ;_uu_ 4        \        P                  V R4      ;'       g    \        4       pVP                  VR4      pVe.   VP                  V8w  d   VP                   RV 2VP
                  r2\        W#4      WA&   \        V4      \        8”  d   VP                  RR7       K(  V\        V &   \        \        4      \        8”  d   \        P                  RR7       K0   RRR4       R#   + '       g   i     R# ; i)z½Queue ``text`` (a formatted diagnostics block) for ``owner``.  A note still queued for ``path``
(an older check finished while a newer one was starting) is kept in front, with its baseline.Nz

F)Úlast)Ú_LOCKr   Úpopr   r   r   r   ÚlenÚ_MAX_PER_OWNERÚpopitemÚ_MAX_OWNERS)r    r0   r   r   ÚnotesÚolders   &&&&  r   Úpostr<   =   sº   € ÷ 
ŽÜ—‘˜E 4Ó(×9Ð9¬K«MˆØ—	‘	˜$ Ó%ˆØÒ §¡¨tÔ!3Ø%*§Z¡Z L°°T°FÐ";¸U×=PÑ=P�-Ü˜DÓ0ˆ‰Ü�%‹jœ>Ô)Ø�M‰M˜uˆMÖ%ØŒ�‰Ü”'‹lœ[Ô(Ü�O‰O ˆOÖ'ð )÷ 
��Šús   �CC4Ã4D	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r    r   r0   r   r!   zOptional[_Note]r   )r"   s   "r   r#   r#   M   s!   € ÷ 8ñ 8�ð 8 Sð 8¨_ñ 8r   c                óÒ   € V '       g   R# \         ;_uu_ 4        \        P                  V 4      pV'       d   VP                  VR4      MRuuRRR4       #   + '       g   i     R# ; i)a  Withdraw ``owner``'s undelivered note for ``path``: a newer edit of the file supersedes it and
diffs against its ``baseline_text``.  The newer check carries it and hands it back to
:func:`restore` only if it ends with no verdict, so the older errors are not lost.N)r4   r   r-   r5   )r    r0   r:   s   && r   Útaker?   M   s;   € ÷ Ùß	ŽÜ—‘˜EÓ"ˆß(-ˆu�y‰y˜˜tÔ$°4÷ 
��‹ús   ™1AÁA&	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r    r   r0   r   r!   r1   r   )r"   s   "r   r#   r#   X   s!   € ÷ =ñ =�=ð =¨ð =°tñ =r   c                ón   € V '       d-   V F$  p\        WVP                  VP                  4       K&  	  R# R# )z?Queue ``notes`` (oldest first) withdrawn by :func:`take` again.N)r<   r   r   )r    r0   r:   Únotes   &&& r   ÚrestorerC   X   s*   € çÛˆDÜ�˜dŸi™i¨×);Ñ);Ö<ó ñ r   c               ó    € V ^8„  d   QhRRRR/# )r   Úownersr   r!   úlist[tuple[str, str]]r   )r"   s   "r   r#   r#   _   s   € ÷ ñ �}ð Ð)>ñ r   c                 ó2  € . p\         ;_uu_ 4        \        P                  R V  4       4       FI  p\        P	                  VR4      pV'       g   K#  VP                  R VP                  4        4       4       KK  	  RRR4       V#   + '       g   i     T# ; i)zKEvery queued ``(path, text)`` for ``owners``, oldest first, and clear them.c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir,   r   ©Ú.0Úos   & r   Ú	<genexpr>Úpop_notes.<locals>.<genexpr>c   s   é € Ð":©f¨»§1¢1«fùs   ‚	�
Nc              3  ó@   "  € T F  w  rWP                   3x € K  	  R # 5ir,   )r   )rJ   r0   rB   s   &  r   rL   rM   f   s   é € ÐM¹}±°˜D§)¡)Õ,»}ùs   ‚)r4   ÚdictÚfromkeysr   r5   ÚextendÚitems)rE   Úoutr    r:   s   *   r   Ú	pop_notesrT   _   sm   € à!#€Cß	ŽÜ—]‘]Ñ":©fÓ":Ö:ˆEÜ—K‘K  tÓ,ˆEß‰uØ—
‘
ÑM¸u¿{¹{¼}ÓMÖMñ ;÷ 
ð
 €J÷ 
Žð
 €Jús   ‘;BÁ*BÂB	c               ó    € V ^8„  d   QhRRRR/# )r   r    r   r!   Úobjectr   )r"   s   "r   r#   r#   j   s   € ÷ ñ ˜ð  ñ r   c                óÊ   € \        4       p\        ;_uu_ 4        \        P                  V \	        4       4      P                  V4       RRR4       V#   + '       g   i     T# ; i)z}Record a check of ``owner``'s still running; pass the token to :func:`settled` once its verdict
has been posted (or dropped).N)rV   r4   r   Ú
setdefaultr%   Úaddr'   s   & r   Útrack_pendingrZ   j   sD   € ô ‹H€Eß	ŽÜ×Ñ˜E¤3£5Ó)×-Ñ-¨eÔ4÷ 
à€L÷ 
Žà€Lús   ™.AÁA"	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r    r   r(   rV   r!   r1   r   )r"   s   "r   r#   r#   s   s!   € ÷ ñ �3ð ˜vð ¨$ñ r   c                óö   € \         ;_uu_ 4        \        P                  V 4      pVe!   VP                  V4       V'       g   \        V  \         P	                  4        R R R 4       R #   + '       g   i     R # ; ir,   )Ú_SETTLEDr   r-   ÚdiscardÚ
notify_all)r    r(   Útokenss   && r   Úsettledra   s   sI   € ß	ŽÜ—‘˜eÓ$ˆØÒØ�N‰N˜5Ô!ßÜ˜U�OÜ×ÑÔ÷ 
��Šús   �2A'ÁA'Á'A8	c               ó    € V ^8„  d   QhRRRR/# )r   Úagentr   r!   ztuple[Optional[str], ...]r   )r"   s   "r   r#   r#   }   s   € ÷ Dñ D�3ð DÐ4ñ Dr   c                óŽ   € \        V R R4      \        V RR4      3p\        ;QJ d    . R V 4       F  NK  	  5# ! R V 4       4      # )Ú
session_idNÚ_current_task_idc              3  óV   "  € T F  p\        V\        4      '       d   TMR x € K!  	  R # 5ir,   )Ú
isinstancer   rI   s   & r   rL   Ú_owners.<locals>.<genexpr>   s!   é € ÐC¹F°q”j ¤C×(Ò(‘¨dÔ2»Fùs   ‚'))ÚgetattrÚtuple)rc   rE   s   & r   Ú_ownersrl   }   sB   € Ü�e˜\¨4Ó0´'¸%ÐASÐUYÓ2ZÐ[€FßŒ5ÑC¹FÓC�5ÐCˆ5ÑC¹FÓCÓCÐCr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rc   r   ÚtimeoutÚfloatr!   rF   r   )r"   s   "r   r#   r#   ‚   s"   € ÷ ñ ˜Cð ¨%ð ÐDYñ r   c                ó,  a€ \         P                  \        V 4      4       Uu. uF  q"'       g   K  VNK  	  upoS'       g   . # \        ;_uu_ 4        \        P	                  V3R lVR7       RRR4       \        S!  # u upi   + '       g   i     L; i)zŸTurn end: wait up to ``timeout`` for ``agent``'s running checks, then pop every undelivered
``(path, text)`` verdict.  Returns at once when nothing is running.c                 óŠ   <€ \         ;QJ d&    R  S  4       F  '       g   K   R'       * # 	  R'       * # ! R  S  4       4      '       * # )c              3  óL   "  € T F  p\         P                  V4      x € K  	  R # 5ir,   )r   r-   rI   s   & r   rL   Ú5settle_for_agent.<locals>.<lambda>.<locals>.<genexpr>‰   s   é € Ð)JÁ6¸a¬(¯,©,°q¯/¨/Ã6ùs   ‚"$TF)Úany)rE   s   €r   Ú<lambda>Ú"settle_for_agent.<locals>.<lambda>‰   s+   ø€ §c£cÑ)JÁ6Ó)J§c¤cÕ"J¢cÕ"J cÑ)JÁ6Ó)JÓ&JÕ"Jr   )rn   N)rO   rP   rl   r]   Úwait_forrT   )rc   rn   rK   rE   s   && @r   Úsettle_for_agentrx   ‚   sk   ø€ ô Ÿ™¤w¨u£~Ô6Ó<Ñ6�A»!�aˆaÑ6Ñ<€FßØˆ	ß	ŽÜ×ÑÔJÐT[ÐÔ\÷ 
ä�fÑÐùò =÷ 
�ús   ¢	A>°A>ÁBÂB	c               ó    € V ^8„  d   QhRRRR/# )r   rc   r   r!   r1   r   )r"   s   "r   r#   r#   �   s   € ÷ 8ñ 8˜Cð 8 Dñ 8r   c                óz   € \        \        V 4      !  pV'       g   R# ^ RIHp V F  w  r4V! V RV 2V4       K  	  R# )z§Move ``agent``'s finished verdicts onto its live-notes queue, which rides the next tool result
(or the next user turn).  Called right before that tool result is built.N)Úqueue_plugin_noticezlsp:)rT   rl   Úagent.plugin_live_notesr{   )rc   r:   r{   r0   r   s   &    r   Úforward_to_agentr}   �   s9   € ô ”w˜u“~Ñ&€EßÙÝ;Û‰
ˆÙ˜E T¨$¨ =°$Ö7ó r   )ÚTURN_END_WAITr)   r.   r}   rT   r<   rC   rx   ra   r?   rZ   ))Ú__conditional_annotations__Ú__doc__Ú
__future__r   Ú
contextlibÚ	threadingÚcollectionsr   Úcontextvarsr   Údataclassesr   Útypingr   r   r   r   r   r9   r7   ÚLockr4   Ú	Conditionr]   r~   r   r   r   Úcontextmanagerr)   r.   r<   r?   rC   rT   rZ   ra   rl   rx   r}   Ú__all__)r   s   @r   Ú<module>rŒ      sø   øðôõ  #ã Û Ý #Ý "Ý !ß *Ñ *á$.Ð/JÐTXÔ$Y€Ð!Ó YØ€Ø€Ø�ŠÓ€Ø×Ò˜uÓ%€à€ñ �$Ô÷!ð !ó ð!ñ 6A³]€Ð	2Ó Bà#%€Ð
 Ó %ð ×Ñôó ðõõ(õ 8õ=õõõõDð
 3@÷ õ8òC‚r   