+
    jHàj¢  ã                  ó’  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
 ^RIHt ^RIHtHt ]P                   ! ]4      tR(t]! 4       tR]R&   ]P.                  ! 4       tRt^@tR	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 R llt"R R lt#R R lt$RR/R R llt%R  t&R! R" lt'R# R$ lt(R%R/R& R' llt)R# )*a  Startup / attach latency: one bucketed row per process start and surface.

In-process surfaces (classic CLI, messaging gateway, ``hermes serve``) measure from the OS process
creation time, the earliest timestamp available (it includes interpreter start and imports), to the
moment they are ready. The Ink TUI and the Desktop app measure on their own side and report through
the ``shared_metrics.startup_latency`` RPC. Recording goes through the shared ``_emit`` gate, so a
profile without shared metrics enabled records nothing.
)ÚannotationsN)ÚAny)Úshared_metrics_contract)Ú_bucketÚ_non_negative_numberzset[tuple[int, str, str]]Ú	_recordedi   ÚHERMES_RELAUNCHED_PIDc               ó    € V ^8„  d   QhRRRR/# )é   Ú
elapsed_msr   Úreturnz
str | None© )Úformats   "ÚT/home/ubuntu/.hermes/hermes-agent/hermes_cli/observability/shared_metrics_startup.pyÚ__annotate__r   '   s   € ÷ Pñ P˜sð P zñ Pó    c                óF   € \        V 4      pVf   R # \        V\        R4      # )NÚgte_10s)r   r   Ú_THRESHOLDS_MS)r   Úvalues   & r   Úlatency_bucketr   '   s$   € Ü  Ó,€EØ’=ˆ4ÐO¤g¨e´^ÀYÓ&OÐOr   c               ó$   € V ^8„  d   QhRRRRRR/# )r
   Úsurfacer   r   r   zdict[str, str] | Noner   )r   s   "r   r   r   ,   s"   € ÷ :ñ : sð :¸ð :Ð@Uñ :r   c                óZ   € \        V4      pV \        P                  9  g   Vf   R # RVRV /# )Nr   r   )r   ÚcontractÚSTARTUP_SURFACES)r   r   Úbuckets   $$ r   Ústartup_latency_fieldsr   ,   s0   € Ü˜JÓ'€FØ”h×/Ñ/Ô/°6²>ÙØ˜f i°Ð9Ð9r   c               ó$   € V ^8„  d   QhRRRRRR/# )r
   r   Ústrr   r   r   ÚNoner   )r   s   "r   r   r   3   s&   € ÷ iñ i sð i¸ð iÀñ ir   c                óL   € ^RI Hp V! \        P                  \        WR7       R# )zORecord one measured startup (no-op unless shared metrics are on; never raises).)Ú_emit©r   r   N)Úshared_metrics_eventsr"   r   ÚSTARTUP_LATENCY_MARKr   )r   r   r"   s   $$ r   Úrecord_startup_latencyr&   3   s   € å,á	Œ(×
'Ñ
'Ô)?È×hr   c               ó   € V ^8„  d   QhRR/# )r
   r   zfloat | Noner   )r   s   "r   r   r   :   s   € ÷ ñ ˜Lñ r   c                 ó¦   €  ^ RI p \        V P                  \        P                  ! 4       4      P                  4       4      #   \         d     R# i ; i)zPEpoch seconds at which the OS created this process, or ``None`` when unreadable.N)ÚpsutilÚfloatÚProcessÚosÚgetpidÚcreate_timeÚ	Exception)r)   s    r   Úprocess_started_atr0   :   s?   € ðÛä�V—^‘^¤B§I¢I£KÓ0×<Ñ<Ó>Ó?Ð?øÜô Úðús   ‚>A ÁAÁAc               ó   € V ^8„  d   QhRR/# ©r
   r   r    r   )r   s   "r   r   r   D   s   € ÷ 6ñ 6 ñ 6r   c                 ól   € \        \        P                  ! 4       4      \        P                  \        &   R# )zTCalled right before an in-place ``exec``: the new program inherits this PID and env.N)r   r,   r-   ÚenvironÚRELAUNCHED_PID_ENVr   r   r   Úmark_in_place_relaunchr6   D   s   € ä%(¬¯ª«Ó%5„B‡J�JÔ!Ó"r   c               ó   € V ^8„  d   QhRR/# ©r
   r   Úboolr   )r   s   "r   r   r   I   s   € ÷ Bñ B˜dñ Br   c                 ó†   € \         P                  P                  \        4      \	        \         P
                  ! 4       4      8H  # )N)r,   r4   Úgetr5   r   r-   r   r   r   Ú_relaunched_in_placer<   I   s&   € ä�:‰:�>‰>Ô,Ó-´´R·Y²Y³[Ó1AÑAÐAr   c               ó$   € V ^8„  d   QhRRRRRR/# )r
   r   r   Ú	launch_idr   r9   r   )r   s   "r   r   r   N   s!   € ÷ ñ �Cð  Cð °ñ r   c                ó  € \         P                  ! 4       W3p\        ;_uu_ 4        V\        9   g   \	        \        4      \
        8¼  d    R R R 4       R# \        P                  V4        R R R 4       R#   + '       g   i     R # ; i)NFT)r,   r-   Ú_lockr   ÚlenÚ_MAX_RECORDEDÚadd)r   r>   Úkeys   && r   Ú_claimrE   N   sQ   € Ü�9Š9‹;˜Ð
+€Cß	ŽØ”)Ôœs¤9›~´Ô>Ø÷ 
‰ô 	�‰�cÔØ÷	 
��Šús   ¦%A5ÁA5Á5B	c               ó   € V ^8„  d   QhRR/# r8   r   )r   s   "r   r   r   W   s   € ÷ ñ ˜Tñ r   c                 ó   € ^RI Hp  V ! 4       # )é   ©Úenabled)Úrelay_shared_metricsrJ   rI   s    r   Ú_collection_enabledrL   W   s   € Ý-á‹9Ðr   c               ó$   € V ^8„  d   QhRRRRRR/# )r
   r   r   Úready_atr*   r   r    r   )r   s   "r   r   r   ]   s&   € ÷ `ñ `¨ð `¸ð `À$ñ `r   c                ón   € \        4       pVe'   \        V \        RW,
          4      R,          R7       R # R # )Ng        éè  r#   )r0   r&   Úmax)r   rN   Ústarteds   && r   Ú_record_since_process_startrS   ]   s/   € Ü Ó"€GØÒÜ w¼3¸sÀHÕDVÓ;WÐZ^Õ;^×_ñ r   Ú
backgroundFc               ó$   € V ^8„  d   QhRRRRRR/# )r
   r   r   rT   r9   r   r    r   )r   s   "r   r   r   c   s&   € ÷ Tñ T #ð T°dð TÀtñ Tr   c               ó°  € \         P                   ! 4       p \        4       '       g"   \        V 4      '       d   \        4       '       g   R# V'       g   \	        W4       R# \
        P                  ! 4       p\        P                  ! VP                  \        W3RRR7      P                  4        R#   \         d    \        P                  RT RR7        R# i ; i)a,  ``surface`` became ready now: record process-start -> now once per process.

``background`` hands the (possibly cold, ~seconds) metrics runtime start to a daemon thread
under the caller's contextvars (profile binding), so an event loop never waits on it; the
ready time is taken before the hand-off.
Nzhermes-startup-latencyT)ÚtargetÚargsÚnameÚdaemonz#Startup latency for %s not recorded)Úexc_info)Útimer<   rE   rL   rS   ÚcontextvarsÚcopy_contextÚ	threadingÚThreadÚrunÚstartr/   ÚloggerÚdebug)r   rT   rN   Úcontexts   &$  r   Úrecord_process_readyrf   c   s�   € ô �yŠy‹{€HðTä×!Ò!¬°¯ªÔ@S×@UÒ@UÙßÜ'¨Ô:ÙÜ×*Ò*Ó,ˆÜ×ÒØ—;‘;Ô&AÀ7Ð%UØ)°$ô	
÷ ‰%Ž'øÜô TÜ�‰Ð:¸GÈdˆ×SðTús$   —1B. Á
B. ÁB. ÁAB. Â.#CÃCc                 ó   € R R lp V # )zVA prompt_toolkit ``after_render`` handler that records the first rendered prompt once.c               ó    € V ^8„  d   QhRRRR/# )r
   Ú_appr   r   r    r   )r   s   "r   r   Ú.cli_prompt_ready_handler.<locals>.__annotate__~   s   € ÷ 5ñ 5˜ð 5 ñ 5r   c                ó    € \        R RR7       R# )ÚcliT)rT   N)rf   )ri   s   &r   Ú
_on_renderÚ,cli_prompt_ready_handler.<locals>._on_render~   s   € Ü˜U¨t×4r   r   )rm   s    r   Úcli_prompt_ready_handlerro   {   s   € õ5ð Ðr   c               ó   € V ^8„  d   QhRR/# r2   r   )r   s   "r   r   r   „   s   € ÷ $ñ $ 4ñ $r   c                 ój   € \         P                  P                  R4      '       g   \        R4       R# R# )z§A ``-q`` run is ready to dispatch its query. Kanban workers are dispatched processes, not a
user waiting on a prompt, so they stay out of the CLI startup distribution.ÚHERMES_KANBAN_TASKrl   N)r,   r4   r;   rf   r   r   r   Úrecord_cli_one_shot_readyrs   „   s%   € ô �:‰:�>‰>Ð.×/Ò/Ü˜UÖ#ñ 0r   c               ó    € V ^8„  d   QhRRRR/# )r
   r>   r   r   r   r   )r   s   "r   r   r   ‹   s   € ÷ dñ d˜3ð d 3ñ dr   c                ó^   € \        V \        4      '       d   \        V 4      \        8:  d   V # R# )z«The client's per-launch id, only ever a local latch key (never recorded). Older clients send
none and latch on their side; they count once per backend process and surface.Ú )Ú
isinstancer   rA   Ú_LAUNCH_ID_MAX_LEN)r>   s   &r   Ú_launch_keyry   ‹   s(   € ô # 9¬c×2Ò2´s¸9³~ÔI[Ô7[ˆ9ÐcÐacÐcr   r>   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r
   Úclient_surfacer   r   r>   r   r    r   )r   s   "r   r   r   ‘   s0   € ÷ Gñ G°#ð GÀ3ð GÐSVð GÐbfñ Gr   c                ó°   € RRRRRR/P                  V 4      pVe;   \        V4      e,   \        V\        V4      4      '       d   \	        W1R7       R# R# R# R# )zûThe TUI / Desktop client's own launch -> ready measurement, once per (surface, client launch)
in this backend process. ``client_surface`` is the client's declared surface or the backend's
detection (``desktop``/``tui``); anything else records nothing.ÚdesktopÚdesktop_attachÚtuiNr#   )r;   r   rE   ry   r&   )r{   r   r>   r   s   $$$ r   Úrecord_rpc_startup_latencyr€   ‘   s`   € ð Ð*Ð,<Ð>NÐPUÐW\Ð]×aÑaÐbpÓq€GàÒœ~¨jÓ9ÒEÌ&ÐQXÔZeÐfoÓZp×JqÒJqÜ w×Fñ KrÑEÑr   ))iô  Últ_500ms)rP   Ú500ms_to_1s)iÐ  Ú1s_to_2s)iˆ  Ú2s_to_5s)i'  Ú	5s_to_10s)rv   )*Ú__conditional_annotations__Ú__doc__Ú
__future__r   r]   Úloggingr,   r_   r\   Útypingr   rv   r   r   r   r   Ú	getLoggerÚ__name__rc   r   Úsetr   Ú__annotations__ÚLockr@   rB   rx   r5   r   r   r&   r0   r6   r<   rE   rL   rS   rf   ro   rs   ry   r€   )r†   s   @r   Ú<module>r�      sÑ   øðôõ #ã Û Û 	Û Û Ý å 1ß Bà	×	Ò	˜8Ó	$€ð€ñ
 (+£u€	Ð$Ó ,Ø�ŠÓ€à€ØÐ ð -Ð õPõ
:õiõõ6õ
B÷
õõ`ðT¸U÷ Tò0õ$õdðGÐY]÷ Gñ Gr   