+
    lHàjõ!  ã                   ój  € R t ^ RIt^RIHtHt ]P
                  ! ]4      t]! 4       t]P                  t	]P                  tR R ltR R ltR(R lt]	! R4      ]R	 R
 l4       4       t]	! R4      ]R R l4       4       t]	! R4      ]R R l4       4       t]	! R4      ]R R l4       4       t]	! R4      ]R R l4       4       t]	! R4      ]R R l4       4       t]	! R4      ]R R l4       4       t]	! R4      ]R R l4       4       t]	! R 4      ]R! R" l4       4       t]	! R#4      ]R$ R% l4       4       tR& R' ltR# ))u†  Shared-metrics consent JSON-RPC handlers (the Desktop twin of ``hermes setup``'s Shared Metrics
section). Both opt-ins live in the focused profile's config.yaml exactly where the wizard writes
them â€” ``telemetry.shared_metrics.enabled`` (local collection) and ``.send`` (daily upload) â€” so the
CLI and the app can never disagree about the answer. ``shared_metrics.set`` enforces the wizard's
invariant (sending needs collection) and reconciles the consent windows in the local store on every
change, through the same single writer the wizard uses.
Bodies are rebound onto server.py's globals (method_ctx.bind_module) and reference them bare.
N)ÚHandlerRegistryÚbind_modulec                ó$   € V ^8„  d   QhR\         /# )é   Úreturn©Údict)Úformats   "ÚG/home/ubuntu/.hermes/hermes-agent/tui_gateway/methods_shared_metrics.pyÚ__annotate__r      s   € ÷ ñ ¤Dñ ó    c                ó   € ^ RI Hp V! V 4      # )z^The one ``{enabled, send, decided, reask}`` reading every surface shares (CLI offer included).)Úconsent_state)Ú/hermes_cli.observability.shared_metrics_consentr   )Úcfgr   s   & r
   Ú_shared_metrics_consentr      s   € åMá˜ÓÐr   c                ó   € V ^8„  d   QhRR/# ©r   r   N© )r	   s   "r
   r   r      s   € ÷ uñ u°4ñ ur   c                ó
  € ^ RI Hp \        V \        4      '       d   V P	                  R4      MRp\        V\        4      '       d   VP	                  R4      MRpT! R\        V\
        4      '       d   V'       d   TMRR7       R# )z²Desktop has no setup-finish RPC; this first-run answer is the one backend call made once,
right after onboarding settles. A no-op (inside the events API) unless collection is on.)Úrecord_setup_completedÚmodelNÚproviderÚdesktop)Úsurfacer   )Ú.hermes_cli.observability.shared_metrics_eventsr   Ú
isinstancer   ÚgetÚstr)r   r   r   r   s   &   r
   Ú&_shared_metrics_record_setup_completedr      s]   € õ Vä *¨3´× 5Ò 5ˆC�G‰G�GÔ¸4€EÜ(2°5¼$×(?Ò(?ˆu�y‰y˜Ô$ÀT€HÙ 9Ä:ÈhÔX[×C\ÒC\×ai±xÐos×tr   c                 ó„   € ^ RI Hp V! WP                  R4      VP                  R4      VP                  R4      VR7       R# )é    )Úrecord_model_frictionÚsession_keyÚagentÚprofile_home)Ú
session_idr$   Úhermes_homeÚturnsN)Ú-hermes_cli.observability.shared_metrics_modelr"   r   )ÚsignalÚsessionr(   r"   s   &&& r
   Ú_tui_model_frictionr,   %   s2   € ÝSÙØŸ;™; }Ó5¸W¿[¹[ÈÓ=QØ—K‘K Ó/°u÷>r   zshared_metrics.statusc                ó0   € V ^8„  d   QhR\         R\         /# ©r   Úparamsr   r   )r	   s   "r
   r   r   .   s   € ÷ 'ñ '”4ð 'œDñ 'r   c                óš   €  \        V \        \        4       4      4      #   \         d!   p\	        T R\        T4      4      u Rp?# Rp?ii ; i)z›``{enabled, send, decided, reask}`` for the focused profile. A pure read of config.yaml (no defaults
merged, so ``decided`` sees only what the user wrote).iç  N)Ú_okr   Ú	_load_cfgÚ	ExceptionÚ_errr   )Úridr/   Úes   && r
   Ú_r7   ,   s?   € ð
'Ü�3Ô/´	³Ó<Ó=Ð=øÜô 'Ü�C˜œs 1›vÓ&Õ&ûð'ús   ‚ ŸA
ªA¿A
ÁA
zshared_metrics.setc                ó0   € V ^8„  d   QhR\         R\         /# r.   r   )r	   s   "r
   r   r   9   s   € ÷ 2ñ 2”4ð 2œDñ 2r   c                óì  € VP                  R4      RJ pT;'       d    VP                  R4      RJ p^ RIHp  \        4       pV! WRV4       \	        V4       ^ RIH	p T! TR7       T'       g'   ^ R	I
Hp ^ R
IHp	 ^ RIHp
 T! 4        T	! T
! 4       4       TP                  R4      RJ d   \!        T4       \#        T \%        T4      4      #   \
         d!   p\        T R\        T4      4      u Rp?# Rp?ii ; i)ap  Write both opt-ins at once and reconcile the consent windows. ``send`` is forced off when
``enabled`` is off (the wizard's rule: sending cannot outlive collection, and turning collection
off withdraws send consent). ``first_run`` marks the Desktop first-run answer, which also records
the setup-completed metric. Answers the stored ``{enabled, send, decided, reask}``.ÚenabledTÚsend)Ú
set_answeriè  N)Ú_record_send_consent_change)r:   )Úpurge_onboarding_latches)Úpurge_pending_receipts)Úget_hermes_homeÚ	first_run)r   r   r<   Ú_load_cfg_rawÚ	_save_cfgr3   r4   r   Úhermes_cli.setupr=   Ú/hermes_cli.observability.shared_metrics_desktopr>   Ú/hermes_cli.observability.shared_metrics_processr?   Úhermes_constantsr@   r   r1   r   )r5   r/   r:   r;   r<   r   r6   r=   r>   r?   r@   s   &&         r
   r7   r7   7   sÍ   € ð �j‰j˜Ó# tÐ+€GØ×1Ð1�v—z‘z &Ó)¨TÐ1€DÝJð'Ü‹oˆÙ�3 Ô&Ü�#Œõ =á¨Õ-ßÝ\ÝZÝ4á Ô"Ù™Ó0Ô1Ø‡z�z�+Ó $Ó&Ü.¨sÔ3ÜˆsÔ+¨CÓ0Ó1Ð1øô ô 'Ü�C˜œs 1›vÓ&Õ&ûð'ús   ¸C ÃC3ÃC.Ã(C3Ã.C3zshared_metrics.slash_commandc                ó0   € V ^8„  d   QhR\         R\         /# r.   r   )r	   s   "r
   r   r   X   ó   € ÷ "ñ "”4ð "œDñ "r   c                ó’   € ^ RI Hp T! \        VP                  R4      ;'       g    R4      \	        4       R7       \        V RR/4      # )a  The Desktop and Ink TUI dispatchers call this once per user-typed slash command, locally
handled ones included; the gateway never counts slash.exec / command.dispatch itself, so
each command lands exactly once. Always ``{ok: true}`` (the events API never raises).)Úrecord_slash_commandÚcommandÚ )rL   r   ÚokT)r   rK   r   r   Ú_resolve_session_platformr1   )r5   r/   rK   s   && r
   r7   r7   V   s=   € õ Tá¤ V§Z¡Z°	Ó%:×%@Ð%@¸bÓ!AÔKdÓKfÕgÜˆs�T˜4�LÓ!Ð!r   zshared_metrics.startup_latencyc                ó0   € V ^8„  d   QhR\         R\         /# r.   r   )r	   s   "r
   r   r   d   s   € ÷ "ñ "”4ð "œDñ "r   c                ó¾   € ^ RI Hp T! VP                  R4      ;'       g    \        4       VP                  R4      VP                  R4      R7       \	        V RR/4      # )a[  The Ink TUI (gateway ready) and Desktop (backend attached) each report their own launch ->
ready time once per launch; ``launch_id`` latches it here too, so a reconnect to this backend
never re-counts. A Desktop on a URL/cloud backend has no ``HERMES_DESKTOP`` here, so the
client's declared surface wins over env detection. Always ``{ok: true}``.)Úrecord_rpc_startup_latencyr   Ú
elapsed_msÚ	launch_id)Úclient_surfacerS   rT   rN   T)Ú/hermes_cli.observability.shared_metrics_startuprR   r   rO   r1   )r5   r/   rR   s   && r
   r7   r7   b   sV   € õ [áØ—z‘z )Ó,×KÐKÔ0IÓ0KÐX^×XbÑXbÐcoÓXpØ—*‘*˜[Ó)õô ˆs�T˜4�LÓ!Ð!r   zshared_metrics.update_runc                ó0   € V ^8„  d   QhR\         R\         /# r.   r   )r	   s   "r
   r   r   u   s   € ÷ 
"ñ 
"”4ð 
"œDñ 
"r   c           	     óÚ   € ^ RI Hp V! VP                  R4      VP                  R4      VP                  R4      VP                  R4      VP                  R4      R7       \        V RR	/4      # )
z¥Desktop reports each packaged self-update once (a pending record survives the restart that
applies it and is sent on the next backend attach). Always ``{ok: true}``.)Úrecord_desktop_updateÚoutcomeÚfailed_stageÚduration_msÚ	mechanismÚfrom_commit_date)rZ   r[   r\   r]   r^   rN   T)Ú.hermes_cli.observability.shared_metrics_updaterY   r   r1   )r5   r/   rY   s   && r
   r7   r7   s   s^   € õ
 UáØ—
‘
˜9Ó%°F·J±J¸~Ó4NØ—J‘J˜}Ó-¸¿¹ÀKÓ9PØŸ™Ð$6Ó7õô
 ˆs�T˜4�LÓ!Ð!r   z"shared_metrics.desktop_feature_usec                ó0   € V ^8„  d   QhR\         R\         /# r.   r   )r	   s   "r
   r   r   †   ó   € ÷ "ñ "”4ð "œDñ "r   c                óZ   € ^ RI Hp V! VP                  R4      R7       \        V RR/4      # )z™Desktop reports each area the user opened, at most once per UTC day (latched on both sides).
Always ``{ok: true}``; a no-op unless shared metrics are on.)Úrecord_desktop_feature_useÚarea)rd   rN   T)rE   rc   r   r1   )r5   r/   rc   s   && r
   r7   r7   „   s*   € õ
 [á F§J¡J¨vÓ$6Õ7Üˆs�T˜4�LÓ!Ð!r   zshared_metrics.desktop_frictionc                ó0   € V ^8„  d   QhR\         R\         /# r.   r   )r	   s   "r
   r   r   ‘   ra   r   c                óz   € ^ RI Hp V! VP                  R4      VP                  R4      R7       \        V RR/4      # )zžOne Desktop friction event (dismissed notice, error toast by category, renderer crash, backend
disconnect, slow frame), capped per day. Always ``{ok: true}``.)Úrecord_desktop_frictionÚkindÚdetail)rh   ri   rN   T)rE   rg   r   r1   )r5   r/   rg   s   && r
   r7   r7   �   s5   € õ
 Xá §¡¨FÓ!3¸F¿J¹JÀxÓ<PÕQÜˆs�T˜4�LÓ!Ð!r   z!shared_metrics.desktop_onboardingc                ó0   € V ^8„  d   QhR\         R\         /# r.   r   )r	   s   "r
   r   r   œ   s   € ÷ "ñ "”4ð "œDñ "r   c                óz   € ^ RI Hp V! VP                  R4      VP                  R4      R7       \        V RR/4      # )zaOne Desktop first-run step transition, once per (step, event) per profile. Always ``{ok: true}``.)Úrecord_desktop_onboardingÚstepÚevent)rm   rn   rN   T)rE   rl   r   r1   )r5   r/   rl   s   && r
   r7   r7   š   s5   € õ Zá 6§:¡:¨fÓ#5¸V¿Z¹ZÈÓ=PÕQÜˆs�T˜4�LÓ!Ð!r   zshared_metrics.desktop_dislikec                ó0   € V ^8„  d   QhR\         R\         /# r.   r   )r	   s   "r
   r   r   ¦   rI   r   c                óš   € ^ RI Hp V! VP                  R4      VP                  R4      VP                  R4      R7       \        V RR/4      # )a  One Desktop dislike signal (quick close, cancelled flow, setting changed vs default, rage click,
undo, feature disabled), capped per signal per day. For a setting the backend reads the saved value
and compares it to the default itself; only the key and the direction are recorded.)Úrecord_desktop_disliker*   ÚtargetÚsetting)r*   rr   rs   rN   T)rE   rq   r   r1   )r5   r/   rq   s   && r
   r7   r7   ¤   sD   € õ Wá &§*¡*¨XÓ"6¸v¿z¹zÈ(Ó?SÐ]c×]gÑ]gÐhqÓ]rÕsÜˆs�T˜4�LÓ!Ð!r   zshared_metrics.desktop_dailyc                ó0   € V ^8„  d   QhR\         R\         /# r.   r   )r	   s   "r
   r   r   ²   s   € ÷ 	,ñ 	,”4ð 	,œDñ 	,r   c                óº   € ^ RI Hp V! VP                  R4      VP                  R4      VP                  R4      VP                  R4      R7      p\        V RV/4      # )z¼One finished Desktop day: mode use (Bot Mode vs Sessions, with the bot count) and button presses
per action. ``{recorded: true}`` once settled, so the client drops the day; false keeps it.)Úrecord_desktop_dailyÚdayÚmodesÚactionsÚ	bot_count)rw   rx   ry   rz   Úrecorded)rE   rv   r   r1   )r5   r/   rv   r{   s   &&  r
   r7   r7   °   sT   € õ
 Uá#Ø�J‰J�uÓ V§Z¡Z°Ó%8À&Ç*Á*ÈYÓBWØ—*‘*˜[Ó)ô€Hô ˆs�Z Ð*Ó+Ð+r   c                ó   € V ^8„  d   QhRR/# r   r   )r	   s   "r
   r   r   ¿   s   € ÷ 0ñ 0˜ñ 0r   c                 ó2   € \        \        4       V RR7       R# )r7   )ÚskipN)r7   )r   Úglobals)Úservers   &r
   Úregisterr�   ¿   s   € Ü”“	˜6¨×/r   )é   )Ú__doc__ÚloggingÚ
method_ctxr   r   Ú	getLoggerÚ__name__ÚloggerÚ	_registryÚmethodÚprofile_scopedÚ_profile_scopedr   r   r,   r7   r�   r   r   r
   Ú<module>r�      s©  ðñó ç 4à	×	Ò	˜8Ó	$€ÙÓ€	Ø	×	Ñ	€Ø×*Ñ*€õõuô>ñ ÐÓ Øô'ó ó !ð'ñ ÐÓØô2ó ó ð2ñ: Ð&Ó'Øô"ó ó (ð"ñ Ð(Ó)Øô"ó ó *ð"ñ Ð#Ó$Øô
"ó ó %ð
"ñ Ð,Ó-Øô"ó ó .ð"ñ Ð)Ó*Øô"ó ó +ð"ñ Ð+Ó,Øô"ó ó -ð"ñ Ð(Ó)Øô"ó ó *ð"ñ Ð&Ó'Øô	,ó ó (ð	,÷0r   