
    i                        U d Z ddlmZ ddlZddlm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e
dd%dZ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

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)Path)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/ubuntu/.hermes/hermes-agent/gateway/runtime_footer.py_home_relative_cwdr   $   s     rw!!#&&GOOC   	'Q$YY!,,tbf}"="=Y3t99::&&   


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#   2   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 )
zResolve 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>L   s    !G!G!GQ#a&&!G!G!Gr$   	platformsc                ,    g | ]}t          |          S r0   r1   r2   s     r   r5   z)resolve_footer_config.<locals>.<listcomp>W   s    )P)P)PQ#a&&)P)P)Pr$   )listr   get
isinstancedictbool)r%   r'   resolvedcfg
global_cfgr6   plat_cfgplat_footers           r   resolve_footer_configrB   9   s    !D,A,ABBH"
!
!)
,
,
2C)**J*d## H
"""&z~~i'@'@"A"AHYjnnX..55 	H*X:N 	H!G!G*X2F!G!G!GHX 	QGGK((.B	==..h%% 	Q",,'788K+t,, Q++*.{y/I/I*J*JHY'kooh77>> Q;xCX Q)P)P+h:O)P)P)PHX&Or$   )r
   r,   context_tokensintcontext_lengthOptional[int]r,   Iterable[str]c                   g }|D ]}|dk    r't          |           }|r|                    |           /|dk    rX|rU|dk    rO|dk    rIt          dt          dt	          ||z  dz                                }|                    | d           |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   %r
   TERMINAL_CWDr   )r#   appendmaxminroundr   r   environr9   _SEPjoin)
r   rC   rE   r
   r,   partsfieldmpctrels
             r   format_runtime_footerrX   \   s    E " "GU##A  Qm## (.1"4"419L9L!Se^n-LPS,S&T&TUUVVYYY'''e^^$S%NBJNN>2,N,NOOC "S!!!  r99Ur$   )r
   c           	         t          | |          }|                    d          sdS t          |||||                    d          pt                    S )zTop-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.
    r+   r   r,   )r   rC   rE   r
   r,   )rB   r9   rX   r   )r%   r'   r   rC   rE   r
   r>   s          r   build_footer_linerZ   ~   sc      \
:
:C779 r %%wwx  3O   r$   )r
   r   r   r   )r   r   r   r   )N)r%   r&   r'   r(   r   r)   )r   r   rC   rD   rE   rF   r
   r   r,   rG   r   r   )r%   r&   r'   r(   r   r   rC   rD   rE   rF   r
   r   r   r   )__doc__
__future__r   r   pathlibr   typingr   r   r   r   __annotations__rQ   r   r#   rB   rX   rZ   r0   r$   r   <module>r`      s    2 # " " " " " 				       * * * * * * * * * *#B B B B B   $ $ $ $  $         P +     R        r$   