
    i                       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Zddl	m
Z
 ddlmZmZ  e
j                    Z e
e          j        j                                        Z ej        dd          Z e ej        dd                    Z e
 ej        d	 eed
z  dz                                                                                                Zedz  Zedz  Zedz  Zedz  Zedz  Zedz  Z de
fdZ!de
defdZ" e!            Z# e"e#          Z$e#8 ee#          ej%        vr#ej%        &                     ee#                     dZ'ndZ'	 ddl(m)Z) n# e*$ r dZ)Y nw xY wi Z+ ej,                    Z-de
fdZ.de/fdZ0ddZ1 e1             e+Z2de
fdZ3 e3            a4 ej        dd          a5dd Z6de7fd!Z8d"Z9d#Z:h d$Z;h d%Z<h d&Z=d'd(d(d)d*d+d,d-d.d/d0
Z>g d1Z? e0            @                    d2i           @                    d3e?          ZAd4d5d6d7d4d8d9d7d4d:d;d7d4d<d=d7d4d>d?d7d4d@dAd7d4dBdCd7gZBi ZCe/ee/f         eDdD<   dEZEi dFdGdHd4dIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdiZFg djZGdkdldmdndodpdqdrdsdtdudvZHdwdxdydzd{dyd|d}dyd~ddygdddydddydddydddygdddydddydddydddygdddygdddydddygdddydddydddygdddydddydddydddydddydddygdddydddydddydddydddydddydddydddydddydddydddygdddydddydddydddydddygdddydddydddydwdxdydzd{dydddygdddydddygdʜZI e7d˄ dD                       ZJh dͣZKdZLdedz  dedz  fdЄZMddededz  de7fd҄ZNde/fdӄZOde/fdԄZPdeQe         dz  fdՄZRdeQe         fdքZSdeTe         fdׄZUdddٜdedede/fd܄ZVde/dz  fd݄ZWdedeTe         fd߄ZXddedz  dede/dz  de/fdZYdedz  deTe/         deTe/         fdZZdddedz  dede/dz  de/dz  fdZ[	 ddddededz  de/dz  de/fdZ\	 ddddedededz  de/dz  def
dZ]de/fdZ^de/dede_fdZ`dedefdZaeEfdededeTe/         fdZbde_fdZcdddedededeTe/         fdZddde/dz  deTe/         fdZedde/dz  de/eeTe/         f         fdZfdedz  de_fdZgdedeTe/         dedz  deTe/         fdZhdedefdZideTe/         fdZjdde/dz  deTe/         fdZkdede7fdZlde/fdZmedz  d z  Zn ej,                    ZodZp ej,                    Zqi Zre/eDd<    ej,                    Zsi Zte/eDd<    ej                    Zu ejv                    Zwd Zxd Zyi Zze/eDd<    ej,                    Z{dedej,        fdZ| eth                    d	ddddd
 ej        dd          dd	Z}de/fdZ~defdZde/fdZ eQe}                                          dhz
  Zdd	dhiZh dZde/de/fdZ e            Ze                                rLe@                    d          r6 e
ed                                                                                   a4	  e0            Ze@                    di           Z eee/          re@                    ddئ          Z eee          r(e                                re                                a5n# e*$ r Y nw xY w ej                    Zej        eDd<   	 ddlmZ  e             dS # e$ r Y dS w xY w(  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.jsonreturnc                  n   g } t          j        d          rX|                     t          t          j        d                                                                                               t          j        dt          t          dz                      }|                     t          |                                          dz             |                     t          j	        dz             t          j	        dz  
                                r|                     t          j	                   |                     t          dz  dz             |                     t          dz             | D ]C}|
                                r-|dz  
                                r|                                c S DdS )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      '/home/ubuntu/hermes-webui/api/config.py_discover_agent_dirr    -   s    J 
y)** \$ry)ABBCCNNPPXXZZ[[[ )M3ti/?+@+@AAKd;''2244~EFFF i&7888 	>)1133 ,)*+++ dY&7888 d^+,,, " ";;== 	"d^3;;== 	"<<>>!!!4    	agent_dirc                    t          j        d          rt          j        d          S | r\| dz  dz  dz  }|                                rt          |          S | dz  dz  dz  }|                                rt          |          S t          dz  dz  dz  }|                                rt          |          S dd	l}d
D ]}|                    |          }|r|c S dS )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.venvr   N)python3r'   r)   )r   r   r   r   r   shutilwhich)r"   venv_pyvenv_py_win
local_venvr*   namefounds          r   _discover_pythonr1   W   s    
y&'' 0y./// $f$u,x7>> 	 w<<  &(94|C 	${### W$u,x7J : MMM%  T"" 	LLL	 9r!   TFVALID_REASONING_EFFORTS)xhighhighmediumlowminimalc                      t          j        d          } | r!t          |                                           S 	 ddlm}  |            dz  S # t          $ r t          dz  dz  cY S w xY w)z/Return config.yaml path for the active profile.HERMES_CONFIG_PATHr   get_active_hermes_homezconfig.yamlr   )r   r   r   r   api.profilesr<   ImportErrorr   )env_overrider<   s     r   _get_config_pathr@      s    9122L /L!!,,...0777777%%''-77 0 0 0i-////0s   A A&%A&c                  :    t           st                       t           S )z;Return the cached config dict, loading from disk if needed.)
_cfg_cachereload_config r!   r   
get_configrE      s     r!   c                     t           5  t                                           t                      } 	 ddl}|                                 rV|                    |                                           }t          |t                    rt          
                    |           n# t          $ r Y nw xY wddd           dS # 1 swxY w Y   dS )z7Reload config.yaml from the active profile's directory.r   N)	_cfg_lockrB   clearr@   yamlr   	safe_load	read_text
isinstancedictupdate	Exception)config_path_yamlloadeds      r   rC   rC      s   	 
 
&((	    !!## .)>)>)@)@AAfd++ .%%f--- 	 	 	D	
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
s5   (B=A.B B= 
B-*B=,B--B==CCc                  P   t          j        d          rEt          t          j        d                                                                                    S t
          dz  } |                                 r|                                 S t          dz                                  S )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_workspacerX      s     
y122 XBI>??@@KKMMUUWWWKF}}  ~~#,,...r!   HERMES_WEBUI_DEFAULT_MODELzopenai/gpt-5.4-minic                     d} d}d}ddddt            dt          rt          nd	 d
t          r| n| dt           dt           dt           dt
           dt           dt                       d
t                                                      rdnd dg}t          d
                    |          d           t          st          | dd           dS dS )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_EXErV   DEFAULT_WORKSPACEHOSTPORTr@   r   printjoin_HERMES_FOUND)okwarnerrliness       r   print_startup_configrk      s1    B D C 	+,&9&&cD::ccjHa^acc':''&9&&.,..(4(($((~+--~~>N>P>P>W>W>Y>Y1|_|~~
E 
$))E

$'''' 
 F F F 	
 	
 	
 	
 	
 	

 
r!   c                      dg} g }i }| D ]Z}	 t          |           # t          $ r;}|                    |           t          |          j         d| ||<   Y d}~Sd}~ww xY wt          |          dk    ||fS )zw
    Attempt to import the key Hermes modules.
    Returns (ok: bool, missing: list[str], errors: dict[str, str]).
    	run_agentz: Nr   )
__import__rO   r   type__name__len)requiredmissingerrorsmodes        r   verify_hermes_importsrw      s    
 }HGF 5 5	5sOOOO 	5 	5 	5NN3 "!WW-4444F3KKKKKK		5
 LLA//s   
A"1AA"i@ i  @>   .bmp.gif.ico.jpg.png.svg.jpeg.webp>   .md.mdown	.markdown>   .c.h.go.js.py.rs.sh.ts.cpp.css.csv.jsx.log.sql.tsx.txt.xml.yml.bash.html.java.toml.yaml.env.jsonz	image/pngz
image/jpegz	image/gifzimage/svg+xmlz
image/webpzimage/x-iconz	image/bmpzapplication/pdfapplication/json)
r|   r{   r~   ry   r}   r   rz   rx   z.pdfr   )browserclarifycode_executioncronjob
delegationfile	image_genmemorysession_searchskillsterminaltodowebwebhookplatform_toolsetscli
OpenRouteropenrouter/freeAuto (Free Router))provideridlabelz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)_DYNAMIC_MODEL_CACHEi,  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Ollamaz	LM Studio)ollamalmstudio)r   r   r   r   r   r   r   r   r   r   r   r   customr   r   r   local)ANTHROPIC_API_KEYANTHROPIC_TOKEN)OPENAI_API_KEY)OPENROUTER_API_KEY)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)r   r   r   r   r   r   r   r   r   r   z
minimax-cnzclaude-opus-4.6zClaude Opus 4.6r   r   z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.4zgemini-2.0-flashzGemini 2.0 Flash)r   r   r   r   r   r   r   r   r   r   geminic              #   ,   K   | ]}|t           v |V  d S Nr2   ).0efforts     r   	<genexpr>r     s:          ((( ((((   r!   )r8   r7   r6   r5   r4   >   mistral-small-2603mistral-small-latestmistral-vibe-cli-fast)z
magistral-zlabs-leanstral-provider_idc                     | pd                                                                 } | sd S dddddd}|                    | |           S )Nr[   r   r   r   r   )codexmoonshotkimiz	deep-seek
clawrouter)striplowerget)r   aliasess     r   _normalize_provider_idr     sb    $"++--3355K t!  G ;;{K000r!   active_providerc                     t          |           pd} t          |          }|r
| |k    rd| fS 	 t                              |           | fS # t          $ r d| fcY S w xY w)Nr[   i  )r   _PROVIDER_SORT_ORDERindex
ValueError)r   r   s     r   _provider_sort_keyr     s    (55;K,_==O !;/99K  "$**;77EE " " "[!!!!"s   A
 
AAc                     t           dz  dz  } 	 ddlm}  |            dz  }n# t          $ r | }Y nw xY wi }| |fD ]}|                                s	 |                                                                D ]}|                                }|r|                    d          sld|v rh|	                    dd          \  }}|                                                    d                              d	          ||                                <   # t          $ r Y w xY wd
 t                                          D             h dz  }|D ]}	t          j        |	          }
|
r|
||	<   |S )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   r   r   r;   #=   "'c                     h | ]	}|D ]}|
S rD   rD   )r   keyskeys      r   	<setcomp>z$_load_profile_env.<locals>.<setcomp>  s?          	   r!   >   API_KEYLOCAL_API_KEYHERMES_API_KEYHERMES_OPENAI_API_KEY)r   r=   r<   r>   r   rK   
splitlinesr   
startswithsplitrO   _PROVIDER_ENV_KEYSvaluesr   r   )main_env_path_gahprofile_env_pathdatar   linekvinterestingr  vals              r   _load_profile_envr    s    9$v-M)??????466F? ) ) )() D 01 
 
{{}} 		((3355 F Fzz|| F 4 4 F::c1--DAq&'ggiiooc&:&:&@&@&E&EDO	F
  	 	 	D	 &--//  	 	 		K   inn 	DIKs   # 22C D
D! D!c                     t           dz  } i }|                                 s|S 	 |                                                                 D ]}|                                }|r|                    d          sld|v rh|                    dd          \  }}|                                                    d                              d          ||                                <   n# t          $ r Y nw xY w|S )z9Read repo-local .env overrides used by the WebUI service.r   r   r   r  r  r  )r   r   rK   r  r   r  r  rO   )env_pathr  r  r  r  s        r   _load_repo_envr    s    6!HD?? &&((3355 	B 	BD::<<D BDOOC00 BSD[[zz#q))1"#''))//#"6"6"<"<S"A"AQWWYY		B
    Ks   C C% %
C21C2c                      t          j        d          } | s"t                                          dd          } | sd S d |                     d          D             }d |D             S )NHERMES_WEBUI_ALLOWED_PROVIDERSr[   c                 n    h | ]2}t          |                                          #t          |          3S rD   r   r   r   r   parts     r   r  z)_get_allowed_providers.<locals>.<setcomp>  sF       t99??t$$  r!   ,c                     h | ]}||S rD   rD   r   r   s     r   r  z)_get_allowed_providers.<locals>.<setcomp>  s    BBBKkBKBBBr!   r   r   r  r   r  )rawalloweds     r   _get_allowed_providersr*    s    
)4
5
5C I""#CRHH t IIcNN  G
 CB7BBBBr!   c                      t          j        d          } | s"t                                          dd          } d |                     d          D             }d |D             S )NHERMES_WEBUI_HIDDEN_PROVIDERSr[   c                 n    h | ]2}t          |                                          #t          |          3S rD   r!  r"  s     r   r  z(_get_hidden_providers.<locals>.<setcomp>  sF       t99??t$$  r!   r$  c                     h | ]}||S rD   rD   r&  s     r   r  z(_get_hidden_providers.<locals>.<setcomp>"  s    AAAK[AKAAAr!   r'  )r(  hiddens     r   _get_hidden_providersr0    sv    
)3
4
4C H""#BBGG IIcNN  F
 BA6AAAAr!   c                     t                      | pg D ]U}t          |pd                                                                          }|t          v r                    |           Vfdt          D             S )Nr[   c                     g | ]}|v |	S rD   rD   )r   r   seens     r   
<listcomp>z0_normalize_reasoning_options.<locals>.<listcomp>+  s    KKKvFdNNFNNNr!   )setr   r   r   r3   add_REASONING_EFFORT_ORDER)optionsr(  r   r3  s      @r   _normalize_reasoning_optionsr9  %  s    UUD}"  SYB%%''--//,,,HHVKKKK!8KKKKr!   r[   r8  notemoder;  c                   t          | pd                                                                          pd} t          |          }dg}| dk    r+|                    d           |                    |           n"| dk    r|                    d           n| dvrd} | |t          |pd                                          | dvdS )	Nunsupportedr[   r   nonetoggle>   modelr>  >   r   r@  )r<  r8  r;  disabled)r   r   r   r9  r   extend)r<  r8  r;  normalized_optionsr  s        r   _reasoning_metadatarE  .  s    t$}%%++--3355FD5g>>TFxf())))			f	-	-	-DJB%%'' 44	  r!   c                     d | pg D             }|sd S t          d |D                       rt          ddd          S t          d |D                       rt          dd	
          S d S )Nc                     h | ]n}t          |pd                                           %t          |pd                                                                                               dd          oS )r[   -_)r   r   r   replacer   items     r   r  z@_reasoning_metadata_from_supported_parameters.<locals>.<setcomp>B  sv       tzr??  ""DJB%%''//S99  r!   c              3   &   K   | ]}d |v pd|v V  dS )reasoning_effortzreasoning.effortNrD   rK  s     r   r   z@_reasoning_metadata_from_supported_parameters.<locals>.<genexpr>J  s3      
[
[%C);t)C
[
[
[
[
[
[r!   r   r7   r6   r5   zGThis provider reports explicit reasoning-effort controls for the model.r:  c              3   X   K   | ]%}|d k    p|dk    p|                     d          V  &dS )	reasoninginclude_reasoningz
reasoning.Nr  rK  s     r   r   z@_reasoning_metadata_from_supported_parameters.<locals>.<genexpr>P  s_          	 	)&&	)??<((     r!   r@  zOThis model exposes reasoning as an on/off toggle, not a low/medium/high ladder.r;  )anyrE  )supported_parameters
normalizeds     r   -_reasoning_metadata_from_supported_parametersrX  A  s     )/R  J
  t

[
[PZ
[
[
[[[ 
"-Z
 
 
 	

    	     	
 #b
 
 
 	
 4r!   model_idc                 x   	 ddl m}  ||           }n# t          $ r g }Y nw xY wt          |          }|r|S t	          | pd                                                                          }|                    d          rt          d          S |                    d          sd|v rt          d          S g S )	Nr   )github_model_reasoning_effortsr[   )z	openai/o1z	openai/o3z	openai/o4o1r   o4rO  zgpt-5z/gpt-5)r8   r7   r6   r5   )hermes_cli.modelsr[  rO   r9  r   r   r   r  )rY  r[  effortsrW  r(  s        r   $_copilot_reasoning_efforts_for_modelr`  ]  s    DDDDDD00::    .g66J 
hn"


#
#
%
%
+
+
-
-C
~~OPP G+,EFFF
~~g R(c//+,PQQQIs    ##	raw_entryc                 ~   t          |           pd} t          |pd                                          }|                                | dk    rdk    rt	          dd          S | dk    s*                    d          s                    d	          rt	          d
d          S | dk    rdv rt	          d
d          S t          |          }|rt	          d|          S d }d }t          |t                    r7t          |
                    d                    }|
                    d          }||S t          |t                    r(|
                    d          du rt	          dd          S t          v s t          fdt          D                       rt	          dd          S t	          d          S )Nr[   r   r   r>  zdOpenRouter Auto (Free) can route across multiple models, so reasoning controls are unavailable here.rT  r   r   r   rA  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   )r8  rV  capabilitiesrQ  Tr@  z[This model supports reasoning on or off, but does not expose low/medium/high effort levels.c              3   B   K   | ]}                     |          V  d S r   rS  )r   prefix	raw_lowers     r   r   z0_reasoning_metadata_for_model.<locals>.<genexpr>  s1      \\y##F++\\\\\\r!   z:This Mistral model supports reasoning as an on/off toggle.)r   r   r   r   rE  r  r`  rL   rM   rX  r   _MISTRAL_REASONING_MODEL_IDSrU  !_MISTRAL_REASONING_MODEL_PREFIXES)r   rY  ra  r_  supported_metard  rg  s         @r   _reasoning_metadata_for_modelrk  p  s    (55;K8>r""((**H  Il""y4E'E'E"w
 
 
 	

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

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

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

 }---r!   
raw_modelsc                 F   t          |           } g }|pg D ]}t          |t                    st          |                    d          pd                                          }|sQt          |          }t          | ||          |d<   |                    |           |S )Nr   r[   ra  rQ  )r   rL   rM   r   r   r   rk  r   )r   rl  	annotatedr(  rY  entrys         r   _annotate_reasoning_metadatarq    s    (55KIR    #t$$ 	swwt}}*++1133 	S		:;\abbbkr!   all_envrs  c                f   t          |           } t          |pd                                          }| r|sd S | dk    rt          |          }ny| dk    r*t	                      pt
                              | g           }nI| t
          v rt
                              | g           }n$t          |                              | g           }|pg D ]c}t          |t                    st          |                    d          pd                                          |k    rt          |          c S dd S )Nr[   r   rr  r   r   )
r   r   r    _discover_openrouter_free_models_discover_codex_model_entries_PROVIDER_MODELSr   (_discover_named_custom_provider_catalogsrL   rM   )r   rY  rs  rl  r(  s        r   _lookup_model_catalog_entryry    sF    )55K8>r""((**H h tl""5gFFF

		&	&244]8H8L8L[Z\8]8]

	(	(	(%))+r::

=gNNNRRS^`bcc
R  #t$$ 	swwt}}"##))++x7799 84r!   c                .   t          | pd                                          }|}t          |          }|r<	 t          |          \  }}}|r|}|s|rt          |          }n# t          $ r Y nw xY wt          |||          }	t          |||	          S )Nr[   rr  rn  )r   r   r   resolve_model_providerrO   ry  rk  )
rY  r   rs  selected_modelresolved_modelresolved_provider_model	_providerrI  ra  s
             r   get_model_reasoning_metadatar    s     R((..00N#N.{;; 	#9.#I#I FIq (!'$ F F$:9$E$E! 	 	 	D	 ,  I
 )):NV_````s   *A# #
A0/A0rN  c                   t          |pd                                                                          }|sdS t          | ||          }|                    d          rdS d |                    d          pg D             }||v r|ndS )Nr[   )r   rs  rB  c                     h | ]Z}t          |pd                                           %t          |pd                                                                           [S )r[   )r   r   r   rK  s     r   r  z)clamp_reasoning_effort.<locals>.<setcomp>   sf       tzr??  ""DJB%%''  r!   r8  )r   r   r   r  r   )rY  rN  r   rs  valuemetar)  s          r   clamp_reasoning_effortr    s      &B''--//5577E r'  D
 xx
 r XXi((.B  G
 W$$55",r!   c                  6   	 ddl m}   |             dz  }n# t          $ r t          dz  dz  }Y nw xY w|                                si S 	 t          j        |                                          }t          |t                    r|ni S # t          $ r i cY S w xY w)Nr   r;   z	auth.jsonr   )r=   r<   r>   r   r   jsonloadsrK   rL   rM   rO   )r  auth_store_pathr  s      r   _load_auth_storer    s    9??????$&&;. 9 9 9*[89 !!## 	z/335566!$--5tt25   			s    00
>B	 	BB
auth_storec                 $   t          |          pd}|                     d          pi }|                    |          }t          |t                    r|                    d          s?|                    d          s*|                    d          s|                    d          rdS |                    d          s|                    d	          rdS |rdS n|rdS |                     d          pi }||v r|                    |          rdS d
S )Nr[   	providerstokensapi_keyr  api_keysTcredential_pooloauthF)r   r   rL   rM   )r  r   r  statepools        r   _auth_store_has_providerr    s)   (55;K{++1rIMM+&&E% 99X 	%))I"6"6 	%))E:J:J 	eiiXbNcNc 	499&'' 	599W+=+= 	4 	4		 t>>+,,2Ddtxx44t5r!   base_urlc                    | pd                                 } | sdS t          d| v r| nd|            }|j        p|j        p|j        pd                                }d}|D ]\  }}||v r|c S |j        r	 dd l}|                    |j                  }|j        s|j	        s|j
        rd|v s	|j        dv rdS d	|v sd
|v rd	S dS n=# t          $ r0 |                    d          s|                    d          rY dS Y nw xY wdS )Nr[   r   z://zhttp://))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   >   	localhostr   r   z	lm-studior   r  z.local)r   r   hostnamenetlocr   r   	ipaddress
ip_address
is_privateis_loopbackis_link_localr   r  endswith)r  parsedhost
hosted_mapneedler   r  addrs           r   _infer_provider_from_base_urlr  ,  s   B%%''H x%8"3"3hh9M89M9MNNFOAv}AArHHJJD	J  *  T>>   	''88D $"2 d6H t##v:T'T'T#8%%)<)<%:w  	 	 	{++ t}}X/F/F ww 	 8s   6A C 8C 4C?>C?	cache_keyttl_secondsc                    t          j                     }t                              |           }|r=||                    dd          z
  |k     r d |                    dg           D             S 	  |            pg }n# t          $ r g }Y nw xY w|r%d |D             }||dt          | <   d |D             S |r d |                    dg           D             S g S )	Ntsr   c                 ,    g | ]}t          |          S rD   rM   rK  s     r   r4  z._load_cached_model_catalog.<locals>.<listcomp>W      @@@tT

@@@r!   modelsc                 ,    g | ]}t          |          S rD   r  rK  s     r   r4  z._load_cached_model_catalog.<locals>.<listcomp>_  s    ///$t**///r!   )r  r  c                 ,    g | ]}t          |          S rD   r  rK  s     r   r4  z._load_cached_model_catalog.<locals>.<listcomp>d  s    ...tT

...r!   c                 ,    g | ]}t          |          S rD   r  rK  s     r   r4  z._load_cached_model_catalog.<locals>.<listcomp>g  r  r!   )timer   r   rO   )r  loaderr  nowcachedfreshr  s          r   _load_cached_model_catalogr  S  s   
)++C!%%i00F A3D!,,,;;@@vzz(B'?'?@@@@B     //////+
 +
Y' /.v.... A@@vzz(B'?'?@@@@Is   .A; ;B
	B
c                 H    t          |                                           dv S )N>   0.00.000.0000.0000r[   0)r   r   )r  s    r   _looks_like_free_pricer  k  s     u::!LLLr!   )r  r  c                       pd                                                     d            sg S dt          t                   f fd}t	          ||          S )Nr[   /r   c                     dd l }                     d          r dn d}ddi}pd                                }|r|dk    rd	| |d
<   | j                            ||d          }| j                            |d          5 }t          j        |                                	                    d                    }d d d            n# 1 swxY w Y   g }t          |t                    r}t          |                    d          t                    r|                    dg           }n>t          |                    d          t                    r|                    dg           }t                      }g }	|D ]}
t          |
t                    rt          |
                    d          p+|
                    d          p|
                    d          pd                                          }t          |
                    d          p|
                    d          p|                                          }|
                    d          pi }|
                    d          pg }t          |t                    r|                    d          du r n)t          |
pd                                          }|}i }g }|r||v rR|                    |           ||p|d}t          |t                    r|rt          |          |d<   t          |t                    r|rt          |          |d<   |	                    |           |	S )Nr   /v1/models
/v1/modelsAcceptr   r[   zno-key-requiredBearer AuthorizationGET)headersmethod
   timeoututf-8r  r  r   r/   rA  rd  rV  completion_chatFr   )urllib.requestr  r   requestRequesturlopenr  r  readdecoderL   rM   r   listr5  r   r6  r   )urllibendpoint_urlr  tokenreqresponsepayloadmodels_listr3  entriesrL  rY  r   rd  rV  rp  r  r  s                   r   _loadz1_discover_openai_compatible_models.<locals>._loady  s   /7/@/@/G/Gd(++++PXMdMdMd/0B%%'' 	9U///'8'8'8GO$n$$\75$QQ^##C#44 	Bj!7!7!@!@AAG	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B gt$$ 	8'++f--t44 8%kk&"55GKK11488 8%kk(B77  	" 	"D$%% *txx~~\&1A1A\TXXgEVEV\Z\]]cceeDHHV,,M0A0AMXNNTTVV#xx77=2'+xx0F'G'G'M2$lD11 l6F6FGX6Y6Y]b6b6btzr??0022 !')$ x4//HHX#e.?x@@E,-- ;, ;(,\(:(:n%.55 K:N K045I0J0J,-NN5!!!!s   :CCC)r   rstripr  rM   r  )r  r  r  r  s   ``  r   "_discover_openai_compatible_modelsr  o  sw     B%%''..s33H 	,4: , , , , , , ,\ &i777r!   c                 $   | pt                      }t                              dg           }t          |t                    sg }t                              di           }t          |t
                    r|                                D ]\  }}t          |t
                    s|                    |                    d|          |                    dd          |                    dd          |                    dd          d           g }t                      }|D ]o}t          |t
                    st          |                    d          pd          
                                }	t          |                    d	          pd          
                                                    d
          }
|	r|
st          |	          }|s|	                                                    d          r||v r|                    |           t          |                    d          pd          
                                }|snt                               |d          D ]R}t          |                    |          pt#          j        |          pd          
                                }|r|} nS|                    ||	t&                              ||	                    dd                              dd                                                    |
|t          |                    d          pd          
                                t          |                    d          pd          
                                d           q|S )Ncustom_providersr  r/   apir[   r  	transport)r/   r  r  api_moder  r  zcustom-api-rD   rH   rI  r  rA  )r   r/   r   r  r  r  rA  )r  cfgr   rL   r  rM   itemsr   r5  r   r   r  r   r   r  r6  r  r   r   _PROVIDER_DISPLAYrJ  title)rs  envr  providers_dictpidr(  r  r3  ra  raw_namer  r   r  r  	candidates                  r   _load_named_custom_providersr    su   

(&((Cww1266&--  WW["--N.$'' 
&,,.. 		 		HCc4(( ##,,GGE2..779b11GGK44	% %     GUUD% & &	)T** 	y}}V,,23399;;y}}Z006B77==??FFsKK 	x 	,X66 	 >>&&}55 	$immI..4"55;;== 	)--k2>>   D	# D"EEKKMM	 'GE 	&)--k8;K;KCQT;U;U;];]^acf;g;g;m;m;o;opp IMM*55;<<BBDDw//5266<<>>
 
 	 	 	 	 Nr!   c                    i }t          |           D ]}t          |                    dd          |                    dd          d|                    dd           d|                    dd                     }|                    d	d          }|r&|d
 |D             vr|                    ||d           |r|||d         <   |S )Nrr  r  r[   r  znamed-custom:r   r\   )r  r  r  rA  c                     h | ]
}|d          S r   rD   r   ms     r   r  z;_discover_named_custom_provider_catalogs.<locals>.<setcomp>  s    8Q8Q8QQ48Q8Q8Qr!   r   )r  r  r   r   )rs  catalogsrp  r  configured_models        r   rx  rx    s    &(H-g>>> 4 43YYz2..IIi,,`eiir&B&B``UYYz[]E^E^``
 
 
 !99Wb11 	O 08Q8Q&8Q8Q8Q Q QMM!1<LMMNNN 	4-3HU=)*Or!   c                 x     t                       sdS t           fdt                      D                       S )NFc              3   J   K   | ]}|                     d           k    V  dS )r   Nr   )r   rp  r   s     r   r   z,_provider_is_named_custom.<locals>.<genexpr>  s4      cc5uyy'';6ccccccr!   )r   rU  r  r   s   `r   _provider_is_named_customr    sG    (55K uccccD`DbDbccccccr!   c                    t          |           pd} t          |          }g }|pg D ]}t          |t                    st          |                    d          pd                                          }|sQ|}| r#| |k    r|                    d          sd|  d| }t          |          }||d<   t          |                    d          p|                                          p||d<   |                    |           |S )Nr[   r   @r\   r   )r   rL   rM   r   r   r   r  r   )r   rl  r   r  r(  rY  	routed_idrp  s           r   _with_provider_hintsr    s#   (55;K,_==OFR  #t$$ 	swwt}}*++1133 		 	5;/99(BUBUVYBZBZ94K44(44IS		dSWWW--9::@@BBNhgeMr!   c                    | pd                                 }|s|S |                    dd          }dddddd	d
}g }|                    d          D ]}|                                }||v r|                    ||                    7|rR|d         dk    rF|dd                              dd                                          r|                    |           |                    dd                                          r|                    |           |                    |                                r|                                n|                                           t          |          dk    rQ|d         dk    rE|d                             dd                                          rd|d          g|dd          z   }d
                    |          S )Nr[   rI  rH  GPTOSSCodexMiniMaxSpark)gptossr   minimaxsparkr   or  .   zGPT-r  )r   rJ  r  r   r   isdigitisupperupper
capitalizerq   re   )rY  r(  specialpartsr  r7   s         r   _format_codex_model_labelr    s   >r
 
 
"
"C 

++c3

C G E3 	S 	Skkmm'>>LL&&&& 	SSVs]]s122wsB'?'?'G'G'I'I]LL[[b!!))++ 	SLLLL%--//Qu?O?O?Q?QRRRR
5zzQ58u,,q1A1A#r1J1J1R1R1T1T,"a""#eABBi/88E??r!   c                  N    dt           t                   fd} t          d|           S )Nr   c                     d } 	 ddl m}  |            }|                    d          } n# t          $ r d } Y nw xY w	 ddlm}  ||           }n# t          $ r g }Y nw xY wt                      }g }|pg D ]m}t          |t                    s|	                                }|r||v r3|
                    |           |                    |t          |          d           n|S )Nr   )!resolve_codex_runtime_credentialsr  )get_codex_model_ids)access_tokenr   )hermes_cli.authr  r   rO   hermes_cli.codex_modelsr  r5  rL   r   r   r6  r   r  )r  r  credsr  	model_idsr3  r  rY  s           r   r  z,_discover_codex_model_entries.<locals>._load9  s[   	 IIIIII5577E 99Y//LL 	  	  	 LLL	 	CCCCCC++FFFII 	 	 	III	  !R 
	 
	Hh,, ~~''H x4//HHXNN28<<      s   %* 99A AAr   )r  rM   r  )r  s    r   rv  rv  8  s3    4:    < &ne<<<r!   c                     | pt                      dt          t                   ffd}t          d|          }|r|S d t          D             S )Nr   c            	         dd l } ddi}                    d          pt          j        d          }|rd| |d<   | j                            d|          }| j                            |d	
          5 }t          j        |	                                
                    d                    }d d d            n# 1 swxY w Y   g }t                      }t          |t                    r|                    dg           ng D ]}t          |t                    st          |                    d          pd                                          }	|	r|	|v rV|                    d          pi }
t!          |
                    d                    r"t!          |
                    d                    s|                    d          pi }d |                    d          pg D             }d |                    d          pg D             }d|vsd|vsd|v r|                    |	           t          |                    d          pd                                          }|	dk    rd}n|p|	}d |                    d          pg D             }|                    |	|d|v rdndt'          |          d            d!d"h}t          |t                    r|                    dg           ng D ]}t          |t                    st          |                    d          pd                                          }	|	r|	|v s|	|vrY|                    |	           t          |                    d          pd                                          }|                    |	|p|	d#           |                    d$ %           |D ]}|                    d&d            |S )'Nr   r  r   r   r  r  z#https://openrouter.ai/api/v1/models)r     r  r  r  r   r[   pricingprompt
completionarchitecturec                 P    h | ]#}t          |                                          $S rD   r   r   r   r  s     r   r  zB_discover_openrouter_free_models.<locals>._load.<locals>.<setcomp>w  s&    QQQc!ffllnnQQQr!   input_modalitiesc                 P    h | ]#}t          |                                          $S rD   r*  r+  s     r   r  zB_discover_openrouter_free_models.<locals>._load.<locals>.<setcomp>x  s&    SSS!s1vv||~~SSSr!   output_modalitiestextaudior/   r   r   c                 P    h | ]#}t          |                                          $S rD   r*  r+  s     r   r  zB_discover_openrouter_free_models.<locals>._load.<locals>.<setcomp>  s&    XXXAQXXXr!   rV  toolsr  )r   r   _sort_toolsrV  zz-ai/glm-5.1zqwen/qwen3.6-plusr   c                     | d         dk    rdnd|                      dd          | d                                         fS )Nr   r   r   r  r3  r   )r   r   )rL  s    r   <lambda>zA_discover_openrouter_free_models.<locals>._load.<locals>.<lambda>  sC    d000AAaHH]A&&M!!'
 r!   r  r3  )r  r   r   r   r  r  r  r  r  r  r  r5  rL   rM   r   r   r  r6  r   sortedsortpop)r  r  r  r  r  r  r  r3  rL  rY  r%  archinputsoutputsr/   r   	supported_wanted_nonfreer  s                     r   r  z/_discover_openrouter_free_models.<locals>._load]  s   /0''.//R29=Q3R3R 	;':':':GO$n$$%JT[$\\^##C#44 	Bj!7!7!@!@AAG	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B /9'4/H/HPGKK+++b 	 	DdD)) 488D>>/R006688H x4//hhy))/RG*7;;x+@+@AA F\]d]h]hiu]v]vFwFw 88N++1rDQQdhh7I.J.J.PbQQQFSStxx8K/L/L/RPRSSSGV##vW'<'<7@R@RHHXtxx''-2..4466D,,,,(XX:P1Q1Q1WUWXXXINN$+y$8$8qqa(.y(9(9	      
 0:'4/H/HPGKK+++b 	 	DdD)) 488D>>/R006688H x4//8?3R3RHHXtxx''-2..4466DNN)     
 	 
 
 	 	 	
  	* 	*DHH]D))))s   5:B;;B?B?zopenrouter-freec                 0    g | ]}|d          |d         dS )r   r   r   rD   r  s     r   r4  z4_discover_openrouter_free_models.<locals>.<listcomp>  s(    RRRQ1T7QwZ00RRRr!   )r  r  rM   r  _OPENROUTER_FREE_MODELS)rs  r  r  r  s      @r   ru  ru  Z  sy    

(&((CF4: F F F F F FP ((95AAF RR:QRRRRr!   c                 R   d}d}t                               di           }t          |t                    r*|                    d          }|                    d          }t	          |          }t          |          }| pd                                } | s| ||fS |                     d          r*d| v r&| dd                             dd          \  }}||dfS d	| v rG|                     d	d          \  }}|d
k    r| d
|fS |r||k    r|||fS |t          v r||k    r|s| d
dfS | ||fS )a  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.
    NrA  r   r  r[   r   r\   r  r  r   )
r  r   rL   rM   r   r  r   r  r  rw  )	rY  config_providerconfig_base_url	model_cfgconfig_provider_is_named_customprovider_hint
bare_modelrf  bares	            r   r{  r{    s|    OO$$I)T"" 4#--
33#--
33,_==O&?&P&P#B%%''H :/99
 3 /C8OO$,QRRL$6$6sA$>$>!z=$..
h~~c1-- l**\?::  	:v88/99 %%%&O*C*CLk*C\4//_o55r!   c            
        34567 d4t           } g }t                      5t                      }t          5          }t	          5          }d}t
                              di           }d}t          |t                    r|} ngt          |t                    rRt          |                    d                    4|                    dd          }|                    dd          }|r|} t          j        d          p't          j        d	          pt          j        d
          }|r|                                } 4s"t          |                    d                    4t                      }	4r|	                    4           	 ddlm}
 ddlm}  |
            D ]}|                    d          s	  ||d                                       dd          }|dk    rEn# t(          $ r Y nw xY wt          |d                   }|r|	                    |           n# t(          $ r Y nw xY w|                    d          pi                                 D ]8}t          |          }|r%t-          ||          r|	                    |           9|                    d          pi                                 D ](}t          |          }|r|	                    |           )t.                                          D ]5\  }}t3          5fd|D                       r|	                    |           6|D ].}|                    d          }|r|	                    |           /t5                      66rD6fd|	D             }	4r46vrd46fd|D             }6fd|                                D             }t7                      77rD7fd|	D             }	4r47v rd47fd|D             }7fd|                                D             }g }|rt9          |          nd}|rf|dv ra	 ddl}|                                }|                    d          r|dz   }n|                    d           d!z   }i }d"}|D ]7}5                    |          pt          j        |          }|r
d#| |d$<    n8|j         !                    |d%&          }|                                D ]\  }}|"                    ||           |j         #                    |d'(          5 }tI          j%        |&                                '                    d)                    }ddd           n# 1 swxY w Y   g } d*|v r$t          |d*         tP                    r	|d*         } n'd+|v r#t          |d+         tP                    r|d+         } | D ]}!t          |!t                    s|!                    dd          p+|!                    d,d          p|!                    dd          }"|!                    d,d          p|!                    dd          p|"}#|"r/|#r-|)                    |"|#d-           |	                    |           n# t(          $ r Y nw xY wt
                              d.g           }$t          |$tP                    rd/ |D             }%|$D ]}&t          |&t                    s|&                    dd          }'|'rg|'|%vrcd |'v r|'*                    d           d0         n|'}(|)                    |'|(d-           |%                    |'           |	                    d1           |	rtW          |	4fd23          D ]})tX                              |)|)-                                          }*|)d4k    rGt]          |)t_          5                    }+|)                    |)d5ta          |)|+4          d6           }|)tb          v r^tb          |)         },|)d7k    rte                      p|,},t]          |)|,          },ta          |)|,4          }-|)                    |)|*|-d6           |)|v rNt]          |)|                    |)g                     },|)                    |)|*ta          |)|,4          d6           6|r:t]          |)|          },|)                    |)|*ta          |)|,4          d6           r|)3                    d1          r| | *                    d           d0         d-}.ti          |)| |.8          |.d9<   |)                    |)|*|.gd6           nUd | v r| *                    d           d0         n| }/| |/d-}.ti          d| |.8          |.d9<   |)                    dd:|.gd6           | r`d; 33fd<|D             }0 3|           |0vrAd | v r| *                    d           d0         n| }/d=}1|D ]j}24rf|2                    d          4k    rM| |/d-}.ti          |2                    d          | |.8          |.d9<   |2d+         5                    d|.           d>}1 nk|1sX|rV| |/d-}.ti          |d                             d          | |.8          |.d9<   |d         d+         5                    d|.           nW|sU| |/d-}.ti          4pd| |.8          |.d9<   |)                    4pdtX                              4pd4pd:          |.gd6           4| |d?S )@a  
    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}]}]
    }
    Nrr  r[   rA  r   defaultr  HERMES_MODELOPENAI_MODEL	LLM_MODELr   r   )list_available_providers)get_auth_statusauthenticatedr   
key_sourcezgh auth tokenr  r  c              3   B   K   | ]}                     |          V  d S r   r  )r   r  rs  s     r   r   z'get_available_models.<locals>.<genexpr>7  s-      --!w{{1~~------r!   r   c                     h | ]}|v |	S rD   rD   )r   r  allowed_providerss     r   r  z'get_available_models.<locals>.<setcomp>A  s$    \\\c3J[C[C[cC[C[C[r!   c                 B    g | ]}|                     d           v |S r  r  )r   rp  rT  s     r   r4  z(get_available_models.<locals>.<listcomp>D  s;     "
 "
 "
yy''+<<< <<<r!   c                 $    i | ]\  }}|v 	||S rD   rD   )r   r   r  rT  s      r   
<dictcomp>z(get_available_models.<locals>.<dictcomp>H  s5     !
 !
 !
#V/// ///r!   c                     h | ]}|v|	S rD   rD   )r   r  hidden_providerss     r   r  z'get_available_models.<locals>.<setcomp>P  s$    ___c3N^C^C^cC^C^C^r!   c                 B    g | ]}|                     d           v|S r  r  )r   rp  rY  s     r   r4  z(get_available_models.<locals>.<listcomp>S  s;     "
 "
 "
yy''/??? ???r!   c                 $    i | ]\  }}|v	||S rD   rD   )r   r   r  rY  s      r   rW  z(get_available_models.<locals>.<dictcomp>W  s5     !
 !
 !
#V"222 222r!   >   r   r   r   r   r  r  r  r  )r
  r  r   r	  r   r  r  r  r  )r  r  r  r  r  r  r/   r   r  c                     h | ]
}|d          S r  rD   r  s     r   r  z'get_available_models.<locals>.<setcomp>  s    BBBAdGBBBr!   r   r   c                 $    t          |           S r   )r   )xr   s    r   r5  z&get_available_models.<locals>.<lambda>  s    <NqRa<b<b r!   r6  r   r   )r   r   r  r   rn  rQ  Defaultc                     | pd} |                      d          r d| v r|                     dd          d         } d| v r|                     dd          d         } | S )Nr[   r   r\   r  r  r   )r  r  )mids    r   _normz#get_available_models.<locals>._norm  se    )C~~c"" +sczziiQ''*czziiQ''+Jr!   c                 d    h | ],}|                     d g           D ]} |d                   -S )r  r   r  )r   gr  rb  s      r   r  z'get_available_models.<locals>.<setcomp>  sA    TTT1hPR@S@STT1agTTTTr!   FT)r   default_modelgroups)6DEFAULT_MODELr  r  r  rx  r  r   rL   r   rM   r   r   r   r   r5  r6  r^  rN  r  rO  rO   r  r  r  r  rU  r*  r0  r  r  r  r  r  r  
add_headerr  r  r  r  r  r  r   r  r7  r  r  rq  ru  r  rw  rv  r  rk  insert)8re  rf  r  named_custom_providersnamed_custom_catalogscfg_base_urlrD  cfg_default	env_modeldetected_providers_lap_gas_p_src_pid	_norm_pid_keys_entryauto_detected_modelsendpoint_providerr  r  r  r  api_key_varsr  r  r  r  r  r  r  r  rA  rY  
model_name_custom_providers_cfg_seen_custom_ids_cp	_cp_model	_cp_labelr  provider_nameopenrouter_modelsrl  r  fallback_modelr   all_ids_norminjectedrd  rb  r   rs  rT  rY  s8                                                      @@@@@r   get_available_modelsr    s^     O!MF!!G!##J9'JJJDWUUU L$$IL)S!! (!	It	$	$ (0z1J1JKKmmIr22 }}Z44 	('M 	.))`RY~-F-F`")T_J`J`I *!))  T0@Q1R1RSS
  0///FFFFFF;;;;;;$&& 	- 	-B66/** tBtH~~)),;;?** +   )"T(33D -"&&t,,,	-    
 ,,288:: . .*400	 	.1*iHH 	.""9--- 1228b>>@@ . .*400	 	.""9--- *//11 ) )e----u----- 	)""4(((( ) )zz-(( 	)""4(((.00 
\\\\-?\\\ 	#6GGG"O"
 "
 "
 "
5"
 "
 "
!
 !
 !
 !
'<'B'B'D'D!
 !
 !
 -.. 
____-?___ 	#2BBB"O"
 "
 "
 "
5"
 "
 "
!
 !
 !
 !
'<'B'B'D'D!
 !
 !
 GS]5lCCCY] ,)-VVV+	!!!! $))++H  '' C')3's33lB GNL#  !++c**<binn /B/B/BGO,E
 .((e(DDC % %1q!$$$$''R'88 CHz(--//"8"8"A"ABBC C C C C C C C C C C C C C C K~~*T&\4"@"@~"6lT!!jh&F&F!"8n$ > >!%..  99T2..a%))FB2G2Ga599U\^`KaKa"YYvr22Xeii6L6LXPX
 >
 >(//x*0U0UVVV&**+<===>  	 	 	D	  GG$6;;'.. 
1BB-ABBB( 	1 	1Cc4(( ,,I 1Y.>>>8;y8H8HIOOC0044i	$++9y,Q,QRRR $$Y///"&&x000  Ee,2b2b2b2bccc <	 <	C-11#syy{{CCMl""$@4WEEE% %! #& ,238I?[[     
 (((
 .c2
.((!>!@!@!NJJ9#zJJ
-c:OO#& -$     
 ---9#?T?X?XY\^`?a?abb
#& -23
OTT      ( !=cCW!X!XJMM'*$1"6sJ"X"X# #    
 ^^H--   ,!.!4!4S!9!9"!=& &N 3PPSUbn|2}2}2}N;/MM'*$1#1"2# #    q<	B 14}0D0D##C((,,- ->>&CI}hv&w&w&w{#iYSaRbccddd  +	 	 	 UTTTTTT5|3347=4H4HM'',,R00mEH 
 
" 	quu]';';'N'N,9E%J%JN2Om,,%"03 3 3N;/
 hK&&q.999#HE  (5!F!F.K1IMM-00!,/ / /{+
 q	(#**1n==== (5!F!F.K#0y!,/ / /{+
 #2#?i 1 5 5o6RTcTpgp q q-.     +&  sn   .H! 6+G#!H! #
G0-H! /G000H! !
H.-H.+C1Y; :U"Y; "U&&Y; )U&*DY; ;
ZZstaticz
index.htmld   STREAMSCANCEL_FLAGSc                      | t           _        d S r   _thread_ctxr  )kwargss    r   _set_thread_envr  .  s    KOOOr!   c                      i t           _        d S r   r  rD   r!   r   _clear_thread_envr  1  s    KOOOr!   SESSION_AGENT_LOCKS
session_idc                     t           5  | t          vrt          j                    t          | <   t          |          cd d d            S # 1 swxY w Y   d S r   )SESSION_AGENT_LOCKS_LOCKr  	threadingLock)r  s    r   _get_session_agent_lockr  8  s    	! / /000.7n.>.>
+":./ / / / / / / / / / / / / / / / / /s   1AA
A
enterdarkHERMES_WEBUI_BOT_NAMEHermes)	default_workspacesend_keyshow_token_usageshow_cli_sessionssync_to_insightscheck_for_updatesthemebot_namepassword_hashc                     i } t                                           rm	 t          j        t                               d                    }t          |t                    rt          D ]}||v r||         | |<   n# t          $ r Y nw xY w| S )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   r  r  rK   rL   rM   _SETTINGS_DEFAULTSrO   )stored_settingsstoredr  s      r   _load_stored_settingsr  M  s     O 	Z 7 7 7 I IJJF&$'' ;- ; ;Cf}}/5c{, 	 	 	D	s   AA9 9
BBc                     t           } 	 t                      }|                    di           }t          |t                    r)|                                r|                                } nPt          |t                    r;t	          |                    dd          pd                                          }|r|} n# t          $ r Y nw xY w| S )z4Return the effective default model from config.yaml.rA  rJ  r[   )rg  rE   r   rL   r   r   rM   rO   )re  r  rD  model_values       r   _current_default_modelr  a  s    !M
llGGGR((	i%% 	,)//*;*; 	,%OO--MM	4(( 	,immIr::@bAAGGIIK , +   s   B2B< <
C	C	c                      t          t                    } |                     t                                 t	                      | d<   | S )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.
    re  )rM   r  rN   r  r  )settingss    r   load_settingsr  r  s@     &''HOO)++,,, 6 8 8H_Or!   r  r  z
ctrl+enter>   r  r  r  r  r  c                    ddl }t          t                    }|                    t	                                 |                     dd          }|rt          |t                    r|                                rwt          t                    
                                }|                    ||                                
                                z                                             |d<   |                     dd          rd|d<   |                                 D ]D\  }}|t          v r6|t          v r|t          |         vr'|t           v rt#          |          }|||<   Et$                              t)          j        |dd          d	
           d|v r|d         ad|v r9t/          |d                                                                                   at7                      }|                    d          |d<   |S )zISave settings to disk. Returns the merged settings. Ignores unknown keys.r   N_set_passwordr  _clear_passwordFr  )ensure_asciiindentr  r  re  r  )hashlibrM   r  rN   r  r9  rL   r   r   rV   encodesha256	hexdigestr  _SETTINGS_ALLOWED_KEYS_SETTINGS_ENUM_VALUES_SETTINGS_BOOL_KEYSboolr  
write_textr  dumpsrg  r   r   r   ra   r  r   )r  _hlcurrentraw_pwsaltr  r  mergeds           r   save_settingsr    s   %&&GNN(**+++\\/400F Z*VS)) Zfllnn Z9~~$$&&#&::dV\\^^5J5J5L5L.L#M#M#W#W#Y#Y ||%u-- (#'     1&&&)))a7LQ7O.O.O'''GGGAJ
7q999     '!!0g%% )<!=>>IIKKSSUU__F%kk/::F?Mr!   r  rA  rJ  SESSIONS)init_profile_state)r   Nr   )__doc__collectionsr  r   sysr  r  	tracebackuuidpathlibr   urllib.parser   r   homer   __file__r   r   r   r   rb   intrc   r   r   rV   SESSION_DIRWORKSPACES_FILESESSION_INDEX_FILEr  LAST_WORKSPACE_FILEPROJECTS_FILEr    r1   r_   r`   r   r   rf   hermes_constantsr3   rO   rB   r  rG   r@   rM   rE   rC   r  rX   ra   rg  rk   tuplerw   MAX_FILE_BYTESMAX_UPLOAD_BYTES
IMAGE_EXTSMD_EXTS	CODE_EXTSMIME_MAP_DEFAULT_TOOLSETSr   CLI_TOOLSETSr@  r   __annotations__ _DYNAMIC_MODEL_CACHE_TTL_SECONDSr  r   r  rw  r7  rh  ri  r   r   r  r  r5  r*  r0  r  r9  rE  rX  r`  rk  rq  ry  r  r  r  r  r  r  r  r  r  r  rx  r  r  r  rv  ru  r{  r  _INDEX_HTML_PATHLOCKSESSIONS_MAX	CHAT_LOCKr  STREAMS_LOCKr  SERVER_START_TIMEr   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  _startup_settingsr   _cfg_startup_mrL   r   OrderedDictr  r=   r  r>   rD   r!   r   <module>r     s  	 	 	      				 



                 + + + + + + + + $)++DNN!(0022	 ry$k22
s929(&1122 DCy7"##    :<<		 

 "J.!$55#m3 !O3!$88 !O3'T ' ' ' 'T# # # # # #N ! ""
j))
" 
s:ch&&J(((MMML8888888 L L LKL 
IN		0$ 	0 	0 	0 	0D        /T / / / /  0/11 BI:<QRR!
 !
 !
 !
F0u 0 0 0 0& #  POO
+++Q Q Q	 |\+&8	    
 z|| 3R88<<UDUVV %6[opp%=[vww%<[  A  A%?[xyy%>[wxx%M  \A  B  B%P  \A  B  B  )+ d39o * * *#&  

M
'
7BK
h
&
8ACS
 
<
 '(9
 <Fz
 y	

 
 '
 y
 #H
 /;L
 =
 #,Y
 K
 
 
     :!)!EG#%#)  " !.?@@".ABB".ABB!.@AA	 7711--	22	 o>>o>>".ABB#.BCC	  *:;; 1EFF"1IJJ
 $0DEE$0EFF%0FGG i88g66m<<i88i88o>> !3DEE+>>!2DEE'2JKK&2IJJ%.AA%.AA!2DEE 2CDD2BCC!2DEE .AA'2JKK.AA'2JKK.AA Y77^<<X66 ->??"-@AA-=>>  ,<==!,>??KI I V  %    F              
% !1d
 1sTz 1 1 1 1" "C "#* "PU " " " "(4 ( ( ( (V    "CC4 C C C C	Bs3x 	B 	B 	B 	BLT#Y L L L L /3   c # t    &4RV;    83 49    &3. 3.sTz 3.S 3.UY\`U` 3.lp 3. 3. 3. 3.lcDj d4j UYZ^U_    &  	  t D[	
 
D[   < #a  	a a aata D[	a
 
a a a a> #-
  - - --- t-
 D[- 	- - - -6$      C D    ($C $C $ $ $ $N Kk  # C ostxoy    0MT M M M M 88 88 8888 88 	88
 
$Z88 88 88 88v? ?$+ ?d ? ? ? ?D dTk TRUW[\`WaRaMb    &d3: d$ d d d dc tDz TWZ^T^ cghlcm    *     :=tDz = = = =DNS NSdTk NST$Z NS NS NS NSb26S 26U 26 26 26 26j|d | | | |@
 x',6  #IN$$"IN$$	   "IN$$d   DIKK  io      T   *IN,, / /	 / / / / .//	18<<  t    (    "	t 	 	 	 	 /446677?:KK ,'  ihh "D "T " " " "J "MOO  `011 ` D!23F!GHHSSUU]]__	:<<L			'2	&	&Bz"d #VVIr""z"c #rxxzz #

 	 	 	D	 %<K$;$=$=+
! = = =	////// 	 	 	DD	s7   E% %E/.E/A8\: :]] ]3 3]<;]<