§
    øžyjF  ã                  óŒ   — U d Z ddlmZ ddlZddlmZmZmZ dZde	d<   dZ
d%d„Zd&d„Z	 d'd(d„Zd)d„Zddedœd*d"„Zddd#œd+d$„ZdS ),u—  Gateway runtime-metadata footer.

Renders a compact footer showing runtime state (model, context %, cwd) and
appends it to the FINAL message of an agent turn when enabled.  Off by default
to keep replies minimal.

Config (``~/.hermes/config.yaml``)::

    display:
      runtime_footer:
        enabled: true                       # off by default
        fields: [model, context_pct, cwd]   # order shown; drop any to hide

Available fields:
    model        â€” bare model id, vendor prefix dropped (``gpt-5.4``)
    context_pct  â€” last-call context occupancy as a percent (``5%``)
    latency      â€” wall-clock duration of the turn (``22s``, ``1m05s``)
    cwd          â€” home-relative working dir (``~``)

``latency`` is opt-in: it is NOT in the default field set, so a footer whose
``fields`` are unset renders exactly as before.

Per-platform overrides live under ``display.platforms.<platform>.runtime_footer``.
Users can toggle the global setting with ``/footer on|off`` from both the CLI
and any gateway platform.

The footer is appended to the final response text in ``gateway/run.py`` right
before returning the response to the adapter send path â€” so it only lands on
the final message a user sees, not on tool-progress updates or streaming
partials.  When streaming is on and the final text has already been delivered
piecemeal, the footer is sent as a separate trailing message via
``send_trailing_footer()``.
é    )ÚannotationsN)ÚAnyÚIterableÚOptional)ÚmodelÚcontext_pctÚcwdztuple[str, ...]Ú_DEFAULT_FIELDSu    Â· r	   ÚstrÚreturnc                ó8  — | sdS 	 t           j                             d¦  «        }t           j                             | ¦  «        }|rB||k    s"|                     |t           j        z   ¦  «        rd|t          |¦  «        d…         z   S |S # t          $ r | cY S w xY w)zGReturn *cwd* with ``$HOME`` collapsed to ``~``.  Empty string if unset.Ú Ú~N)ÚosÚpathÚ
expanduserÚabspathÚ
startswithÚsepÚlenÚ	Exception)r	   ÚhomeÚps      ú</home/ragecks/.hermes/hermes-agent/gateway/runtime_footer.pyÚ_home_relative_cwdr   ,   s¤   € àð ØˆrðÝŒw×!Ò! #Ñ&Ô&ˆÝŒG�OŠO˜CÑ Ô ˆØð 	'�Q˜$’Y�Y !§,¢,¨tµb´f©}Ñ"=Ô"=�YØ˜�3˜t™9œ9˜:˜:œÑ&Ð&ØˆøÝð ð ð Øˆ
ˆ
ˆ
ðøøøs   †BB
 ÂB
 Â
BÂBr   úOptional[str]c                óB   — | sdS |                       dd¦  «        d         S )uM   Drop ``vendor/`` prefix for readability (``openai/gpt-5.4`` â†’ ``gpt-5.4``).r   ú/é   éÿÿÿÿ)Úrsplit)r   s    r   Ú_model_shortr"   :   s(   € àð ØˆrØ�<Š<˜˜QÑÔ Ô#Ð#ó    Úuser_configúdict[str, Any] | NoneÚplatform_keyú
str | Noneúdict[str, Any]c                óL  — dt          t          ¦  «        dœ}| pi                      d¦  «        pi }|                     d¦  «        }t          |t          ¦  «        rnd|v r%t          |                     d¦  «        ¦  «        |d<   t          |                     d¦  «        t           ¦  «        r|d         rd„ |d         D ¦   «         |d<   |rÙ|                     d¦  «        pi }|                     |¦  «        }t          |t          ¦  «        r˜|                     d¦  «        }t          |t          ¦  «        rnd|v r%t          |                     d¦  «        ¦  «        |d<   t          |                     d¦  «        t           ¦  «        r|d         rd	„ |d         D ¦   «         |d<   |S )
zñResolve effective runtime-footer config for *platform_key*.

    Merge order (later wins):
        1. Built-in defaults (enabled=False)
        2. ``display.runtime_footer``
        3. ``display.platforms.<platform_key>.runtime_footer``
    F)ÚenabledÚfieldsÚdisplayÚruntime_footerr*   r+   c                ó,   — g | ]}t          |¦  «        ‘ŒS © ©r   ©Ú.0Úfs     r   ú
<listcomp>z)resolve_footer_config.<locals>.<listcomp>T   s   € Ð!GÐ!GÐ!G¨Q¥# a¡&¤&Ð!GÐ!GÐ!Gr#   Ú	platformsc                ó,   — g | ]}t          |¦  «        ‘ŒS r/   r0   r1   s     r   r4   z)resolve_footer_config.<locals>.<listcomp>_   s   € Ð)PÐ)PÐ)P°Q­#¨a©&¬&Ð)PÐ)PÐ)Pr#   )Úlistr
   ÚgetÚ
isinstanceÚdictÚbool)r$   r&   ÚresolvedÚcfgÚ
global_cfgr5   Úplat_cfgÚplat_footers           r   Úresolve_footer_configrA   A   s¬  € ð !­DµÑ,AÔ,AÐBÐB€HØÐ˜"×
!Ò
! )Ñ
,Ô
,Ð
2°€Cà—’Ð)Ñ*Ô*€JÝ�*�dÑ#Ô#ð HØ˜
Ð"Ð"Ý"& z§~¢~°iÑ'@Ô'@Ñ"AÔ"AˆH�YÑÝ�j—n’n XÑ.Ô.µÑ5Ô5ð 	H¸*ÀXÔ:Nð 	HØ!GÐ!G°*¸XÔ2FÐ!GÑ!GÔ!GˆH�XÑàð 	QØ—G’G˜KÑ(Ô(Ð.¨Bˆ	Ø—=’= Ñ.Ô.ˆÝ�h¥Ñ%Ô%ð 	QØ"Ÿ,š,Ð'7Ñ8Ô8ˆKÝ˜+¥tÑ,Ô,ð QØ Ð+Ð+Ý*.¨{¯ª¸yÑ/IÔ/IÑ*JÔ*J�H˜YÑ'Ý˜kŸošo¨hÑ7Ô7½Ñ>Ô>ð QÀ;ÈxÔCXð QØ)PÐ)P¸+ÀhÔ:OÐ)PÑ)PÔ)P�H˜XÑ&à€Or#   ÚsecondsÚfloatc                ó˜   — | dk     rdS t          t          | ¦  «        ¦  «        }|dk     r|› d�S t          |d¦  «        \  }}|› d|d›d�S )z6Humanize a turn duration: ``<1s``, ``22s``, ``1m05s``.r   z<1sé<   ÚsÚmÚ02d)ÚintÚroundÚdivmod)rB   ÚtotalrG   Úsecs       r   Ú_format_latencyrN   d   se   € à�‚{€{ØˆuÝ•�g‘”ÑÔ€EØˆr‚z€zØˆ{ˆ{ˆ{ÐÝ�E˜2ÑÔ�F€A€sØÐÐ�#ÐÐÐÐÐr#   )r	   Úturn_secondsr+   Úcontext_tokensrI   Úcontext_lengthúOptional[int]rO   úOptional[float]r+   úIterable[str]c                ó`  — g }|D �]}|dk    r't          | ¦  «        }|r|                     |¦  «         Œ0|dk    rX|rU|dk    rO|dk    rIt          dt          dt	          ||z  dz  ¦  «        ¦  «        ¦  «        }	|                     |	› d�¦  «         ŒŽ|dk    r+|�(|dk    r"|                     t          |¦  «        ¦  «         Œ¿|dk    rFt          |pt          j         	                    d	d
¦  «        ¦  «        }
|
r|                     |
¦  «         �Œ|sd
S t                               |¦  «        S )uß   Render the footer line, or return "" if no fields have data.

    Fields are skipped silently when their underlying data is missing â€” a
    partially-populated footer is better than a line with ``?%`` or empty slots.
    r   r   r   éd   ú%ÚlatencyNr	   ÚTERMINAL_CWDr   )r"   ÚappendÚmaxÚminrJ   rN   r   r   Úenvironr8   Ú_SEPÚjoin)r   rP   rQ   r	   rO   r+   ÚpartsÚfieldrG   ÚpctÚrels              r   Úformat_runtime_footerrd   o   sS  € ð €EØð "ñ "ˆØ�GÒÐÝ˜UÑ#Ô#ˆAØð  Ø—’˜Q‘”�øØ�mÒ#Ð#Øð ( .°1Ò"4Ð"4¸È1Ò9LÐ9LÝ˜!�S ¥e¨^¸nÑ-LÐPSÑ,SÑ&TÔ&TÑUÔUÑVÔV�Ø—’ ˜Y˜Y˜YÑ'Ô'Ð'øØ�iÒÐð Ð'¨L¸AÒ,=Ð,=Ø—’�_¨\Ñ:Ô:Ñ;Ô;Ð;øØ�eŠ^ˆ^Ý$ SÐ%N­B¬J¯NªN¸>È2Ñ,NÔ,NÑOÔOˆCØð "Ø—’˜SÑ!Ô!Ð!ùð ð ØˆrÝ�9Š9�UÑÔÐr#   )r	   rO   c           
     ó®   — t          | |¦  «        }|                     d¦  «        sdS t          ||||||                     d¦  «        pt          ¬¦  «        S )a¹  Top-level entry point used by gateway/run.py.

    Returns the footer text (empty string when disabled or no data).  Callers
    append this to the final response themselves, preserving a single blank
    line of separation.

    ``turn_seconds`` is the wall-clock duration of the agent run, measured by
    the caller with ``time.monotonic()``.  Callers that don't measure it leave
    it ``None`` and the ``latency`` field is skipped.
    r*   r   r+   )r   rP   rQ   r	   rO   r+   )rA   r8   rd   r
   )r$   r&   r   rP   rQ   r	   rO   r=   s           r   Úbuild_footer_linerf   —   sf   € õ(   ¨\Ñ
:Ô
:€CØ�7Š7�9ÑÔð ØˆrÝ ØØ%Ø%ØØ!Ø�wŠw�xÑ Ô Ð3¥Oðñ ô ð r#   )r	   r   r   r   )r   r   r   r   )N)r$   r%   r&   r'   r   r(   )rB   rC   r   r   )r   r   rP   rI   rQ   rR   r	   r   rO   rS   r+   rT   r   r   )r$   r%   r&   r'   r   r   rP   rI   rQ   rR   r	   r   rO   rS   r   r   )Ú__doc__Ú
__future__r   r   Útypingr   r   r   r
   Ú__annotations__r^   r   r"   rA   rN   rd   rf   r/   r#   r   ú<module>rk      s  ðð ð  ð  ðD #Ð "Ð "Ð "Ð "Ð "à 	€	€	€	Ø *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ð *à#B€Ð BÐ BÐ BÑ BØ€ðð ð ð ð$ð $ð $ð $ð  $ð ð  ð  ð  ð  ðFð ð ð ð  Ø$(Ø+ð%ð %ð %ð %ð %ð %ð^ Ø$(ðð ð ð ð ð ð ð r#   