
    `gjښ                     V   U d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
mZ ddlmZ ddlmZmZmZmZ erddlmZ  ej*                  e      ZdZd	Zd
ZdZdefdZdededefdZddlm Z!m"Z# dZ$dZ%deeee   f   fdZ&dZ'dZ(dZ)dZ*dedz  defdZ+dedz  de,fdZ-dedz  de,fdZ.ddd e/e   d!e	d"e0dee   fd#Z1d$edee0   fd%Z2d&e	dee0   fd'Z3d(ede4e0d)f   fd*Z5dGd+edee   fd,Z6dee0   fd-Z7dee0   fd.Z8dee	   fd/Z9d&e	d0edee   fd1Z:dHd&ee	   dee;   fd2Z<d3Z=da>ee4   e?d4<   dHd&ee	   dee4   fd5Z@defd6ZAdaBee0   e?d7<    ej                         ZDd8 ZEdId"eFdee0   fd9ZGd:e0defd;ZHd<edefd=ZI	 	 	 	 	 	 dJd>d?d@ed!edAee;   dBee   dCedDe0dEefdFZJy)KzWelcome banner, ASCII art, skills summary, and update check for the CLI.

Pure display functions with no HermesCLI state dependency.
    N)Path)urlparse)get_hermes_home)TYPE_CHECKINGDictListOptional)Consolez[1;38;2;255;215;0mz[1mz[2mz[0mtextc                 8    ddl m} ddlm}  | ||              y)z:Print ANSI-colored text through prompt_toolkit's renderer.r   )print_formatted_text)ANSIN)prompt_toolkitr   prompt_toolkit.formatted_textr   )r   	_pt_print_PT_ANSIs      D/root/.hermes/venv/lib/python3.12/site-packages/hermes_cli/banner.pycprintr   '   s    @>htn    keyfallbackreturnc                 `    	 ddl m}  |       j                  | |      S # t        $ r |cY S w xY w)z5Get a color from the active skin, or return fallback.r   get_active_skin)hermes_cli.skin_enginer   	get_color	Exception)r   r   r   s      r   _skin_colorr   2   s4    : **399 s    --)__version____release_date__u  [bold #FFD700]██╗  ██╗███████╗██████╗ ███╗   ███╗███████╗███████╗       █████╗  ██████╗ ███████╗███╗   ██╗████████╗[/]
[bold #FFD700]██║  ██║██╔════╝██╔══██╗████╗ ████║██╔════╝██╔════╝      ██╔══██╗██╔════╝ ██╔════╝████╗  ██║╚══██╔══╝[/]
[#FFBF00]███████║█████╗  ██████╔╝██╔████╔██║█████╗  ███████╗█████╗███████║██║  ███╗█████╗  ██╔██╗ ██║   ██║[/]
[#FFBF00]██╔══██║██╔══╝  ██╔══██╗██║╚██╔╝██║██╔══╝  ╚════██║╚════╝██╔══██║██║   ██║██╔══╝  ██║╚██╗██║   ██║[/]
[#CD7F32]██║  ██║███████╗██║  ██║██║ ╚═╝ ██║███████╗███████║      ██║  ██║╚██████╔╝███████╗██║ ╚████║   ██║[/]
[#CD7F32]╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝╚══════╝╚══════╝      ╚═╝  ╚═╝ ╚═════╝ ╚══════╝╚═╝  ╚═══╝   ╚═╝[/]u  [#CD7F32]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⡀⠀⣀⣀⠀⢀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#CD7F32]⠀⠀⠀⠀⠀⠀⢀⣠⣴⣾⣿⣿⣇⠸⣿⣿⠇⣸⣿⣿⣷⣦⣄⡀⠀⠀⠀⠀⠀⠀[/]
[#FFBF00]⠀⢀⣠⣴⣶⠿⠋⣩⡿⣿⡿⠻⣿⡇⢠⡄⢸⣿⠟⢿⣿⢿⣍⠙⠿⣶⣦⣄⡀⠀[/]
[#FFBF00]⠀⠀⠉⠉⠁⠶⠟⠋⠀⠉⠀⢀⣈⣁⡈⢁⣈⣁⡀⠀⠉⠀⠙⠻⠶⠈⠉⠉⠀⠀[/]
[#FFD700]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⡿⠛⢁⡈⠛⢿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#FFD700]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠿⣿⣦⣤⣈⠁⢠⣴⣿⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#FFBF00]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠻⢿⣿⣦⡉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#FFBF00]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢷⣦⣈⠛⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#CD7F32]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣴⠦⠈⠙⠿⣦⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#CD7F32]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣤⡈⠁⢤⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#B8860B]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠷⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#B8860B]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠑⢶⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#B8860B]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠁⢰⡆⠈⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#B8860B]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⠈⣡⠞⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]
[#B8860B]⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀[/]c                      	 ddl m}   |        }i }|D ];  }|j                  d      xs d}|j	                  |g       j                  |d          = |S # t        $ r i cY S w xY w)a  Return skills grouped by category, filtered by platform and disabled state.

    Delegates to ``_find_all_skills()`` from ``tools/skills_tool`` which already
    handles platform gating (``platforms:`` frontmatter) and respects the
    user's ``skills.disabled`` config list.
    r   )_find_all_skillscategorygeneralname)tools.skills_toolr#   r   get
setdefaultappend)r#   
all_skillsskills_by_categoryskillr$   s        r   get_available_skillsr.   \   s{    6%'
 02 J99Z(5I%%h3::5=IJ   	s   A A! A!i`T  z0https://github.com/NousResearch/hermes-agent.gitz$github.com/nousresearch/hermes-agenturlc                    | sy| j                         }|j                  d      rd|t        d      d z   }n`|j                  d      rd|t        d      d z   }n=t        |      }|j                  r&|j
                  r|j                   |j
                   }|j                         j                  d      }|j                  d      r|dd }|j                         S )	z>Return ``host/owner/repo`` for common GitHub remote URL forms. zgit@github.com:zgithub.com/Nzssh://git@github.com//.git)	strip
startswithlenr   netlocpathrstripendswithlower)r0   valueparseds      r   _canonical_github_remoter@      s    IIKE)*c*;&<&= >>			1	2c*A&B&C DD%==V[[}}ofkk]3EKKM  %E~~fcr
;;=r   c                     | sy| j                         j                         }|j                  d      xs |j                  d      S )NFzgit@zssh://)r6   r=   r7   )r0   r>   s     r   _is_ssh_remoterB      s=    IIKEF#Au'7'7'AAr   c                 @    t        |       xr t        |       t        k(  S N)rB   r@   _OFFICIAL_REPO_CANONICAL)r0   s    r   _is_official_ssh_remoterF      s    #\#;C#@D\#\\r      timeoutargscwdrI   c          	          	 t        j                  dg| dd|t        |            }|j                  dk7  ry |j
                  xs dj                         S # t        $ r Y y w xY w)NgitTcapture_outputr   rI   rK   r   r2   
subprocessrunstrr   
returncodestdoutr6   )rJ   rK   rI   results       r   _git_stdoutrW      sm    	NTNC
 AMMR&&((	  s   &A 	A"!A"	local_revc                     	 t        j                  ddt        dgddd      }|j                  dk7  s|j
                  sy|j
                  j                         d   }|sy|| k(  rdS t        S # t        $ r Y yw xY w)	zCompare an embedded git revision to upstream main via ls-remote.

    Returns 0 if up-to-date, ``UPDATE_AVAILABLE_NO_COUNT`` if behind,
    or ``None`` on failure.
    rM   z	ls-remotezrefs/heads/mainT
   )rO   r   rI   Nr   )rQ   rR   _UPSTREAM_REPO_URLr   rT   rU   splitUPDATE_AVAILABLE_NO_COUNT)rX   rV   upstream_revs      r   _check_via_revr_      s    K!35FGdB
 AV]]==&&(+L	)1H/HH  s   !A, ,	A87A8repo_dirc           	         t        g d|       }t        |      r*t        ddg|       }|rt        |      nd}|t        k(  ry|S t        ddg|       }|dk(  }	 g d	}|r|d
dgz  }|j	                  d       t        j                  |ddt        |              |rAt        ddg|       }t        ddg|       xs t        ddg|       }|r|sy||k(  rdS t        S 	 t        j                  g ddddt        |             }|j                  dk(  r#t        |j                  j                               S 	 y# t        $ r Y w xY w# t        $ r Y yw xY w)z5Count commits behind origin/main in a local checkout.)remotezget-urlorigin)rK   	rev-parseHEADN   z--is-shallow-repositorytrue)rM   fetchrc   z--depth1z--quietTrZ   )rO   rI   rK   
FETCH_HEADorigin/mainr   )rM   rev-list--countzHEAD..origin/mainrG   rN   )rW   rF   r_   r]   r*   rQ   rR   rS   r   rT   intrU   r6   )	r`   
origin_urlhead_revcheckedshallow
is_shallow
fetch_args
target_revrV   s	            r   _check_via_local_gitrv      s   <(KJz*V4(C.6.*D// ;(ABQGF"J/
9c**J)$H	
  V4(Cl3B GK7XF 	 z
*qI0II	?dAH

 !v}}**,-- " 5  0  s&   A D7 AE 7	EE	EEv.c                     g }| j                  d      D ]  }	 |j                  t        |              t	        |      S # t        $ r |j                  d       Y Gw xY w)zMParse '0.13.0' into (0, 13, 0) for comparison. Non-numeric segments become 0..r   )r\   r*   rn   
ValueErrortuple)rw   partssegments      r   _version_tupler~      s[    E773< 	LLW&
 <  	LLO	s   ?AApackagec                 b   	 ddl }d|  d}|j                  j                  |ddi      }|j                  j                  |d	      5 }t	        j
                  |j                               }|j                  d
i       j                  d      cddd       S # 1 sw Y   yxY w# t        $ r Y yw xY w)zIFetch the latest version of a package from PyPI. Returns None on failure.r   Nzhttps://pypi.org/pypi/z/jsonAcceptzapplication/json)headersrG   rH   infoversion)	urllib.requestrequestRequesturlopenjsonloadsreadr(   r   )r   urllibr0   reqrespdatas         r   _fetch_pypi_latestr   	  s    &wiu5nn$$S8=O2P$Q^^##C#3 	7t::diik*D88FB'++I6	7 	7 	7  s1   AB" AB	B" BB" B" "	B.-B.c                      t               } | y| t        k(  ry	 t        |       t        t              kD  ryy# t        $ r | t        k7  rdcY S dcY S w xY w)zoCompare installed version against PyPI latest.

    Returns 0 if up-to-date, 1 if behind, None on failure.
    Nr   rf   )r   VERSIONr~   r   )latests    r   check_via_pypir     s]    
  !F~-&!N7$;; -g%q,1,-s   6 AAAc            	         t               } | dz  }t        j                  j                  d      xs d}	 ddlm}m}  | |             dk(  ry	 t        j                         }	 |j                         r|t        j                  |j                               }||j                  dd      z
  t        k  r=|j                  d      |k(  r)|j                  d	      t        k(  r|j                  d
      S |rt        |      }nrt!        t"              j$                  j$                  j'                         }|dz  j                         s| dz  }|dz  j                         st)               }nt+        |      }	 |j-                  t        j.                  |||t        d             |S # t        $ r Y ]w xY w# t        $ r Y w xY w# t        $ r Y |S w xY w)a  Check whether a Hermes update is available.

    Two paths: if ``HERMES_REVISION`` is set (nix builds embed it), compare
    it to upstream main via ``git ls-remote``. Otherwise look for a local
    git checkout and count commits behind ``origin/main``.

    Returns the number of commits behind, ``UPDATE_AVAILABLE_NO_COUNT`` (-1)
    if behind but the count is unknown, ``0`` if up-to-date, or ``None`` if
    the check failed or doesn't apply. Cached for 6 hours.
    z.update_checkHERMES_REVISIONNr   )detect_install_methodget_project_rootdockertsrevverbehindr4   hermes-agent)r   r   r   r   )r   osenvironr(   hermes_cli.configr   r   r   timeexistsr   r   	read_text_UPDATE_CHECK_CACHE_SECONDSr   r_   r   __file__parentresolver   rv   
write_textdumps)	hermes_home
cache_fileembedded_revr   r   nowcachedr   r`   s	            r   check_for_updatesr   (  s    "#K.J::>>"34<LM !1!34@ A ))+C
ZZ
 4 4 67Ffjjq)),GGJJu%5JJu%0zz(++ -
 >((//7796!))+"^3H6!))+#%F)(3FJJcVLQXYZ	
 MU  $  *  Ms6   F #BF/ 0-F> 	F,+F,/	F;:F;>	G
Gc                      t        t              j                  j                  j                         } | dz  j	                         st               }|dz  } | dz  j	                         r| S dS )zReturn the active Hermes git checkout, or None if this isn't a git install.

    Prefers the running code's location over the profile-scoped path
    because ``$HERMES_HOME/hermes-agent/`` may be a stale copy carried
    over by ``--clone-all``.
    r4   r   N)r   r   r   r   r   r   )r`   r   s     r   _resolve_repo_dirr   t  s`     H~$$++335Hv%%'%'/ 6)1138==r   r   c           	          	 t        j                  ddd|gdddt        |             }|j                  dk7  ry|j
                  xs d	j                         }|xs dS # t        $ r Y yw xY w)
z4Resolve a git revision to an 8-character short hash.rM   rd   z	--short=8TrG   rN   Nr   r2   rP   )r`   r   rV   r>   s       r   _git_short_hashr     sy    	Kc2H
 A]] b'')E=D  s   'A 	A)(A)c           	         | xs
 t               } | 	 ddlm}  |d      }|r||ddS 	 yt	        | d      }t	        | d      }|r|s	 ddlm}  |d      }|r||ddS 	 yd}	 t        j                  g d	d
d
dt        |             }|j                  dk(  r+t        |j                  xs dj                         xs d      }||t        |d      dS # t        $ r Y yw xY w# t        $ r Y yw xY w# t        $ r d}Y ;w xY w)u  Return upstream/local git hashes for the startup banner.

    For source installs and dev images this runs ``git rev-parse`` against
    the active checkout.  When no checkout is available — the canonical case
    is the published Docker image, which excludes ``.git`` from the build
    context — we fall back to the baked-in build SHA (see
    ``hermes_cli/build_info.py``) and return it as a frozen
    ``upstream == local`` state with ``ahead=0``.  A built image is by
    definition pinned to one commit, so "ahead" is always zero and the
    banner correctly shows ``· upstream <sha>`` with no carried-commits
    annotation.
    Nr   )get_build_sha   )short)upstreamlocalaheadrk   re   )rM   rl   rm   zorigin/main..HEADTrG   rN   0)r   hermes_cli.build_infor   r   r   rQ   rR   rS   rT   rn   rU   r6   max)r`   r   bakedr   r   r   rV   s          r   get_git_banner_stater     sA    .,.H	;!*E$)EAFF  x7HHf-E5	;!*E$)EAFF  E?H
 !-#446=#>E !53ua=IIA  		  		  s6   C C" $AC1 	CC"	C.-C.1C?>C?z9https://github.com/NousResearch/hermes-agent/releases/tag_latest_release_cachec           	      J   t         
t         xs dS | xs
 t               } | da y	 t        j                  g ddddt	        |             }|j                  dk7  rda y|j                  xs dj                         }|sda yt         d	| }||fa t         S # t
        $ r da Y yw xY w)
u  Return ``(tag, release_url)`` for the latest git tag, or None.

    Local-only — runs ``git describe --tags --abbrev=0`` against the
    Hermes checkout. Cached per-process. Release URL always points at the
    canonical NousResearch/hermes-agent repo (forks don't get a link).
    N )rM   describez--tagsz
--abbrev=0T   rN   r   r2   r3   )
r   r   rQ   rR   rS   r   rT   rU   r6   _RELEASE_URL_BASE)r`   rV   tagr0   s       r   get_latest_release_tagr     s     ($,,.,.H "
7H
 A "==B
%
%
'C "q
&C #J     "s   %B B"!B"c            
          dt          dt         d} t               }|s| S |d   }|d   }t        |j	                  d      xs d      }|dk  s||k(  r|  d| S |d	k(  rd
nd}|  d| d| d| d| d
S )z;Return the version label shown in the startup banner title.zHermes Agent vz ()r   r   r   r   u    · upstream rf   commitcommitsu
    · local z (+z	 carried )r   RELEASE_DATEr   rn   r(   )basestater   r   r   carried_words         r   format_banner_version_labelr     s    G9B|nA6D "EZ H'NE		'"'a(EzX&}XJ//$z8yLV=
*UG3ugY|n\]^^r   _update_resultc                  X    d } t        j                  | d      }|j                          y)z4Kick off update check in a background daemon thread.c                  @    t               at        j                          y rD   )r   r   _update_check_donesetr   r   r   _runz#prefetch_update_check.<locals>._run  s    *, r   T)targetdaemonN)	threadingThreadstart)r   ts     r   prefetch_update_checkr     s$    ! 	T2AGGIr   c                 :    t         j                  |        t        S )z:Get result of prefetched check. Returns None if not ready.rH   )r   waitr   rH   s    r   get_update_resultr     s    G,r   tokensc                     | dk\  r,| dz  }t        |      }t        ||z
        dk  r| dS |ddS | dk\  r,| dz  }t        |      }t        ||z
        dk  r| dS |ddS t        |       S )uL   Format a token count for display (e.g. 128000 → '128K', 1048576 → '1M').i@B g?Mz.1fi  K)roundabsrS   )r   valroundeds      r   _format_context_lengthr   (  s    y *sW}$Ya= c!}	5un*sW}$Ya= c!}v;r   toolset_namec                 8    | sy| j                  d      r| dd S | S )zANormalize internal/legacy toolset identifiers for banner display.unknown_toolsNi)r<   )r   s    r   _display_toolset_namer   9  s3       * 	Sb r   consoler
   modeltoolsenabled_toolsets
session_idcontext_lengthproviderc	                 n   ddl m}	m}
 ddlm} ddlm} |ddl m} |xs g }|xs g } |	d      \  }}|D ch c]  }t        |       }}|r<|D cg c]1  }t        |j                  d	|j                  d
d                  |v r|3 }}t               }t               }|D ]l  }|j                  d
d      }|
j                  |i       }|j                  dg       }|j                  d      r|j                  |       \|j                  |       n |j                  d      }|j                  dd       |j                  dd       t        dd      }t        dd      }t        dd      }t        dd      }	 ddlm}  |       }t#        |d      r|j$                  r|j$                  nt&        }d|dg}|xs dj+                         j-                         dk(  r|} d}!	 ddlm}" dd lm}#  |# |"       j                  d      xs i       }$|$j                  d!i       j                  |       }%|%rM|%j                  d"      xs i }&t        |&j                  d#      xs d      }'d$|'v r|'j7                  d$      d%   n|'}!t9        |       d&kD  r| dd' d(z   } |!rd)| d*| d+|! d,nd}(|rd)| d*| d-t;        |       d.nd})|j=                  d/| d0|  d,|( |) d)| d*| d1       nd$|v r|j7                  d$      d%   n|}*|*j?                  d2      r|*dd3 }*t9        |*      d&kD  r|*dd' d(z   }*|rd)| d*| d-t;        |       d.nd})|j=                  d/| d-|* d,|) d)| d*| d1       tA        jB                  d4      r|j=                  d5| d6       |j=                  d7| d-| d,       |r|j=                  d7| d8| d,       d9jE                  |      }+d:| d;g},i }-|D ]@  }.|.d<   d
   }/tG         ||/      xs d=      }0|-jI                  |0g       j=                  |/       B |D ]k  }|j                  d	|j                  d
d>            }1tG        |1      }2|2|-vrg |-|2<   |j                  dg       D ]  }/|/|-|2   vs|-|2   j=                  |/         m tK        |-jM                               }3|3dd? }4t9        |3      d?z
  }5|4D ]  }0|-|0   }6g }7tK        |6      D ]N  }8|8|v r|7j=                  d@|8 d,       |8|v r|7j=                  dA|8 d,       7|7j=                  d/| d-|8 d,       P dBjE                  |7      }9t9        dBjE                  tK        |6                  dCkD  rg }:d};tK        |6      D ]K  }8|;t9        |8      z   dDz   dEkD  r|:j=                  d(        n$|:j=                  |8       |;t9        |8      dDz   z  };M g }7|:D ]e  }8|8d(k(  r|7j=                  dF       |8|v r|7j=                  d@|8 d,       4|8|v r|7j=                  dA|8 d,       N|7j=                  d/| d-|8 d,       g dBjE                  |7      }9|,j=                  d7| d-|0 dG|9         |5dkD  r|,j=                  d7| dH|5 dI       	 ddJl'm(}<  |<       }=|=r|,j=                  d       |,j=                  d:| dK       |=D ]  }>|>j                  dL      }?|>dM   r1|,j=                  d7| d-|>d
    dN| dO|>dP    dQ| dR| d-|>d    dS       J|>j                  dT      s|?dTk(  r%|,j=                  d7| d-|>d
    dU|>dP    dQ| dV	       |?dWk(  r"|,j=                  d7| d-|>d
    dU|>dP    dX       |?dYk(  r%|,j=                  d7| d-|>d
    dU|>dP    dQ| dZ	       |,j=                  d@|>d
    dU|>dP    d[        |,j=                  d       |,j=                  d:| d\       | xs d]|v }@|@r+tS               }AtU        d^ |AjW                         D              }Bni }Ad}BtY        jZ                         j\                  }Ct_        ta        |Cd_z        d`z
  da      }D@s|,j=                  d7| db       n?Ar'tK        AjM                               D ]	  }EtK        A|E         }Ft9        |E      dDz   }Gt_        D|Gz
  dc      }Hg d};}Itc        |F      D ]  \  }J}8IrdBnd}Kt9        |K      t9        |8      z   }Lt9        F      Jddz   z
  }M|MdkD  rt9        deM df      nd}NIr9|;Lz   Nz   HkD  r.t9        F      t9        I      z
  }O|Ij=                  dg|O df        nIj=                  |8       |;Lz  }; dBjE                  I      }P|,j=                  d7| d-E dh| d-|P d,	        n|,j=                  d7| di       |,j=                  d       |=rtU        dj |=D              nd}Qt9        |       dkB dlg}R|QrRj=                  Q dm       Rj=                  dn       	 ddol2m3}S ddlm}T  |S |T             dpk(  r|,j=                  d:| dq| dr| ds       	 ddtl4m5}U  |U       }V|Vr Vduk7  r|,j=                  d:| dv| d-V d,       |,j=                  d7| d-dwjE                  R       d,       	 tm        dxy      }W|WaWdk7  r\ddzlm7}Xm8}Y WdkD  r*Wddk(  rd{nd|}Z|,j=                  d}W d~|Z d Y        d       n% X       }[d}\|[r	\d[ dz  }\|,j=                  \       	 ddlm9}]m:}^m;}_m<}`  |] |`             }a |_|a      r|,j=                  d} ^a       d,       d9jE                  |,      }b|j{                  |+|b       t        dd      }ct        dd      }dt}               }et               }f|frf\  }g}hd:c d|h d-e d}in	d:c d-e d,}i ||idd      }j| j                          tY        jZ                         j\                  }k|kdk\  rM|r$t#        |d      r|j                  r|j                  nt        }l| j                  |l       | j                          | j                  j       yc c}w c c}w # t(        $ r d}t&        }Y 
w xY w# t(        $ r d}!Y 	w xY w# t(        $ r g }=Y w xY w# t(        $ r Y `w xY w# t(        $ r Y @w xY w# t(        $ r Y w xY w# t(        $ r Y w xY w)a  Build and print a welcome banner with caduceus on left and info on right.

    Args:
        console: Rich Console instance.
        model: Current model name.
        cwd: Current working directory.
        tools: List of tool definitions.
        enabled_toolsets: List of enabled toolset names.
        session_id: Session identifier.
        get_toolset_for_tool: Callable to map tool name -> toolset name.
        context_length: Model's context window size in tokens.
        provider: Active provider id. When ``"moa"``, ``model`` is a MoA
            preset name and the banner renders the aggregator instead of a
            bare model slug.
    r   )check_tool_availabilityTOOLSET_REQUIREMENTS)Panel)TableN)get_toolset_for_toolT)quietidr&   r2   r   check_fn)r      )paddingleftcenter)justifyrightbanner_accentz#FFBF00
banner_dimz#B8860Bbanner_textz#FFF8DCsession_borderz#8B8682r   banner_heromoa)load_config)normalize_moa_configpresets
aggregatorr   r3   r/         z...z [dim u   ]·[/] [dim z]agg z[/]]z context[/][z]MoA: z]Nous Research[/]z.ggufHERMES_YOLO_MODEu    [bold red]⚠ YOLO mode[/] [dim u%   ]— all approval prompts bypassed[/]z[dim z
]Session: 
z[bold z]Available Tools[/]functionotherr   r   z[red]z[yellow]z, -   r   *   z[dim]...[/]z:[/] z](and z more toolsets...)[/])get_mcp_statusz]MCP Servers[/]status	connectedz[/] [z](	transportz
)[/] [dim u	   ]—[/] [z tool(s)[/]disabledz
[/] [dim](u   ]— disabled[/]
connectingu   )[/] [yellow]— connecting[/]
configuredu   ]— configured[/]u   )[/] [red]— failed[/]z]Available Skills[/]skillsc              3   2   K   | ]  }t        |        y wrD   )r8   .0ss     r   	<genexpr>z'build_welcome_banner.<locals>.<genexpr>!  s     Ga3q6Gs   g333333?rZ      z]Skills toolset disabled[/]   rf   z, +z more+z:[/] [z]No skills installed[/]c              3   ,   K   | ]  }|d    s	d  yw)r  rf   Nr   r$  s     r   r'  z'build_welcome_banner.<locals>.<genexpr>G  s     @a;@s   
z toolsz skillsz MCP serversz/help for commands)get_current_runtimecodex_app_serverz]Runtime:[/] [z]codex app-server[/] [dim z,](terminal/file ops/MCP run inside codex)[/])get_active_profile_namedefaultz]Profile:[/] [u    ·       ?rH   )get_managed_update_commandrecommended_update_commandr   r   u   [bold yellow]⚠  u%    behind[/][dim yellow] — run [bold]z[/bold] to update[/]u$   [bold yellow]⚠ update available[/]u   [dim yellow] — run [bold]z
[/bold][/])r   "format_unsupported_install_warningis_unsupported_install_methodr   banner_titlez#FFD700banner_borderz#CD7F32z][link=z
[/link][/])titleborder_styler  _   banner_logo)Cmodel_toolsr   r   
rich.panelr   
rich.tabler   r   rS   r(   r   updategrid
add_columnr   r   r   hasattrr
  HERMES_CADUCEUSr   r6   r=   r   r  hermes_cli.moa_configr  r\   r8   r   r*   r<   r   getenvjoinr   r)   sortedkeystools.mcp_toolr  r.   sumvaluesshutilget_terminal_sizecolumnsr   rn   	enumeratehermes_cli.codex_runtime_switchr,  hermes_cli.profilesr.  r   r1  r2  r   r4  r5  r   add_rowr   r   printr;  HERMES_AGENT_LOGO)mr   r   rK   r   r   r   r   r   r   r   r   r   r   _unavailable_toolsetsr   _enabled_tsitemdisabled_tools
lazy_toolsr   ts_reqtools_in_tslayout_tableaccentdimr   session_colorr   _bskin_hero
left_linespreset_name	agg_labelr  r  _moa_preset_agg_amagg_strctx_strmodel_shortleft_contentright_linestoolsets_dicttool	tool_nametoolset
toolset_iddisplay_namesorted_toolsetsdisplay_toolsetsremaining_toolsets
tool_namescolored_namesr&   	tools_strshort_nameslengthr  
mcp_statussrvr  _skills_enabledr,   total_skills
_term_cols_right_col_widthr$   skill_names_prefix_len_availr|   i_sep_needed_after_ind_len	remaining
skills_strmcp_connectedsummary_partsr,  	_load_cfgr.  _profile_namer   r1  r2  commits_wordmanaged_cmdliner   r4  r5  r   _install_methodright_contenttitle_colorborder_colorversion_labelrelease_info_tag_urltitle_markupouter_panel
term_width_logosm                                                                                                                r   build_welcome_bannerr  D  s   , J  #4KRE'-25DAA $44a3q64K41 
488D$((62"678KG  
  
 UN J$ /xx+%)),;hhw+::j!k*!!+./ ::f:-LFH5GV4 )4F
lI
.C}i0D 0)<M : "&-fm&DI[I[""ap eRJB%%'50 		5B'(9(9%(@(FBGDhhy"-11+>G{{<06B$((7+1r225*CIIcN2.#	 {b %cr*U2KHQF3%|C5i[DWYiwF3%|C52H2X1YYde}AfXVK=G9WIVTWSXXdehdiiz{|.1Ulekk#&r*(%cr*K{b %cr*U2KiwF3%|C52H2X1YYde}AfXQ{m3wivcU,WZV[[lmn	yy#$<SEAfghcU!C5,-E-
:,cJK99Z(LF8#678K%'M @$V,	'(<Y(G(R7S  "-44Y?@
 % >XXdDHHVY$?@
,Z8},*,M,''2. 	>Il ;;l+229=	>> ]//12O&r*_-1# !D"7+
:& 	;D~%$$uTF#%67#$$xvS%9:$$qavS%9:	; IIm,	tyy
+,-2KFz* (CI%)B.&&u-""4(#d)a-'( M# ?5=!((7^+!((5c):;Z'!((8D6)=>!((1TF!D6)=>? 		-0IU3%q	ykBCC!DF AU3%v.@-AAVWX1#%
 2VF8?;< 	CWWX&F;""C5#f+eD6C<L;M N5	$qWkK $*(<""C5#f+j[9I8J K5 02 <'""C5#f+j[9I8J K0 1 <'""C5#f+j[9I8J K5 24
 ""CK=
3{3C2D E) */	8 rx';<=
 'DH,CO13G+=+D+D+FGG ))+33J3zC/025r:U3%'BCD	16689 	UH !3H!=>Kh-!+K)K7<F6E$[1 "4$t"d)c$i/[)QU37=z3VHE23qVg-86A #K 03u: =ILL1YKu!56T"'!" 5)Jse1XJfTF!J<sST)	U, 	U3%'>?@rDNC@:@@TUME
|6*|nG,DEMl;<-.	G>y{+/AAtf 5uHJ?/1]i7x~dV1]OSVWX se1V[[%?$@DE"3/&A+`z+1Q;xI""'xq ?22L2N1OOce 9:=9+jQQD""4(	
 	
 00@0BC(9#$F$W#XX[\ IIk*M}5ni8K	:L/1M)+L!
d}GD6=/T}Am_C@!	K MMO))+33JR&,1OTZTfTf""l}eMM+	 5 
B    &  	I	l  
B    2  *  s   p16p697p;  Bq +q% ,7q7 $/r ;A/r +<r' ;qqq"!q"%q43q47	rr	rr	r$#r$'	r43r4)r   rD   )r0  )NNNNNN)K__doc__r   loggingr   rL  rQ   r   r   pathlibr   urllib.parser   hermes_constantsr   typingr   r   r   r	   rich.consoler
   	getLogger__name__logger_GOLD_BOLD_DIM_RSTrS   r   r   
hermes_clir    r   r!   r   rT  rC  r.   r   r]   r[   rE   r@   boolrB   rF   listrn   rW   r_   rv   r{   r~   r   r   r   r   r   dictr   r   r   __annotations__r   r   r   Eventr   r   floatr   r   r   r  r   r   r   <module>r     s0     	      ! , 6 6 $			8	$ 	! S C C  PF j,d3S	>2 2 '   G A #*  &Bd
 Bt B]t ] ] ?@ )d3i ) ) )HSM ) Ic Ihsm I*94 9HSM 9xc eCHo 
 
# 
- -$I8C= IX>8D> >d  # $5J8D> 5JXd^ 5Jp P )- x -'!Xd^ '!x '!T_S _, !% $$Y__& u x} 3 3 "   .27;+/.2/3)-e) eC ec e $T
e+/9e &)e
 *-e $'er   