
    
Bj                        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y)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    · c                    | sy	 t         j                  j                  d      }t         j                  j                  |       }|r8||k(  s"|j	                  |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}    ww!!#&GGOOC Q$Y!,,tbff}"=3t9:&& 
s   A7A? =A? ?BBc                2    | sy| j                  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    <<Q##    c                   dt        t              d}| xs i j                  d      xs i }|j                  d      }t        |t              rdd|v rt        |j                  d            |d<   t        |j                  d      t               r$|d   r|d   D cg c]  }t        |       c}|d<   |r|j                  d      xs i }|j                  |      }t        |t              r|j                  d      }t        |t              rdd|v rt        |j                  d            |d<   t        |j                  d      t               r$|d   r|d   D cg c]  }t        |       c}|d<   |S c c}w c c}w )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$   	platforms)listr   get
isinstancedictboolstr)	user_configplatform_keyresolvedcfg
global_cfgfr'   plat_cfgplat_footers	            r   resolve_footer_configr6   9   sN    !D,ABH"
!
!)
,
2C)*J*d#
""&z~~i'@"AHYjnnX.5*X:N2<X2F!GQ#a&!GHXGGK(.B	==.h%",,'78K+t,+*.{y/I*JHY'kooh7>;xCX:Eh:O)PQ#a&)PHX&O "H *Qs   E0E5)r
   r$   c                   g }|D ]  }|dk(  r t        |       }|s|j                  |       (|dk(  rI|s0|dkD  s6|dk\  s<t        dt        dt	        ||z  dz                    }|j                  | d       v|dk(  s|t        |xs  t        j                  j                  dd            }	|	s|j                  |	        |syt        j                  |      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   environr)   _SEPjoin)
r   context_tokenscontext_lengthr
   r$   partsfieldmpctrels
             r   format_runtime_footerrI   \   s     E "GU#AQm#.1"419L!Se^n-LPS,S&TUVuAY'e^$S%NBJJNN>2,NOCS!" 99Ur!   )r
   c           	         t        | |      }|j                  d      syt        |||||j                  d      xs 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   rB   rC   r
   r$   )r6   r)   rI   r   )r.   r/   r   rB   rC   r
   r1   s          r   build_footer_linerK   ~   sI      \
:C779 %%wwx 3O r!   )r
   r-   returnr-   )r   Optional[str]rL   r-   )N)r.   dict[str, Any] | Noner/   
str | NonerL   zdict[str, Any])r   rM   rB   intrC   Optional[int]r
   rM   r$   zIterable[str]rL   r-   )r.   rN   r/   rO   r   rM   rB   rP   rC   rQ   r
   rM   rL   r-   )__doc__
__future__r   r   pathlibr   typingr   r   r   r   __annotations__r@   r   r    r6   rI   rK    r!   r   <module>rX      s   2 # 	  * *#B B$  $ &    P +  "	
 
  	R &  	
  " 
 	r!   