+
    i                      a  ER) t0 t R t^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
Ht ^ RIHtHt ]P                  ! 4       t]! ]4      P$                  P$                  P'                  4       t]P*                  ! RR4      t]! ]P*                  ! RR4      4      t]! ]P*                  ! R]! ]R	,          R
,          4      4      4      P5                  4       P'                  4       t]R,          t]R,          t]R,          t]R,          t]R,          t ]R,          t!R R lt"R R lt#]"! 4       t$]#! ]$4      t%]$e<   ]! ]$4      ]PL                  9  d"   ]PL                  PO                  ]! ]$4      4       Rt(MRt( ^ RI)H*t* / t,]PZ                  ! 4       t.R R lt/R R lt0R R lt1]1! 4        ],t2R R lt3]3! 4       s4]P*                  ! R R!4      s5R" R# lt6R$ R% lt7R&t8ER+t90 ER,mt:0 ER-mt;0 ER.mt<R'R0R(R1R)R1R*R2R+R3R,R4R-R5R.R6R7R8R/R9/
t=. ER/Ot>]0! 4       P                  R:/ 4      P                  R;]>4      t@R<R=R>R?R@RA/R<R=R>RBR@RC/R<R=R>RDR@RE/R<R=R>RFR@RG/R<R=R>RHR@RI/R<R=R>RJR@RK/R<R=R>RLR@RM/.tA/ tB] ^ k RNtC/ RORPbRQR=bRRRSbRTRUbRVRWbRXRYbRZR[bR\R]bR^R_bR`RabRbRcbRdRebRfRgbRhRibRjRkbRlRmbRnRobRpRqRrRs/CtD. ER0OtERRER1RTER2RQER3RhER4RZER5R\ER6R^ER7R`ER8RdER9RfER:RtER;/tFRRR>RuR@Rv/R>RwR@Rx/R>RyR@Rz/R>R{R@R|/.RTR>R}R@R~/R>RR@R/R>RR@R/R>RR@R/.RVR>RR@R/R>RR@R/R>RR@R/R>RR@R/.RhR>RR@R/.R^R>RR@R/R>RR@R/.ROR>RR@R/R>RR@R/R>RR@R/.RZR>RR@R/R>RR@R/R>RR@R/R>RR@R/R>RR@R/R>RR@R/.R\R>RR@R/R>RR@R/R>RR@R/R>RR@R/R>RR@R/R>RR@R/R>RR@R/R>RR@R/R>RR@R/R>RR@R/R>RR@R/.RfR>RR@R/R>RR@R/R>RR@R/R>RR@R/R>RR@R/.RXR>RR@R/R>R}R@R~/R>RR@R/R>RuR@Rv/R>RwR@Rx/R>RR@R/.RR>RR@R/R>RR@R/./tG]H;QJ d    . R ER< 4       F  NK  	  5M! R ER< 4       4      tI0 ER=mtJER>tKR R ltLER?R R lltMR R ltNR R ltOR R ltPR R ltQR R ltRRRRR/R R lltSR R ltTR R ltUER?R R lltVR R ltWRR/R R lltXER?RR/R R llltYER?RR/R R llltZR R lt[R R lt\R R lt]]C3R R llt^R R lt_RR/R R llt`ER?R R lltaER?R R lltbR R ltcR R ltdER  ER lteER ER ltfER?ER ER lltgER ER lthER ER	 lti]ER
,          ER,          tj]PZ                  ! 4       tk^dtl]PZ                  ! 4       tm/ tn] ^k ]PZ                  ! 4       to/ tp] ^k ]P                  ! 4       tq]P                  ! 4       tsER ttER tu/ tv] ^k ]PZ                  ! 4       twER ER ltxER]! \h        4      ERERERRERRERRERRERERER]P*                  ! ERER4      ERR/	tyER ER ltzER ER  lt{ER! ER" lt|]}! ]yP                  4       4      ER0,
          tERERER#0/t0 ER@mtER$ ER% lt]|! 4       t]EP	                  4       '       dE   ]P                  ER4      '       d-   ]! ]ER,          4      P5                  4       P'                  4       s4 ]0! 4       t]P                  ER&/ 4      t]! ]]4      '       d   ]P                  ER'R4      t]! ]]4      '       d)   ]EP                  4       '       d   ]EP                  4       s5]EP                  ! 4       t] ^k  ^ ER(IHt ]! 4        R#   ]+ d    ER*t* ELi ; i  ]+ d     LAi ; i  ] d     R# i ; i(A  a  
Hermes Web UI -- Shared configuration, constants, and global state.
Imported by all other api/* modules and by server.py.

Discovery order for all paths:
  1. Explicit environment variable
  2. Filesystem heuristics (sibling checkout, parent dir, common install locations)
  3. Hardened defaults relative to $HOME
  4. Fail loudly with a human-readable fix-it message if required modules are missing
NPath)parse_qsurlparseHERMES_WEBUI_HOST	127.0.0.1HERMES_WEBUI_PORT8787HERMES_WEBUI_STATE_DIR.hermeswebuisessionszworkspaces.jsonz_index.jsonzsettings.jsonzlast_workspace.txtzprojects.jsonc                $    V ^8  d   QhR\         /#    returnr   )formats   "'/home/ubuntu/hermes-webui/api/config.py__annotate__r   -   s     ' 'T '    c                    . p \         P                  ! R4      '       dK   V P                  \        \         P                  ! R4      4      P	                  4       P                  4       4       \         P                  ! R\        \        R,          4      4      pV P                  \        V4      P	                  4       R,          4       V P                  \        P                  R,          4       \        P                  R,          P                  4       '       d    V P                  \        P                  4       V P                  \        R,          R,          4       V P                  \        R,          4       V  FJ  pVP                  4       '       g   K  VR,          P                  4       '       g   K:  VP                  4       u # 	  R# )a  
Locate the hermes-agent checkout using a multi-strategy search.

Priority:
  1. HERMES_WEBUI_AGENT_DIR env var  -- explicit override always wins
  2. HERMES_HOME / hermes-agent      -- e.g. ~/.hermes/hermes-agent
  3. Sibling of this repo            -- ../hermes-agent
  4. Parent of this repo             -- ../../hermes-agent (nested layout)
  5. Common install paths            -- ~/.hermes/hermes-agent (again as fallback)
  6. HOME / hermes-agent             -- ~/hermes-agent (simple flat layout)
HERMES_WEBUI_AGENT_DIRHERMES_HOMEr   zhermes-agentzrun_agent.pyN)osgetenvappendr   
expanduserresolvestrHOME	REPO_ROOTparentexists)
candidateshermes_homepaths      r   _discover_agent_dirr&   -   s:    J 
yy)**$ryy)ABCNNPXXZ[ ))M3ti/?+@AKd;'224~EF i&&78 	>)1133)**+ dY&78 d^+,;;==d^3;;==<<>!  r   c                0    V ^8  d   QhR\         R\        /# )r   	agent_dirr   )r   r   )r   s   "r   r   r   W   s     # # # #r   c                &   \         P                  ! R4      '       d   \         P                  ! R4      # V '       dq   V R,          R,          R,          pVP                  4       '       d   \        V4      # V R,          R,          R,          pVP                  4       '       d   \        V4      # \        R,          R,          R,          pVP                  4       '       d   \        V4      # ^ RIpR
 F   pVP                  V4      pV'       g   K  Vu # 	  R	# )z
Locate a Python executable that has the Hermes agent dependencies installed.

Priority:
  1. HERMES_WEBUI_PYTHON env var
  2. Agent venv at <agent_dir>/venv/bin/python
  3. Local .venv inside this repo
  4. System python3
HERMES_WEBUI_PYTHONvenvbinpythonScriptsz
python.exez.venvNpython3)r/   r-   )r   r   r"   r   r    shutilwhich)r(   venv_pyvenv_py_win
local_venvr0   namefounds   &      r   _discover_pythonr7   W   s     
yy&''yy.//f$u,x7>>w<  &(94|C{## W$u,x7J: %T"5L &
 r   TFVALID_REASONING_EFFORTSc                $    V ^8  d   QhR\         /# r   r   )r   s   "r   r   r      s     	0 	0$ 	0r   c                     \         P                  ! R4      p V '       d   \        V 4      P                  4       #  ^ RIHp V! 4       R,          #   \         d    \        R,          R,          u # i ; i)z/Return config.yaml path for the active profile.HERMES_CONFIG_PATHget_active_hermes_homezconfig.yamlr   )r   r   r   r   api.profilesr>   ImportErrorr   )env_overrider>   s     r   _get_config_pathrB      s]    9912LL!,,..07%'-77 0i-//0s   A A/.A/c                $    V ^8  d   QhR\         /# r   dict)r   s   "r   r   r      s      D r   c                 :    \         '       g   \        4        \         # )z;Return the cached config dict, loading from disk if needed.)
_cfg_cachereload_config r   r   
get_configrJ      s    :r   c                    V ^8  d   QhRR/# r   r   NrI   )r   s   "r   r   r      s      t r   c                    \         ;_uu_ 4        \        P                  4        \        4       p  ^ RIpV P                  4       '       dK   VP                  V P                  4       4      p\        V\        4      '       d   \        P                  V4       RRR4       R#   \         d     Li ; i  + '       g   i     R# ; i)z7Reload config.yaml from the active profile's directory.N)	_cfg_lockrG   clearrB   yamlr"   	safe_load	read_text
isinstancerE   update	Exception)config_path_yamlloadeds      r   rH   rH      s    	&(	 !!##)>)>)@Afd++%%f- 
  		 
s)   B.A$BB+(B.*B++B..B?	c                $    V ^8  d   QhR\         /# r   r   )r   s   "r   r   r      s     / /T /r   c                 L   \         P                  ! R4      '       d<   \        \         P                  ! R4      4      P                  4       P	                  4       # \
        R,          p V P                  4       '       d   V P	                  4       # \        R,          P	                  4       # )z
Resolve the default workspace in order:
  1. HERMES_WEBUI_DEFAULT_WORKSPACE env var
  2. ~/workspace (common Hermes convention)
  3. STATE_DIR / workspace (isolated fallback)
HERMES_WEBUI_DEFAULT_WORKSPACE	workspace)r   r   r   r   r   r   r"   	STATE_DIR)commons    r   _discover_default_workspacer_      sq     
yy122BII>?@KKMUUWWKF}}~~#,,..r   HERMES_WEBUI_DEFAULT_MODELzopenai/gpt-5.4-minic                    V ^8  d   QhRR/# rL   rI   )r   s   "r   r   r      s     !
 !
d !
r   c                    Rp RpRpRRRR\          2R\        '       d   \        MR	 R
\        '       d   T MT 2R\         2R\         2R\         2R\
         R\         2R\        4        R
\        4       P                  4       '       d   RMR 2R.p\        RP                  V4      RR7       \        '       g   \        V R2RR7       R# R# )zNPrint detected configuration at startup so the user can verify what was found.z[32m[ok][0mz[33m[!!][0mz[31m[XX][0m z!  Hermes Web UI -- startup configz"  --------------------------------z  repo root   : z  agent dir   : z	NOT FOUNDz  z  python      : z  state dir   : z  workspace   : z  host:port   : :z  config file : z(found)z(not found, using defaults)
T)flusha\    Could not find the Hermes agent directory.
      The server will start but agent features will not work.

      To fix, set one of:
        export HERMES_WEBUI_AGENT_DIR=/path/to/hermes-agent
        export HERMES_HOME=/path/to/.hermes

      Or clone hermes-agent as a sibling of this repo:
        git clone <hermes-agent-repo> ../hermes-agent
N)r    
_AGENT_DIR
PYTHON_EXEr]   DEFAULT_WORKSPACEHOSTPORTrB   r"   printjoin_HERMES_FOUND)okwarnerrliness       r   print_startup_configrs      s     B D C 	+,
9+&
:ERjj^aGbc
:,'
9+&
,-.
4&$(
+-.b>N>P>W>W>Y>Y_|0}~
E 
$))E
$'=e F F 	
 r   c                $    V ^8  d   QhR\         /# r   )tuple)r   s   "r   r   r      s     0 0u 0r   c                     R.p . p/ pV  F  p \        V4       K  	  \        V4      ^ 8H  W3#   \         d9   pTP                  T4       \        T4      P                   RT 2Y#&    Rp?Ka  Rp?ii ; i)zk
Attempt to import the key Hermes modules.
Returns (ok: bool, missing: list[str], errors: dict[str, str]).
	run_agentz: N)
__import__rU   r   type__name__len)requiredmissingerrorsmodes        r   verify_hermes_importsr      s~    
 }HGF	5sO  LA//  	5NN3 "!W--.b4FK		5s   -A0-A++A0i@ .png.jpg.jpeg.gif.svg.webp.ico.bmp.jsonz	image/pngz
image/jpegz	image/gifzimage/svg+xmlz
image/webpzimage/x-iconz	image/bmpz.pdfzapplication/pdfapplication/jsonplatform_toolsetscliprovider
OpenRouteridopenrouter/freelabelAuto (Free Router)zqwen/qwen3.6-plus:freezQwen: Qwen3.6 Plus (free)zqwen/qwen3-coder:freez"Qwen: Qwen3 Coder 480B A35B (free)zopenai/gpt-oss-120b:freezOpenAI: gpt-oss-120b (free)zopenai/gpt-oss-20b:freezOpenAI: gpt-oss-20b (free)z&meta-llama/llama-3.3-70b-instruct:freez#Meta: Llama 3.3 70B Instruct (free)z)nousresearch/hermes-3-llama-3.1-405b:freez#Nous: Hermes 3 405B Instruct (free)i,  nouszNous Portal
openrouter	anthropic	AnthropicopenaiOpenAIopenai-codexzOpenAI CodexcopilotzGitHub Copilotzaiz
Z.AI / GLMkimi-codingzKimi / MoonshotdeepseekDeepSeekmistralMistral	google-aiz	Google AIblockrunzBlockrun / ClawRouterminimaxMiniMaxgoogleGooglez
meta-llamaz
Meta LlamahuggingfaceHuggingFacealibabaAlibabaollamaOllamalmstudioz	LM Studioz
minimax-cnzclaude-opus-4.6zClaude Opus 4.6zclaude-sonnet-4.6zClaude Sonnet 4.6zclaude-sonnet-4-5zClaude Sonnet 4.5zclaude-haiku-4-5zClaude Haiku 4.5zgpt-5.4-minizGPT-5.4 Minizgpt-4ozGPT-4oo3zo4-minizgpt-5.3-codexzGPT-5.3 Codexzgpt-5.2-codexzGPT-5.2 Codexzgpt-5.1-codex-maxzGPT-5.1 Codex Maxzgpt-5.1-codex-minizGPT-5.1 Codex Minizgemini-2.5-prozGemini 2.5 Prodeepseek-chatzDeepSeek V3.2 Chatdeepseek-reasonerzDeepSeek V3.2 Thinkingzxiaomi/mimo-v2-prozMiMo V2 Pro (free)zxiaomi/mimo-v2-omnizMiMo V2 Omni (free)zxiaomi/mimo-v2-flashzMiMo V2 Flash (free)zglm-5.1zGLM-5.1zglm-5zGLM-5zglm-5-turbozGLM-5 Turbozglm-4.7zGLM-4.7zglm-4.5zGLM-4.5zglm-4.5-flashzGLM-4.5 Flashzkimi-for-codingzKimi for Codingz	kimi-k2.5z	Kimi K2.5zkimi-k2-thinkingzKimi K2 Thinkingzkimi-k2-thinking-turbozKimi K2 Thinking Turbozkimi-k2-turbo-previewzKimi K2 Turbo Previewzkimi-k2-0905-previewzKimi K2 0905zkimi-k2-0711-previewzKimi K2 0711zmoonshot-v1-128kzMoonshot v1 128kzmoonshot-v1-32kzMoonshot v1 32kzmoonshot-v1-8kzMoonshot v1 8kzmoonshot-v1-autozMoonshot v1 AutozMiniMax-M2.7zMiniMax M2.7zMiniMax-M2.7-highspeedzMiniMax M2.7 HighspeedzMiniMax-M2.5zMiniMax M2.5zMiniMax-M2.5-highspeedzMiniMax M2.5 HighspeedzMiniMax-M2.1zMiniMax M2.1zgpt-5.4zGPT-5.4geminizgemini-2.0-flashzGemini 2.0 Flashc              #   @   "   T F  pV\         9   g   K  Vx  K  	  R # 5iNr8   ).0efforts   & r   	<genexpr>r     s"       Fv(( FFs   
c                L    V ^8  d   QhR\         R,          R\         R,          /# r   provider_idNr   r   )r   s   "r   r   r     s"     1 1d
 1sTz 1r   c           
          T ;'       g    R P                  4       P                  4       p V '       g   R# RRRRRRRRR	R
/pVP                  W 4      # )rc   Ncodexr   moonshotr   kimiz	deep-seekr   
clawrouterr   )striplowerget)r   aliasess   & r   _normalize_provider_idr     sX    $$"++-335KMZjG ;;{00r   c                J    V ^8  d   QhR\         R\         R,          R\        /# )r   r   active_providerNr   r   ru   )r   s   "r   r   r     s&     " "C "#* "PU "r   c                     \        V 4      ;'       g    R p \        V4      pV'       d   W8X  d   RV 3#  \        P                  V 4      V 3#   \         d    RT 3u # i ; i)rc   i  )r   _PROVIDER_SORT_ORDERindex
ValueError)r   r   s   &&r   _provider_sort_keyr     sf    (5;;K,_=O;9K  "$**;7EE "[!!"s   A AAc                $    V ^8  d   QhR\         /# r   rD   )r   s   "r   r   r     s     ( (4 (r   c                 ,   \         R,          R,          p  ^ RIHp V! 4       R,          p/ pW3 F  pVP	                  4       '       g   K   VP                  4       P                  4        F  pVP                  4       pV'       g   K  VP                  R4      '       d   K6  RV9   g   K?  VP                  R^4      w  rgVP                  4       P                  R4      P                  R4      W6P                  4       &   K  	  K  	  \        P                  4        UU	u0 uF  pV F  p	V	kK  	  K  	  up	p0 Rm,          p
V
 F'  p	\        P                  ! V	4      pV'       g   K#  WV	&   K)  	  V#   \         d    T p ELOi ; i  \         d     EK]  i ; iu up	pi )	a  Read the active profile .env and merge in current process overrides.

Reads the main ~/.hermes/.env first as a base layer, then overlays the
profile-specific .env on top.  This ensures API keys stored in the main
file are visible even when the active profile doesn't duplicate them.
r   .envr=   #="'>   API_KEYLOCAL_API_KEYHERMES_API_KEYHERMES_OPENAI_API_KEY)r   r?   r>   r@   r"   rR   
splitlinesr   
startswithsplitrU   _PROVIDER_ENV_KEYSvaluesr   r   )main_env_path_gahprofile_env_pathdatar%   linekvkeyskeyinterestingvals               r   _load_profile_envr     s^    9$v-M)?6F? D1{{}}	(335zz|4 4 4::c1-DA&'ggiooc&:&@&@&EDO	 6	 2 '--//DC 	 	/		K iin3I  K;  )()  		s<   E) 6E=E=E=(AE=F)E:9E:=FFc                $    V ^8  d   QhR\         /# r   rD   )r   s   "r   r   r     s       r   c                    \         R,          p / pV P                  4       '       g   V#  V P                  4       P                  4        F  pVP	                  4       pV'       g   K  VP                  R4      '       d   K6  RV9   g   K?  VP                  R^4      w  r4VP	                  4       P	                  R4      P	                  R4      WP	                  4       &   K  	  V#   \         d     T# i ; i)z9Read repo-local .env overrides used by the WebUI service.r   r   r   r   r   )r    r"   rR   r   r   r   r   rU   )env_pathr   r   r   r   s        r   _load_repo_envr     s    6!HD??&&(335D::<DtDOOC00SD[zz#q)"#'')//#"6"<"<S"AWWY	 6 K  Ks$   6C $C =C AC C-,C-c                H    V ^8  d   QhR\         \        ,          R,          /# rL   setr   )r   s   "r   r   r     s     C CC4 Cr   c                  d   \         P                  ! R 4      p V '       g   \        4       P                  R R4      p V '       g   R# V P	                  R4       Uu0 uF/  p\        V4      P                  4       '       g   K$  \        V4      kK1  	  ppV Uu0 uF  q3'       g   K  VkK  	  up# u upi u upi )HERMES_WEBUI_ALLOWED_PROVIDERSrc   N,r   r   r   r   r   r   r   r   )rawpartallowedr   s       r   _get_allowed_providersr     s    
))4
5C""#CRH IIcN"Dt9?? 	%t$"  
 ,3B7KkKK7BB
 Cs   !B(<B(	B-B-c                :    V ^8  d   QhR\         \        ,          /# r   r   )r   s   "r   r   r     s     	B 	Bs3x 	Br   c                  P   \         P                  ! R 4      p V '       g   \        4       P                  R R4      p V P	                  R4       Uu0 uF/  p\        V4      P                  4       '       g   K$  \        V4      kK1  	  ppV Uu0 uF  q3'       g   K  VkK  	  up# u upi u upi )HERMES_WEBUI_HIDDEN_PROVIDERSrc   r   r   )r   r   hiddenr   s       r   _get_hidden_providersr     s    
))3
4C""#BBG IIcN"Dt9?? 	%t$"  
 ,2A6K[KK6AA
 Bs   !B2B	B#B#c                :    V ^8  d   QhR\         \        ,          /# r   )listr   )r   s   "r   r   r   %  s     L LT#Y Lr   c                     \        4       pT ;'       g    .  FR  p\        T;'       g    R 4      P                  4       P                  4       pV\        9   g   KA  VP                  V4       KT  	  \         Uu. uF  q3V9   g   K  VNK  	  up# u upi )rc   )r   r   r   r   r9   add_REASONING_EFFORT_ORDER)optionsseenr   r   s   &   r   _normalize_reasoning_optionsr  %  ss    UD}}"}SYYB%%'--/,,HHV  "9K!8vdNFF!8KKKs   5BBr  noterc   c                <    V ^8  d   QhR\         R\         R\        /# )r   moder  r   r   rE   )r   s   "r   r   r   .  s!      c # t r   c          	         \        T ;'       g    R 4      P                  4       P                  4       ;'       g    R p \        V4      pR.pV R8X  d$   VP	                  R4       VP                  V4       M"V R8X  d   VP	                  R4       M	V R	9  d   R p RT RTR\        T;'       g    R4      P                  4       RV R
9  /# )unsupportedrc   r   nonetoggler	  r  r  disabled>   modelr  >   r   r  )r   r   r   r  r   extend)r	  r  r  normalized_optionsr   s   &$$  r   _reasoning_metadatar  .  s    t$$}%++-335FFD5g>TFxf()		f	-	-6DJJB%%'D 44	 r   c                2    V ^8  d   QhR\         R,          /# rL   rD   )r   s   "r   r   r   A  s      4RV; r   c                 L   T ;'       g    .  Uu0 uFo  p\        T;'       g    R 4      P                  4       '       g   K.  \        T;'       g    R 4      P                  4       P                  4       P                  RR4      kKq  	  ppV'       g   R# \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   \        RRRR	7      # \        ;QJ d    R
 V 4       F  '       g   K   RM	  RM! R
 V 4       4      '       d   \        RRR7      # R# u upi )rc   -_Nc              3   F   "   T F  pR V9   ;'       g    RV9   x  K  	  R# 5i)reasoning_effortzreasoning.effortNrI   r   items   & r   r   @_reasoning_metadata_from_supported_parameters.<locals>.<genexpr>J  s)     
[PZ%CC);t)CCPZs   !!TFr   zGThis provider reports explicit reasoning-effort controls for the model.)r  r  c              3   x   "   T F0  pVR 8H  ;'       g    VR8H  ;'       g    VP                  R4      x  K2  	  R# 5i)	reasoninginclude_reasoningz
reasoning.Nr   r  s   & r   r   r  P  sN       D 	 	) 	)&&	) 	)??<(	) s   :::r  zOThis model exposes reasoning as an on/off toggle, not a low/medium/high ladder.r  lowmediumhigh)r   r   r   replaceanyr  )supported_parametersr  
normalizeds   &  r   -_reasoning_metadata_from_supported_parametersr*  A  s    *//R//Dtzzr?  " 	:DJJB%%'//S9/  
 
s
[PZ
[sss
[PZ
[[["-Z
 	

 s  	sss  	   #b
 	
 1s   D!D!D!7D!c                F    V ^8  d   QhR\         R\        \         ,          /# r   model_idr   )r   r   )r   s   "r   r   r   ]  s      3 49 r   c                 l    ^ RI Hp V! V 4      p\        V4      pV'       d   V# \	        T ;'       g    R4      P                  4       P                  4       pVP                  R4      '       d   \        R4      # VP                  R4      '       g   RV9   d   \        R4      # . #   \         d    . p Li ; i)    )github_model_reasoning_effortsrc   zgpt-5z/gpt-5)z	openai/o1z	openai/o3z	openai/o4o1r   o4r"  )minimalr#  r$  r%  )hermes_cli.modelsr0  rU   r  r   r   r   r   )r-  r0  effortsr)  r   s   &    r   $_copilot_reasoning_efforts_for_modelr6  ]  s    D0: .g6J
hnn"

#
#
%
+
+
-C
~~OPP+,EFF
~~g(c/+,PQQI  s   B# #B32B3c                d    V ^8  d   QhR\         R,          R\         R\        R,          R\        /# )r   r   Nr-  	raw_entryr   r
  )r   s   "r   r   r   p  s4     3. 3.sTz 3.S 3.UY\`U` 3.lp 3.r   c                   a \        V 4      ;'       g    R p \        T;'       g    R 4      P                  4       pVP                  4       oV R8X  d   SR8X  d   \	        RRR7      # V R8X  g/   SP                  R4      '       g   SP                  R4      '       d   \	        R	R
R7      # V R8X  d   RS9   d   \	        R	RR7      # \        V4      pV'       d   \	        RVR7      # RpRp\        V\        4      '       d,   \        VP                  R4      4      pVP                  R4      pVe   V# \        V\        4      '       d#   VP                  R4      RJ d   \	        RRR7      # S\        9   gI   \        ;QJ d#    V3R l\         4       F  '       g   K   RM	  RM! V3R l\         4       4      '       d   \	        RRR7      # \	        R4      # )rc   r   r   r  zdOpenRouter Auto (Free) can route across multiple models, so reasoning controls are unavailable here.r!  r   r   r   r  z`DeepSeek switches reasoning via separate Chat and Thinking models instead of an effort dropdown.r   thinkingz[Moonshot exposes thinking via separate model variants instead of per-request effort levels.r   )r  Nr(  capabilitiesr  Tr  z[This model supports reasoning on or off, but does not expose low/medium/high effort levels.c              3   F   <"   T F  pSP                  V4      x  K  	  R # 5ir   r   )r   prefix	raw_lowers   & r   r   0_reasoning_metadata_for_model.<locals>.<genexpr>  s!     \:[y##F++:[   !Fz:This Mistral model supports reasoning as an on/off toggle.)r   r   r   r   r  r   r6  rS   rE   r*  r   _MISTRAL_REASONING_MODEL_IDSr'  !_MISTRAL_REASONING_MODEL_PREFIXES)r   r-  r8  r5  supported_metar;  r>  s   &&&   @r   _reasoning_metadata_for_modelrD  p  s   (5;;K8>>r"((*H Il"y4E'E"w
 	

 j I$8$8$I$IYMaMabuMvMv"s
 	

 m#
i(?"n
 	

 38<G"8W==NL)T""Fy}}UkGlm }}^4!,%%,*:*:;*G4*O"n
 	
 	113\:[\333\:[\\\"M
 	

 }--r   c                v    V ^8  d   QhR\         R,          R\        \        ,          R\        \        ,          /# )r   r   N
raw_modelsr   r   r   rE   )r   s   "r   r   r     s0      cDj d4j UYZ^U_ r   c                 F   \        V 4      p . pT;'       g    .  F  p\        V\        4      '       g   K  \        VP	                  R 4      ;'       g    R4      P                  4       pV'       g   KW  \        V4      p\        WVR7      VR&   VP                  V4       K  	  V# )r   rc   r8  r  )r   rS   rE   r   r   r   rD  r   )r   rF  	annotatedr   r-  entrys   &&    r   _annotate_reasoning_metadatarL    s    (5KIR#t$$swwt}**+113S	:;\abk   r   all_envc          	      r    V ^8  d   QhR\         R,          R\         R\        R,          R\        R,          /# )r   r   Nr-  rM  r   r
  )r   s   "r   r   r     s<      t D[	
 
D[r   c                h   \        V 4      p \        T;'       g    R 4      P                  4       pV '       d	   V'       g   R# V R8X  d   \        VR7      pMnV R8X  d*   \	        4       ;'       g    \
        P                  V . 4      pM>V \
        9   d   \
        P                  V . 4      pM\        VR7      P                  V . 4      pT;'       g    .  F_  p\        V\        4      '       g   K  \        VP                  R4      ;'       g    R 4      P                  4       V8X  g   KT  \        V4      u # 	  R# )rc   Nr   rM  r   r   )
r   r   r    _discover_openrouter_free_models_discover_codex_model_entries_PROVIDER_MODELSr   (_discover_named_custom_provider_catalogsrS   rE   )r   r-  rM  rF  r   s   &&$  r   _lookup_model_catalog_entryrU    s     )5K8>>r"((*Hhl"5gF
		&24]]8H8L8L[Z\8]
	(	(%))+r:
=gNRRS^`bc
R#t$$swwt}""#))+x79	  
 r   c                d    V ^8  d   QhR\         R\         R,          R\        R,          R\        /# )r   r-  r   NrM  r   r
  )r   s   "r   r   r     s>     a aata D[	a
 
ar   c                2   \        T ;'       g    R 4      P                  4       pTp\        V4      pV'       d5    \        V4      w  rgpV'       d   TpV'       g   V'       d   \        V4      p\        VVVR7      p	\        WTV	R7      #   \         d     L(i ; i)rc   rP  rI  )r   r   r   resolve_model_providerrU   rU  rD  )
r-  r   rM  selected_modelresolved_modelresolved_provider_model	_providerr  r8  s
   &&$       r   get_model_reasoning_metadatar^    s     R(..0N#N.{;	#9.#I Fq!'$$:9$E! ,I
 )):V_``  		s   B B "B BBc          
      p    V ^8  d   QhR\         R\         R\         R,          R\        R,          R\         /# )r   r-  r  r   NrM  r   r
  )r   s   "r   r   r     sB     - --- t-
 D[- 	-r   c                   \        T;'       g    R 4      P                  4       P                  4       pV'       g   R # \        V VVR7      pVP	                  R4      '       d   R # VP	                  R4      ;'       g    .  Uu0 uF_  p\        T;'       g    R 4      P                  4       '       g   K.  \        T;'       g    R 4      P                  4       P                  4       kKa  	  ppWG9   d   V# R # u upi )rc   )r   rM  r  r  )r   r   r   r^  r   )r-  r  r   rM  valuemetar  r   s   &&&$    r   clamp_reasoning_effortrc    s      &&B'--/557E'D
 xx
 XXi(..B..Dtzzr?  " 	(DJJB%%'.  
 $5,",s    C1C10C1>'C1c                $    V ^8  d   QhR\         /# r   rD   )r   s   "r   r   r     s      $ r   c                  J    ^ RI Hp  V ! 4       R,          pVP	                  4       '       g   / #  \
        P                  ! VP                  4       4      p\        V\        4      '       d   V# / #   \         d    \        R,          R,          p Lxi ; i  \         d    / u # i ; i)r/  r=   z	auth.jsonr   )r?   r>   r@   r   r"   jsonloadsrR   rS   rE   rU   )r   auth_store_pathr   s      r   _load_auth_storeri    s    9?&;. !!##	zz/3356!$--t525  9*[89  	s(   A- ;B +B -BBB"!B"c                <    V ^8  d   QhR\         R\        R\        /# )r   
auth_storer   r   )rE   r   bool)r   s   "r   r   r     s!       C D r   c                 n   \        V4      ;'       g    R pV P                  R4      ;'       g    / pVP                  V4      p\        V\        4      '       d   VP                  R4      '       gF   VP                  R4      '       g/   VP                  R4      '       g   VP                  R4      '       d   R# VP                  R4      '       g   VP                  R4      '       d   R# V'       d   R# M
V'       d   R# V P                  R4      ;'       g    / pW9   d   VP                  V4      '       d   R# R	# )
rc   	providerstokensapi_keyr   api_keysTcredential_pooloauthF)r   r   rS   rE   )rk  r   rn  statepools   &&   r   _auth_store_has_providerrv    s    (5;;K{+11rIMM+&E%99X%))I"6"6%))E:J:JeiiXbNcNc99&''599W+=+= 	>>+,22Dtxx44r   c                0    V ^8  d   QhR\         R\         /# )r   base_urlr   r   )r   s   "r   r   r   ,  s     $ $C $C $r   c                    T ;'       g    R P                  4       p V '       g   R# \        RV 9   d   T MRV  24      pVP                  ;'       g+    VP                  ;'       g    VP                  ;'       g    R P                  4       pRpV F  w  rEWB9   g   K  Vu # 	  VP                  '       d    ^ RIpVP                  VP                  4      pVP                  '       g%   VP                  '       g   VP                  '       d-   RV9   g   VP                  R9   d   R# RV9   g   RV9   d   R# R	#  R# R#   \         d6    TP                  R4      '       g   TP                  R
4      '       d    R	#  R# i ; i)rc   customz://zhttp://Nr   	localhostr   z	lm-studiolocalz.local))zopenrouter.air   )zapi.deepseek.comr   )zmoonshot.air   )zapi.kimi.comr   )zapi.openai.comr   )zapi.anthropic.comr   )z!generativelanguage.googleapis.comr   )zgoogleapis.comr   >   r{  r   )r   r   hostnamenetlocr%   r   	ipaddress
ip_address
is_privateis_loopbackis_link_localr   r   endswith)rx  parsedhost
hosted_mapneedler   r  addrs   &       r   _infer_provider_from_base_urlr  ,  sB   B%%'H%8"3h78*9MNFOOAAv}}AAAArHHJD	J  *>  * 	''8D$"2"2"2d6H6H6Ht#v:T'T#%)<% 7I 	  	{++t}}X/F/F 0G 		s0   20D8 #D8 5D8 D8 !D8 8!E8E87E8c                R    V ^8  d   QhR\         R\        R\        \        ,          /# )r   	cache_keyttl_secondsr   )r   intr   rE   )r   s   "r   r   r   S  s(      # C ostxoy r   c                 f   \         P                   ! 4       p\        P                  V 4      pV'       dI   W4P                  R ^ 4      ,
          V8  d,   VP                  R. 4       Uu. uF  p\        V4      NK  	  up#  V! 4       ;'       g    . pV'       dC   V Uu. uF  p\        V4      NK  	  ppR VRV/\        V &   V Uu. uF  p\        V4      NK  	  up# V'       d,   VP                  R. 4       Uu. uF  p\        V4      NK  	  up# . # u upi   \         d    . p Li ; iu upi u upi u upi )tsmodels)time_DYNAMIC_MODEL_CACHEr   rE   rU   )r  loaderr  nowcachedr  freshr  s   &&&     r   _load_cached_model_catalogr  S  s   
))+C!%%i0F3D!,,;'-zz(B'?@'?tT
'?@@B )./$t*/#f+
Y' (..vtT
v..'-zz(B'?@'?tT
'?@@I# A   0
 / As0   $D<D 
D D$ D)3D.D! D!c                $    V ^8  d   QhR\         /# r   )rl  )r   s   "r   r   r   k  s     M MT Mr   c                 :    \        V 4      P                  4       R9   # )0>   rc   r  0.00.000.0000.0000)r   r   )ra  s   &r   _looks_like_free_pricer  k  s    u:!LLLr   rp  c          	      ^    V ^8  d   QhR\         R\         R\         R\        \        ,          /# )r   rx  rp  r  r   rG  )r   s   "r   r   r   o  s6     88 8888 88 	88
 
$Z88r   c                    a a S ;'       g    R P                  4       P                  R4      o S '       g   . # R VV 3R llp\        W#4      # )rc   /c                :    V ^8  d   QhR\         \        ,          /# r   r   rE   )r   s   "r   r   8_discover_openai_compatible_models.<locals>.__annotate__y  s     , ,4: ,r   c                    < ^ RI p SP                  R4      '       d   S R2MS R2pRR/pS;'       g    RP                  4       pV'       d   VR8w  d	   R	V 2VR
&   V P                  P	                  WRR7      pV P                  P                  V^
R7      ;_uu_ 4       p\        P                  ! VP                  4       P                  R4      4      pRRR4       . p\        X\        4      '       dp   \        VP                  R4      \        4      '       d   VP                  R. 4      pM7\        VP                  R4      \        4      '       d   VP                  R. 4      p\        4       p. p	V EF  p
\        V
\        4      '       Ed   \        V
P                  R4      ;'       g5    V
P                  R4      ;'       g    V
P                  R4      ;'       g    R4      P                  4       p\        V
P                  R4      ;'       g    V
P                  R4      ;'       g    T4      P                  4       pV
P                  R4      ;'       g    / pV
P                  R4      ;'       g    . p\        V\        4      '       d   VP                  R4      RJ d   EK.  M)\        T
;'       g    R4      P                  4       pTp/ p. pV'       d   W9   d   EKi  VP!                  V4       RTRT;'       g    T/p\        V\        4      '       d   V'       d   \        V4      VR&   \        V\        4      '       d   V'       d   \        V4      VR&   V	P#                  V4       EK  	  V	#   + '       g   i     EL; i)r/  N/v1/models
/v1/modelsAcceptr   rc   zno-key-requiredBearer AuthorizationGET)headersmethodtimeoututf-8r   r  r   r5   r  r;  r(  completion_chatFr   )urllib.requestr  r   requestRequesturlopenrf  rg  readdecoderS   rE   r   r   r   r   r  r   )urllibendpoint_urlr  tokenreqresponsepayloadmodels_listr  entriesr  r-  r   r;  r(  rK  rp  rx  s                   r   _load1_discover_openai_compatible_models.<locals>._loady  s   /7/@/@/G/G(7+PXzYcMd/0B%%'U//)0'8GO$nn$$\5$Q^^##C#44jj!7!7!@AG 5 gt$$'++f-t44%kk&"5GKK1488%kk(B7 D$%%txx~\\&1A\\TXXgEV\\Z\]cceDHHV,MM0AMMXNTTV#xx7==2'+xx0F'G'M'M2$lD11l6F6FGX6Y]b6btzzr?002 !')$x/HHX8We.?.?x@E,--,(,\(:n%.55:N045I0J,-NN5!+  , E 544s   4M))M:	)r   rstripr  )rx  rp  r  r  s   dd$ r   "_discover_openai_compatible_modelsr  o  sD     B%%'..s3H	, ,\ &i77r   c                T    V ^8  d   QhR\         R,          R\        \         ,          /# r   rM  Nr   rE   r   )r   s   "r   r   r     s"     ? ?$+ ?d ?r   c                    T ;'       g    \        4       p\        P                  R . 4      p\        V\        4      '       g   . p\        P                  R/ 4      p\        V\
        4      '       d   VP                  4        Fv  w  rE\        V\
        4      '       g   K  VP                  RVP                  RV4      RVP                  RR4      RVP                  RR4      RVP                  RR4      /4       Kx  	  . p\        4       pV EFi  p\        V\
        4      '       g   K  \        VP                  R4      ;'       g    R4      P                  4       p	\        VP                  R4      ;'       g    R4      P                  4       P                  R	4      p
V	'       d	   V
'       g   K  \        V	4      pV'       g   K  V	P                  4       P                  R
4      '       d   K  W9   d   K  VP                  V4       \        VP                  R4      ;'       g    R4      P                  4       pV'       gz   \         P                  VR4       F_  p\        VP                  V4      ;'       g!    \"        P$                  ! V4      ;'       g    R4      P                  4       pV'       g   K]  Tp M	  TP                  RTRT	R\&        P                  WP)                  RR4      P)                  RR4      P+                  4       4      RT
RTR\        VP                  R4      ;'       g    R4      P                  4       R\        VP                  R4      ;'       g    R4      P                  4       /4       EKl  	  V# )custom_providersrn  r5   rx  apirc   rp  api_mode	transportr  zcustom-api-r   r   r   r  r  rI   )r   cfgr   rS   r   rE   itemsr   r   r   r   r  r   r   r   r  r   r   r   _PROVIDER_DISPLAYr&  title)rM  envr  providers_dictpidr   r  r  r8  raw_namerx  r   rp  r   	candidates   &              r   _load_named_custom_providersr    s   

(
(&(Cww126&-- WW["-N.$''&,,.HCc4((##,CGGE2.3779b1CGGK4	% 	 / GUD%	)T**y}}V,22399;y}}Z066B7==?FFsKx,X6 >>&&}55immI.44"5;;=)--k2> D D		# D D"EKKM	9'G	 ? 	;H)--k;K;KCQT;U;];]^acf;g;m;m;opwIMM*5;;<BBDSw/5526<<>
 	= &P Nr   c                v    V ^8  d   QhR\         R,          R\         \        \        \         ,          3,          /# r  )rE   r   r   )r   s   "r   r   r     s0      dTk TRUW[\`WaRaMb r   c                    / p\        V R 7       F  p\        VP                  RR4      VP                  RR4      RVP                  RR4       RVP                  RR4       2R7      pVP                  RR4      pV'       d2   YC Uu0 uF  qUR	,          kK  	  up9  d   VP                  R	VR
V/4       V'       g   K  W1VR,          &   K  	  V# u upi )rP  rx  rc   rp  znamed-custom:r   rd   )rx  rp  r  r  r   r   )r  r  r   r   )rM  catalogsrK  r  configured_modelms   &     r   rT  rT    s    &(H-g>3YYz2.IIi,%eiir&B%C1UYYz[]E^D_`
 !99Wb1 0&8Q&Q4&8Q QMM4!17<LMN6-3U=)* ? O 9Rs   Cc                >    V ^8  d   QhR\         R,          R\        /# r   )r   rl  )r   s   "r   r   r     s"     d d3: d$ dr   c                    a  \        S 4      o S '       g   R # \        ;QJ d'    V 3R l\        4        4       F  '       g   K   R# 	  R # ! V 3R l\        4        4       4      # )Fc              3   J   <"   T F  qP                  R 4      S8H  x  K  	  R# 5i)r   Nr   )r   rK  r   s   & r   r   ,_provider_is_named_custom.<locals>.<genexpr>  s     cDb5yy';6Dbs    #T)r   r'  r  )r   s   fr   _provider_is_named_customr    sD    (5K3cD`Dbc33c3c3cD`Dbcccr   c          	          V ^8  d   QhR\         R\        \        ,          R\         R,          R\        \        ,          /# )r   r   rF  r   Nr   rG  )r   s   "r   r   r     s:      c tDz TWZ^T^ cghlcm r   c                 4   \        V 4      ;'       g    R p \        V4      p. pT;'       g    .  F  p\        V\        4      '       g   K  \        VP	                  R4      ;'       g    R 4      P                  4       pV'       g   KW  TpV '       d&   W8w  d    VP                  R4      '       g	   RV  RV 2p\        V4      pWgR&   \        VP	                  R4      ;'       g    T4      P                  4       ;'       g    TVR&   VP                  V4       K  	  V# )rc   r   @rd   r   )r   rS   rE   r   r   r   r   r   )r   rF  r   r  r   r-  	routed_idrK  s   &&&     r   _with_provider_hintsr    s    (5;;K,_=OFR#t$$swwt}**+113	;9(BUBUVYBZBZK=(4IS	dSWWW-99:@@BNNhge   Mr   c                0    V ^8  d   QhR\         R\         /# r,  r   )r   s   "r   r   r     s        r   c                    T ;'       g    R P                  4       pV'       g   V# VP                  RR4      pRRRRRRR	R
RRRR/p. pVP                  R4       EF  pVP                  4       pWR9   d   VP	                  W%,          4       K3  V'       dO   V^ ,          R8X  dA   VR,          P                  RR 4      P                  4       '       d   VP	                  V4       K  VP                  RR 4      P                  4       '       d   VP	                  V4       K  TP	                  VP                  4       '       d   VP                  4       MVP                  4       4       EK
  	  \        V4      ^8  dW   V^ ,          R8X  dI   V^,          P                  RR 4      P                  4       '       d   RV^,           2.VR,          ,           pRP                  V4      # )rc   r  r  gptGPTossOSSr   CodexminiMinimaxMaxsparkSparko   NN.zGPT-:r   NNr  )r   r&  r   r   r   isdigitisupperupper
capitalizer{   rm   )r-  r   specialpartsr  r#  s   &     r   _format_codex_model_labelr    sn   >>r
 
 
"C

++c3
CuuuG E3kkm>LL&SVs]s2wsB'?'G'G'I'ILL[[b!))++LLLL%--//u?O?O?QR   5zQ58u,q1A1A#r1J1R1R1T1Taz"#eBi/88E?r   c                :    V ^8  d   QhR\         \        ,          /# r   r  )r   s   "r   r   r   8  s     = =tDz =r   c                  &    R  R lp \        RV 4      # )c                :    V ^8  d   QhR\         \        ,          /# r   r  )r   s   "r   r   3_discover_codex_model_entries.<locals>.__annotate__9  s      4: r   c            	         R p  ^ RI Hp V! 4       pVP                  R4      p  ^ RIHp V! V R7      p\        4       p. pT;'       g    .  Fj  p\        V\        4      '       g   K  VP                  4       pV'       d   Wu9   d   K;  VP                  V4       VP                  RVR\        V4      /4       Kl  	  V#   \         d    R p  Li ; i  \         d    . p Li ; i)N)!resolve_codex_runtime_credentialsrp  )get_codex_model_ids)access_tokenr   r   )hermes_cli.authr  r   rU   hermes_cli.codex_modelsr  r   rS   r   r   r  r   r  )r	  r  credsr  	model_idsr  r  r-  s           r   r  ,_discover_codex_model_entries.<locals>._load9  s    	 I57E 99Y/L	C+FI  !RHh,,~~'Hx/HHXNNh28<  ( -  	 L	   	I	s"   B: C :C
	C
CCr   )r  )r  s    r   rR  rR  8  s    < &ne<<r   c                T    V ^8  d   QhR\         R,          R\        \         ,          /# r  r  )r   s   "r   r   r   Z  s*     NS NSdTk NST$Z NSr   c                    a T ;'       g    \        4       oR  V3R llp\        RV4      pV'       d   V# \         Uu. uF  pRVR,          RVR,          /NK  	  up# u upi )c                :    V ^8  d   QhR\         \        ,          /# r   r  )r   s   "r   r   6_discover_openrouter_free_models.<locals>.__annotate__]  s     F F4: Fr   c                  	  < ^ RI p RR/pSP                  R4      ;'       g    \        P                  ! R4      pV'       d	   RV 2VR&   V P                  P                  RVR7      pV P                  P                  V^R	7      ;_uu_ 4       p\        P                  ! VP                  4       P                  R
4      4      pRRR4       . p\        4       p\        X\        4      '       d   VP                  R. 4      M.  EF5  p\        V\        4      '       g   K  \        VP                  R4      ;'       g    R4      P                  4       p	V	'       d   W9   d   K^  VP                  R4      ;'       g    / p
\!        V
P                  R4      4      '       d!   \!        V
P                  R4      4      '       g   K  VP                  R4      ;'       g    / pVP                  R4      ;'       g    .  Uu0 uF  p\        V4      P#                  4       kK  	  ppVP                  R4      ;'       g    .  Uu0 uF  p\        V4      P#                  4       kK  	  ppRV9  g   RV9  g   RV9   d   EKp  VP%                  V	4       \        VP                  R4      ;'       g    R4      P                  4       pV	R8X  d   RpMT;'       g    T	pVP                  R4      ;'       g    .  Uu0 uF  p\        V4      P#                  4       kK  	  ppTP'                  RT	RTRRV9   d   ^ M^R\)        V4      /4       EK8  	  RR0p\        V\        4      '       d   VP                  R. 4      M.  F  p\        V\        4      '       g   K  \        VP                  R4      ;'       g    R4      P                  4       p	V	'       d   W9   g   V	V9  d   Kd  VP%                  V	4       \        VP                  R4      ;'       g    R4      P                  4       pTP'                  RT	RT;'       g    T	/4       K  	  VP+                  R R 7       V F  pVP-                  RR4       K  	  V#   + '       g   i     EL; iu upi u upi u upi )!r/  Nr  r   OPENROUTER_API_KEYr  r  z#https://openrouter.ai/api/v1/models)r  r  r  r   r   rc   pricingprompt
completionarchitectureinput_modalitiesoutput_modalitiestextaudior5   r   r   r(  r   _sort_toolstoolszz-ai/glm-5.1zqwen/qwen3.6-plusc                 v    V R ,          R8X  d   ^ M^V P                  R^4      V R,          P                  4       3# )r   r   r  r   )r   r   )r  s   &r   <lambda>A_discover_openrouter_free_models.<locals>._load.<locals>.<lambda>  s6    d00AaHH]A&M!'
r   r   )r  r   r   r   r  r  r  rf  rg  r  r  r   rS   rE   r   r   r  r   r  r   sortedsortpop)r  r  rp  r  r  r  r  r  r  r-  r  archr   inputsoutputsr5   r   	supported_wanted_nonfreer  s                      r   r  /_discover_openrouter_free_models.<locals>._load]  s   /0''./RR299=Q3R)0	':GO$nn$$%JT[$\^^##C#44jj!7!7!@AG 5 /9'4/H/HGKK+bPDdD))488D>//R0668Hx/hhy)//RG*7;;x+@AAF\]d]h]hiu]vFwFw88N+11rD.2hh7I.J.P.Pb.PQ.Pc!flln.PFQ/3xx8K/L/R/RPR/RS/R!s1v||~/RGSV#vW'<7@RHHXtxx'--2.446D,,,((15:P1Q1W1WUW1WX1WAQ1WIXNNhGy$8qa&y(9	 1 QB 
 0:'4/H/HGKK+bPDdD))488D>//R0668Hx/8?3RHHXtxx'--2.446DNNh))  Q 	 
 	
 DHH]D) { 544" RS Ys   4Q0"Q31"Q8#"Q=Q0	zopenrouter-freer   r   )r   r  _OPENROUTER_FREE_MODELS)rM  r  r  r  r  s   &   @r   rQ  rQ  Z  sc    

(
(&(CF FP ((95AF:QR:QQT1T7GQwZ0:QRRRs   Ac                0    V ^8  d   QhR\         R\        /# r,  r   )r   s   "r   r   r     s     26 26S 26U 26r   c                N   RpRp\         P                  R/ 4      p\        V\        4      '       d#   VP                  R4      pVP                  R4      p\	        V4      p\        V4      pT ;'       g    RP                  4       p V '       g   WV3# V P                  R4      '       d'   RV 9   d    V R,          P                  R^4      w  rVWeR3# R	V 9   dQ   V P                  R	^4      w  rxVR
8X  d   V R
V3# V'       d   Wq8X  d   WV3# V\        9   d   Wq8w  d   V'       g   V R
R3# WV3# )at  Resolve model name, provider, and base_url for AIAgent.

Model IDs from the dropdown can be in several formats:
  - 'claude-sonnet-4.6'          (bare name, uses config default provider)
  - 'anthropic/claude-sonnet-4.6' (OpenRouter format, provider/model)
  - '@minimax:MiniMax-M2.7'       (explicit provider hint from dropdown)

The @provider:model format is used for models from non-default provider
groups in the dropdown, so we can route them through the correct provider
via resolve_runtime_provider(requested=provider) instead of the default.

Returns (model, provider, base_url) where provider and base_url may be None.
Nr  r   rx  rc   r  rd   r  r  r   )
r  r   rS   rE   r   r  r   r   r   rS  )	r-  config_providerconfig_base_url	model_cfgconfig_provider_is_named_customprovider_hint
bare_modelr=  bares	   &        r   rX  rX    s+    OO$I)T""#--
3#--
3,_=O&?&P#B%%'H/99
 3C8O$,RL$6$6sA$>!$..
h~~c1- l*\?:: v8/99 %%&*CLk\4//o55r   c                $    V ^8  d   QhR\         /# r   rD   )r   s   "r   r   r     s     | |d |r   c                   a9a: Ro9\         p . p\        4       o:\        4       p\        S:R7      p\	        S:R7      pRp\
        P                  R/ 4      pRp\        V\        4      '       d   Tp M^\        V\        4      '       dI   \        VP                  R4      4      o9VP                  RR4      pVP                  RR4      pV'       d   Tp \        P                  ! R4      ;'       g5    \        P                  ! R	4      ;'       g    \        P                  ! R
4      pV'       d   VP                  4       p S9'       g   \        VP                  R4      4      o9\        4       p	S9'       d   V	P                  S94        ^ RIHp
 ^ RIHp V
! 4        Fs  pVP                  R4      '       g   K   V! VR,          4      P                  RR4      pVR8X  d   KE   \        VR,          4      pV'       g   Kb  V	P                  V4       Ku  	  VP                  R4      ;'       g    / P+                  4        F<  p\        V4      pV'       g   K  \-        W/4      '       g   K+  V	P                  V4       K>  	  VP                  R4      ;'       g    / P+                  4        F)  p\        V4      pV'       g   K  V	P                  V4       K+  	  \.        P1                  4        FY  w  pp\2        ;QJ d    V:3R lV 4       F  '       g   K   RM	  RM! V:3R lV 4       4      '       g   KH  V	P                  V4       K[  	  V F/  pVP                  R4      pV'       g   K  V	P                  V4       K1  	  \5        4       pV'       d   V	 Uu0 uF  pVV9   g   K  VkK  	  p	pS9'       d
   S9V9  d   Ro9V Uu. uF  pVP                  R4      V9   g   K  VNK  	  ppVP1                  4        UUu/ uF  w  ppVV9   g   K  VVbK  	  ppp\7        4       pV'       d   V	 Uu0 uF  pVV9  g   K  VkK  	  p	pS9'       d
   S9V9   d   Ro9V Uu. uF  pVP                  R4      V9  g   K  VNK  	  ppVP1                  4        UUu/ uF  w  ppVV9  g   K  VVbK  	  ppp. pV'       d   \9        V4      MRpV'       Ed   VR39   Ed{    ^ RIpVP                  4       pVP=                  R4      '       d   VR,           pMVP?                  R4      R,           p/ pR4pV FD  pS:P                  V4      ;'       g    \        P                  ! V4      p V '       g   K<  RV  2VR&    M	  VP@                  PC                  VRR 7      p!VP1                  4        F  w  p"p#V!PE                  V"V#4       K  	  VP@                  PG                  V!^
R!7      ;_uu_ 4       p$\H        PJ                  ! V$PM                  4       PO                  R"4      4      p%RRR4       . p&R#X%9   d(   \        V%R#,          \P        4      '       d   V%R#,          p&M-R$V%9   d'   \        V%R$,          \P        4      '       d
   V%R$,          p&V& F  p'\        V'\        4      '       g   K  V'P                  RR4      ;'       g-    V'P                  R%R4      ;'       g    V'P                  RR4      p(V'P                  R%R4      ;'       g    V'P                  RR4      ;'       g    T(p)V('       g   K  V)'       g   K  VPS                  RV(R&V)/4       V	P                  V4       K  	  \
        P                  R'. 4      p*\        V*\P        4      '       d   V U+u0 uF  p+V+R,          kK  	  p,p+V* F  p-\        V-\        4      '       g   K  V-P                  RR4      p.V.'       g   K7  V.V,9  g   K@  RV.9   d   V.PU                  R4      R5,          MT.p/VPS                  RV.R&V//4       V,P                  V.4       V	P                  R4       K  	  V	'       Ed   \W        V	V93R( lR)7       EF  p\X        P                  VVP[                  4       4      p0VR*8X  d;   \]        V\_        S:R7      4      p1VPS                  RVRR+R$\a        VV1S94      /4       Ki  V\b        9   d[   \b        V,          p2VR,8X  d   \e        4       ;'       g    T2p2\]        VV24      p2\a        VV2S94      pVPS                  RVRV0R$V/4       K  VV9   dB   \]        VVP                  V. 4      4      p2VPS                  RVRV0R$\a        VV2S94      /4       EK  V'       d2   \]        VV4      p2VPS                  RVRV0R$\a        VV2S94      /4       EKO  VPg                  R4      '       d   EKi  RV R&V PU                  R4      R5,          /p3\i        VV V3R-7      V3R.&   VPS                  RVRV0R$V3./4       EK  	  MPRV 9   d   V PU                  R4      R5,          MT p4RV R&V4/p3\i        RV V3R-7      V3R.&   VPS                  RRRR/R$V3./4       V '       Ed   R0 p5V U6U+u0 uF+  p6V6P                  R$. 4       F  p+V5! V+R,          4      kK  	  K-  	  p7p6p+V5! V 4      V79  Eda   RV 9   d   V PU                  R4      R5,          MT p4Rp8V Ff  p6S9'       g   K  V6P                  R4      S98X  g   K%  RV R&V4/p3\i        V6P                  R4      V V3R-7      V3R.&   V6R$,          Pk                  ^ V34       Rp8 M	  V8'       gW   V'       dO   RV R&V4/p3\i        V^ ,          P                  R4      V V3R-7      V3R.&   V^ ,          R$,          Pk                  ^ V34       MsV'       gl   RV R&V4/p3\i        S9;'       g    RV V3R-7      V3R.&   TPS                  RS9;'       g    RR\X        P                  S9;'       g    RS9;'       g    R/4      R$V3./4       RS9R1V R2V/#   \(         d     E
L)i ; i  \(         d     E
L
i ; iu upi u upi u uppi u upi u upi u uppi   + '       g   i     ELD; i  \(         d     EL!i ; iu up+i u up+p6i )6a  
Return available models grouped by provider.

Discovery order:
  1. Read config.yaml 'model' section for active provider info
  2. Check for known API keys in env or ~/.hermes/.env
  3. Fetch models from custom endpoint if base_url is configured
  4. Fall back to hardcoded model list (OpenRouter-style)

Returns: {
    'active_provider': str|None,
    'default_model': str,
    'groups': [{'provider': str, 'models': [{'id': str, 'label': str}]}]
}
NrP  rc   r  r   defaultrx  HERMES_MODELOPENAI_MODEL	LLM_MODELr   )list_available_providers)get_auth_statusauthenticatedr   
key_sourcezgh auth tokenrn  rr  c              3   F   <"   T F  pSP                  V4      x  K  	  R # 5ir   r  )r   r   rM  s   & r   r   'get_available_models.<locals>.<genexpr>7  s     -u!w{{1~~ur@  TFr   rz  r  r  r  r  r  r  r  )r  r  r  r   r  r5   r   r  c                    < \        V S4      # r   )r   )xr   s   &r   r   &get_available_models.<locals>.<lambda>  s    <NqRa<br   r"  r   r   r   rI  r  Defaultc                     T ;'       g    R p V P                  R4      '       d!   RV 9   d   V P                  R^4      ^,          p RV 9   d   V P                  R^4      R,          p V # )rc   r  rd   r  r   )r   r   )mids   &r   _norm#get_available_models.<locals>._norm  sX    ))C~~c""scziiQ'*cziiQ'+Jr   default_modelgroups>   r|  rz  r   r   )r   r   OPENAI_API_KEYr   r  r   r   )6DEFAULT_MODELr   ri  r  rT  r  r   rS   r   rE   r   r   r   r   r   r  r4  r<  r
  r=  rU   r   rv  r   r  r'  r   r   r  r  r  r  r  r  
add_headerr  rf  rg  r  r  r   r   r   r#  r  r  rL  rQ  r  rS  rR  r   rD  insert);rJ  rK  rk  named_custom_providersnamed_custom_catalogscfg_base_urlr1  cfg_default	env_modeldetected_providers_lap_gas_p_src_pid	_norm_pid_keys_entryallowed_providersr  rK  r   r  hidden_providersauto_detected_modelsendpoint_providerr  rx  r  r  api_key_varsr   rp  r  r   r   r  r   r  r  r-  
model_name_custom_providers_cfgr  _seen_custom_ids_cp	_cp_model	_cp_labelprovider_nameopenrouter_modelsrF  fallback_modelr   rH  gall_ids_norminjectedr   rM  s;                                                            @@r   get_available_modelsro    s     O!MF!G!#J9'JDWU L$IL)S!!!	It	$	$0z1JKmmIr2 }}Z4'M 		.)``RYY~-F``"))T_J`I!) 0@Q1RS
 /F;&B66/**BtH~)),;?* + *"T(3Dt"&&t, ( ,2288:*40	91*HH""9- ;  1288b>>@*40	9""9- A *//1e3-u-333-u---""4( 2 )zz-(4""4( )
 /0-?\-?c3J[C[cc-?\6GG"O5"
5eyy'+<< E5 	 "
 (='B'B'D!
'D#V//  K'D 	 !
 -.-?_-?c3N^C^cc-?_2BB"O5"
5eyy'/?? E5 	 "
 (='B'B'D!
'D#V"22  K'D 	 !
 GS5lCY]|)-VV+	! $))+H  ''')3's3lB GNL#!++c*<<biin718	/BGO,	 $ ..((e(DC1q!$ (''R'88Hzz(--/"8"8"AB 9 K~*T&\4"@"@"6lT!jh&F&F"8n$!%.. 99T2.aa%))FB2Gaa599U\^`Ka"YYvr2XXeii6LXXPX
8

(//x*0UV&**+<= %  GG$6;'..-AB-AAdGG-AB(Cc4((,IyY.>>8;y8HIOOC04i	$++T9gy,QR $$Y/"&&x0 ) ,2bccC-11#syy{CMl"$@4WE%! !3238I?[ 
 ((
 .c2
.(!>!@!N!NJJ9#zJ
-c:O!3f 
 --9#?T?X?XY\^`?ab
!323
OT  (!=cCW!XJMM%s"M "6sJ"X# 
 ^^H--  m!4!4S!9"!=&N 3PPSUbn|2}N;/MM%s"M >"2# q dB 14}0D##C(,-w>&CI}hv&w{#}iYSaRbcd }	 17T1hPR@S1ag@ST|347=4HM'',R0mEH"?quu]';'N&*M7E%JN2Om,%"03N;/
 hK&&q.9#H  "&w!F.K1IMM-0!,/{+
 q	(#**1n="&w!F.K#00y!,/{+
 !?#?#?i 1 5 5o6R6RTcTpTpgp q~.  	?& o  
  6 ]"
!
 `"
!
D 988$  		 C@ Us   :/p  *&o.p  /p  ?	pp*pp"p3p	p"!p">p'p'6p,p,:*q %Aq (q 	A:q 4p27Bq q ,+q q 2q ?q 	*q #q1q.o=9p  <o==p   pp2q	=	q qqstaticz
index.htmlc                      V \         n        R # r   _thread_ctxr  )kwargss   ,r   _set_thread_envru  .  s	    KOr   c                      / \         n        R # r   rr  rI   r   r   _clear_thread_envrw  1  s	    KOr   c                D    V ^8  d   QhR\         R\        P                  /# )r   
session_idr   )r   	threadingLock)r   s   "r   r   r   8  s     / / /	 /r   c                     \         ;_uu_ 4        V \        9  d   \        P                  ! 4       \        V &   \        V ,          uuR R R 4       #   + '       g   i     R # ; ir   )SESSION_AGENT_LOCKS_LOCKSESSION_AGENT_LOCKSrz  r{  )ry  s   &r   _get_session_agent_lockr  8  s:    	!	!00.7nn.>
+":. 
"	!	!	!s   4AA	default_workspacesend_keyentershow_token_usageshow_cli_sessionssync_to_insightscheck_for_updatesthemedarkbot_nameHERMES_WEBUI_BOT_NAMEHermespassword_hashc                $    V ^8  d   QhR\         /# r   rD   )r   s   "r   r   r   M  s      t r   c                 &   / p \         P                  4       '       dc    \        P                  ! \         P	                  RR7      4      p\        V\        4      '       d    \         F  pW!9   g   K  W,          W&   K  	  V # V #   \         d     T # i ; i)zLoad only persisted settings keys from disk.

Older builds stored keys like ``default_model`` in settings.json. Those keys
are now derived from config.yaml and must not leak back into API responses or
be re-persisted forever.
r  encoding)	SETTINGS_FILEr"   rf  rg  rR   rS   rE   _SETTINGS_DEFAULTSrU   )stored_settingsstoredr   s      r   _load_stored_settingsr  M  s     O	ZZ 7 7 7 IJF&$''-C}/5{, .
 ?  		s   AB /B BBc                $    V ^8  d   QhR\         /# r   r   )r   s   "r   r   r   a  s       r   c                    \         p  \        4       pVP                  R/ 4      p\        V\        4      '       d)   VP                  4       '       d   VP                  4       p V # \        V\        4      '       d>   \	        VP                  RR4      ;'       g    R4      P                  4       pV'       d   Tp V #   \         d     T # i ; i)z4Return the effective default model from config.yaml.r  r8  rc   )rM  rJ   r   rS   r   r   rE   rU   )rJ  r  r1  model_values       r   _current_default_modelr  a  s    !M
lGGGR(	i%%)//*;*;%OO-M  	4((immIr:@@bAGGIK +   s*   AB7 B7 "3B7 B7 3B7 7CCc                $    V ^8  d   QhR\         /# r   rD   )r   s   "r   r   r   r  s     	 	t 	r   c                 p    \        \        4      p V P                  \        4       4       \	        4       V R&   V # )zLoad settings from disk, merging with defaults for any missing keys.

``default_model`` is returned as a read-only compatibility field derived
from config.yaml so every UI surface reports the same source of truth.
rJ  )rE   r  rT   r  r  )settingss    r   load_settingsr  r  s1     &'HOO)+, 6 8H_Or   z
ctrl+enterc                0    V ^8  d   QhR\         R\         /# )r   r  r   rD   )r   s   "r   r   r     s     " "D "T "r   c                   ^ RI p\        \        4      pVP                  \	        4       4       V P                  RR4      pV'       d   \        V\        4      '       dx   VP                  4       '       db   \        \        4      P                  4       pVP                  WCP                  4       P                  4       ,           4      P                  4       VR&   V P                  RR4      '       d   RVR&   V P                  4        FK  w  rVV\        9   g   K  V\        9   d   V\        V,          9  d   K1  V\         9   d   \#        V4      pWbV&   KM  	  \$        P'                  \(        P*                  ! VR^R7      RR7       R	V9   d
   VR	,          sR
V9   d/   \/        VR
,          4      P1                  4       P3                  4       s\7        4       pVP9                  R4      VR&   V# )zISave settings to disk. Returns the merged settings. Ignores unknown keys.N_set_passwordr  _clear_passwordF)ensure_asciiindentr  r  rJ  r  )hashlibrE   r  rT   r  r%  rS   r   r   r]   encodesha256	hexdigestr  _SETTINGS_ALLOWED_KEYS_SETTINGS_ENUM_VALUES_SETTINGS_BOOL_KEYSrl  r  
write_textrf  dumpsrM  r   r   r   ri   r  r   )r  _hlcurrentraw_pwsaltr   r   mergeds   &       r   save_settingsr    sy   %&GNN(*+\\/40F*VS))fllnn9~$$&#&::d\\^5J5J5L.L#M#W#W#Y ||%u--#'  &&))a7LQ7O.O''GAJ ! 

7q9   '!0g% )<!=>IIKSSU_F%kk/:F?Mr   r  r8  )init_profile_statec                   V ^8  d   Qh/ ^ \         9   d   \        \        \        3,          ;R&   ^\         9   d
   \        ;R&   ^\         9   d
   \        ;R&   ^\         9   d
   \        ;R&   ^\         9   d   \        P                  ;R&   # )r   r  STREAMSCANCEL_FLAGSr~  SESSIONS)__conditional_annotations__rE   r   collectionsOrderedDict)r   s   "r   r   r      s~     	 	h	 + *d39o *i		J1   K1	N1  d O1	h1  T i1	r5 > =+
!
! =s5	r   )xhighr%  r$  r#  r3  i  @>   r   r   r   r   r   r   r   r   >   .md.mdown	.markdown>   .c.h.go.js.py.rs.sh.ts.cpp.css.csvr   .jsx.log.sql.tsx.txt.xml.yml.bash.html.javar   .toml.yaml)browserclarifycode_executioncronjob
delegationfile	image_genmemorysession_searchskillsterminaltodowebwebhook)r   r   r   r   r   r   r   r   r   r   r   r   rz  r   r   r   r|  )ANTHROPIC_API_KEYANTHROPIC_TOKEN)rL  )r  )GOOGLE_API_KEY)GLM_API_KEY)KIMI_API_KEYCUSTOM_API_MOONSHOT_AI_API_KEY)DEEPSEEK_API_KEYCUSTOM_API_DEEPSEEK_COM_API_KEY)MISTRAL_API_KEY)BLOCKRUN_API_KEY)MINIMAX_API_KEY)MINIMAX_CN_API_KEY)r3  r#  r$  r%  r  >   mistral-small-2603mistral-small-latestmistral-vibe-cli-fast)z
magistral-zlabs-leanstral-r   >   r  r  r  r  )r  __doc__r  rf  r   sysrz  r  	tracebackuuidpathlibr   urllib.parser   r   homer   __file__r!   r   r    r   rj   r  rk   r   r   r]   SESSION_DIRWORKSPACES_FILESESSION_INDEX_FILEr  LAST_WORKSPACE_FILEPROJECTS_FILEr&   r7   rg   rh   r%   r   rn   hermes_constantsr9   rU   rG   r{  rN   rB   rJ   rH   r  r_   ri   rM  rs   r   MAX_FILE_BYTESMAX_UPLOAD_BYTES
IMAGE_EXTSMD_EXTS	CODE_EXTSMIME_MAP_DEFAULT_TOOLSETSr   CLI_TOOLSETSr,  r   _DYNAMIC_MODEL_CACHE_TTL_SECONDSr  r   r   rS  ru   r  rA  rB  r   r   r   r   r   r   r  r  r*  r6  rD  rL  rU  r^  rc  ri  rv  r  r  r  r  r  rT  r  r  r  rR  rQ  rX  ro  _INDEX_HTML_PATHLOCKSESSIONS_MAX	CHAT_LOCKr  STREAMS_LOCKr  SERVER_START_TIMEr|  rs  ru  rw  r~  r}  r  r  r  r  r  r   r   r  r  r  r  _startup_settingsr"   _cfg_startup_mrS   rE   r   r  r  r?   r  r@   r   )r  s   @r   <module>r     s
  	   	 
      + ))+N!!((002	 
yy$k2
299(&12 y7"#  :<	 

 "J.!$55#m3 !O3!$88 !O3'T#N !"
j)
" 
:chh&J(MML8
 
NN		0 /  01 II:<QR!
F0& #  P
+Q	 ;|W\
;
>6+
g&8	 
 | 3R8<<UDUV t%6RY[opt%=RY[vwt%<RY[  At%?RY[xyt%>RY[wxt%MRY  \A  Bt%PRY  \A  B  )+  *#&  

M
'
7BK
h
&
8ACS
 
<
 '(9
 <Fz
 y	

 
 '
 y
 #H
 /;L
 =
 #,Y
 h
K
   9!)!	EG#%#)   	 W.?@	"W.AB	"W.AB	!W.@A	 	~w7	xw1	tw-	yw	2	 	Wo>	Wo>	"W.AB	#W.BC	 	*:; 	1EF	"1IJ 	#w0DE	$w0EF	%w0FG
 
	yWi8	wWg6	}Wm<	yWi8	yWi8	Wo> 	 '3DE	{+>	!2DE	'2JK	&2IJ	%.A	%.A	!2DE	 2CD	2BC	!2DE 	~.A	'2JK	~.A	'2JK	~.A 	yGY7	~G^<	xGX6	 G->?	"G-@A	G-=> 	7,<=	!7,>?KI V  %  F %%  F     
% !1" "(V"C	BLd  &8&3. 3.l  	8a  	a a8-
  - -6 ($N Kk 0M88 88v? ?D &d*:=DNS NSb26j|@
 x',6  NN$NN$	 NN$ IIK  oo   %NN, / ./V		18<T ("	 /4467?:KK ,'  i "J "O 011 !23F!GHSSU]]_	<L			'2	&B"dVVIr""crxxzz

 %0$;$;$= =	/O1  LKLz0  		  		sH   ;\ =(\( &!\( \( \( \5 
\%$\%(\21\25] ?] 