
    i                       d Z ddlZddlZddlZddlZddlZddlZddlZddl	m
Z
 ddlmZmZmZ ddlmZ ddlmZ ddlmZ ddlmZ  ej        e          Z e
e          j        j                                        Zd	Zd
eeef         deeef         fdZ d
eeef         deeef         fdZ!d
eeef         dededdfdZ"dede#fdZ$dgg dg dg dg dg dddgg dg dg dg dg dg dg dg dd Z%d
eeef         defd!Z&d
eeef         d"eddfd#Z'dd$l(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3 dd%l4m5Z5m6Z6 d&efd'Z7dd(l8m9Z9m:Z:m;Z;m<Z< de#fd)Z=dd*edz  ddfd+Z>dd-ed.ed/e#defd0Z?dd-ed1e@d.eAd2edz  deAf
d3ZBdd-ed1e@d.eAd2edz  deAf
d4ZCdd-ed.e#de#fd6ZDdd&ed7e@d8e@de@fd9ZEd:eFfd;ZGd
eFfd<ZHd
eFfd=ZId
eFfd>ZJdd?e
dz  deFeef         fd@ZKd,dAd
eFdBe#fdCZLde#fdDZMde#fdEZNde#fdFZOd
eFfdGZPd
eFfdHZQd
eFfdIZRd
eFfdJZSd
eFfdKZTdL ZUdM ZVdNede@fdOZWdP ZXdQ ZYdR ZZdS Z[dT Z\dU Z]dV Z^d
eFfdWZ_dd
eFdXe#fdYZ`d
eFde#fdZZad[edefd\Zbd
eFd]edee         fd^Zcd
eFd]ed[ede#fd_Zd eed`z            daz  dbz  dcz  ddz  Zede Zfdfdgdhdidjdkdldmdndo	ZgdpeFfdqZhdre
de#fdsZidtdueLfdvdweQfdxdyeRfdzd{e_fd|d}e`fd~deTfgZjd Zkd Zld
eFde#fdZmd
eFfdZndS )u  
Interactive setup wizard for Hermes Agent.

Modular wizard with independently-runnable sections:
  1. Model & Provider — choose your AI provider and model
  2. Terminal Backend — where your agent runs commands
  3. Agent Settings — iterations, compression, session reset
  4. Messaging Platforms — connect Telegram, Discord, etc.
  5. Tools — configure TTS, web search, image generation, etc.

Config files are stored in ~/.hermes/ for easy access.
    N)Path)OptionalDictAny)get_nous_subscription_features)managed_nous_tools_enabled)base_url_hostname)get_optional_skills_dirz*https://hermes-agent.nousresearch.com/docsconfigreturnc                     |                      d          }t          |t                    rt          |          S t          |t                    r*|                                rd|                                iS i S )Nmodeldefault)get
isinstancedictstrstrip)r   current_models     5/home/ubuntu/.hermes/hermes-agent/hermes_cli/setup.py_model_config_dictr   $   st    JJw''M-&& #M"""-%% 2-*=*=*?*? 2=..0011I    c                 x    |                      d          }t          |t                    rt          |          ni S Ncredential_pool_strategiesr   r   r   )r   
strategiess     r   _get_credential_pool_strategiesr   -   s6    899J)*d;;C4
Cr   providerstrategyc                 @    |sd S t          |           }|||<   || d<   d S r   )r   )r   r   r    r   s       r   _set_credential_pool_strategyr"   2   s7     088J#Jx+5F'(((r   c                 v    | r| dk    rdS | dk    rdS ddl m} |                    |           }|sdS |j        dv S )NcustomF
openrouterTr   PROVIDER_REGISTRY>   api_keyoauth_device_code)hermes_cli.authr'   r   	auth_type)r   r'   pconfigs      r   "_supports_same_provider_pool_setupr-   :   sj     x8++u<t111111##H--G u @@@r   copilot-acp)gpt-5.4zgpt-5.4-miniz
gpt-5-minigpt-5.3-codexzgpt-5.2-codexgpt-4.1gpt-4ogpt-4o-minizclaude-opus-4.6zclaude-sonnet-4.6zclaude-sonnet-4.5zclaude-haiku-4.5zgemini-2.5-prozgrok-code-fast-1)zgemini-3.1-pro-previewzgemini-3-pro-previewzgemini-3-flash-previewzgemini-3.1-flash-lite-preview)glm-5.1glm-5zglm-4.7zglm-4.5zglm-4.5-flash)	kimi-k2.6	kimi-k2.5zkimi-k2-thinkingzkimi-k2-turbo-previewzstep-3.5-flashzstep-3.5-flash-2603)ztrinity-large-thinkingztrinity-large-previewztrinity-mini)zMiniMax-M2.7zMiniMax-M2.5zMiniMax-M2.1z
MiniMax-M2)anthropic/claude-opus-4.6anthropic/claude-sonnet-4.6zopenai/gpt-5zgoogle/gemini-3-flash)r8   r9   zopenai/gpt-5.4zgoogle/gemini-3-pro-previewzgoogle/gemini-3-flash-preview)r/   r0   zclaude-sonnet-4-6zgemini-3-flashr5   r7   minimax-m2.7)r6   r7   r4   r5   zmimo-v2.5-proz	mimo-v2.5zmimo-v2-prozmimo-v2-omnir:   zminimax-m2.5zqwen3.6-pluszqwen3.5-plus)zQwen/Qwen3.5-397B-A17Bz"Qwen/Qwen3-235B-A22B-Thinking-2507z#Qwen/Qwen3-Coder-480B-A35B-Instructzdeepseek-ai/DeepSeek-R1-0528zdeepseek-ai/DeepSeek-V3.2zmoonshotai/Kimi-K2.5)r.   copilotgeminizaikimi-codingkimi-coding-cnstepfunarceeminimax
minimax-cn
ai-gatewaykilocodezopencode-zenzopencode-gohuggingfacec                     |                      d          }t          |t                    rHt          |                     d          pd                                                                          S dS )Nagentreasoning_effort )r   r   r   r   r   lower)r   	agent_cfgs     r   _current_reasoning_effortrM   t   sc    

7##I)T"" L9==!344:;;AACCIIKKK2r   effortc                 r    |                      d          }t          |t                    si }|| d<   ||d<   d S )NrH   rI   r   )r   rN   rL   s      r   _set_reasoning_effortrP   {   sD    

7##Ii&& $	#w$*I !!!r   )cfg_getDEFAULT_CONFIGget_hermes_homeget_config_pathget_env_pathload_configsave_configsave_env_valueremove_env_valueget_env_valueensure_hermes_home)Colorscolortitlec                     t                       t          t          d|  t          j        t          j                             dS )zPrint a section header.u   ◆ N)printr]   r\   CYANBOLD)r^   s    r   print_headerrc      s5    	GGG	%uV[
9
9:::::r   )print_error
print_infoprint_successprint_warningc                      t          t          dd          } | dS 	 t          |                                           S # t          $ r Y dS w xY w)z;Return True when stdin looks like a usable interactive TTY.stdinNF)getattrsysboolisatty	Exception)ri   s    r   is_interactive_stdinro      sZ    C$''E}uELLNN###   uus    = 
A
Areasonc                    t                       t          t          dt          j        t          j                             t                       | rt          |            t          d           t                       t          d           t          d           t          d           t          d           t                       t          d           t          d           t                       d	S )
z8Print guidance for headless/non-interactive setup flows.u)   ⚕ Hermes Setup — Non-interactive modez+The interactive wizard cannot be used here.z@Configure Hermes using environment variables or config commands:z)  hermes config set model.provider customz;  hermes config set model.base_url http://localhost:8080/v1z1  hermes config set model.default your-model-namez?Or set OPENROUTER_API_KEY / OPENAI_API_KEY in your environment.zERun 'hermes setup' in an interactive terminal to use the full wizard.N)r`   r]   r\   ra   rb   re   )rp   s    r   #print_noninteractive_setup_guidancerr      s    	GGG	%;V[&+
V
VWWW	GGG 6<===	GGGQRRR:;;;LMMMBCCC	GGGPQQQVWWW	GGGGGr   Fquestionr   passwordc                 ~   |r	|  d| d}n|  d}	 |r2ddl }|                     t          |t          j                            }n't	          t          |t          j                            }|                                p|pdS # t          t          f$ r& t                       t          j
        d           Y dS w xY w)z'Prompt for input with optional default. []: : r   NrJ      )getpassr]   r\   YELLOWinputr   KeyboardInterruptEOFErrorr`   rk   exit)rs   r   rt   displayrz   values         r   promptr      s     "-----/// 	9NNNOOE'6=$A$ABBEE%7788E{{}}--2-x(   s   A2B 3B<;B<choicesdescriptionc                 .    ddl m}  || ||d|          S )z?Single-select menu using curses. Delegates to curses_radiolist.r   )curses_radiolist)selectedcancel_returnsr   )hermes_cli.curses_uir   )rs   r   r   r   r   s        r   _curses_prompt_choicer      s2    555555HgPR`kllllr   c           	         t          | |||          }|dk    r5||k    rt          d           t                       |S t                       |S t          t          | t          j                             t          |          D ]X\  }}||k    rdnd}||k    r.t          t          d| d| t          j                             Ct          d| d|            Yt          d|d	z    d
           	 	 t          t          dt          |           d|d	z    dt          j
                            }|s|S t          |          d	z
  }d|cxk    rt          |          k     rn n|S t          dt          |                      nS# t          $ r t          d           Y n8t          t          f$ r% t                       t!          j        d	           Y nw xY w)zPrompt for a choice from a list with arrow key navigation.

    Escape keeps the current default (skips the question).
    Ctrl+C exits the wizard.
    )r   r   z  Skipped (keeping current)u   ●u   ○   z  Enter for default (ry   z)  Ctrl+C to exitTz  Select [1-z] (z): z$Please enter a number between 1 and zPlease enter a number)r   re   r`   r]   r\   r{   	enumerateGREENr|   lenDIMintrd   
ValueErrorr}   r~   rk   r   )	rs   r   r   r   idxichoicemarkerr   s	            r   prompt_choicer      s+     '7
T
T
TC
axx'>>4555GGGN
	%&-
(
()))w'' * *	6w,,E<<%.V..f..==>>>>(v(((())))Ew{EEEFFF	FS\\FFgkFFF
SS E  e**q.CC&&&&#g,,&&&&&
Ms7||MMNNNN 	1 	1 	1/00000!8, 	 	 	GGGHQKKKKK	s%   6AF	 80F	 )F	 	G$2GGTc                 h   |rdnd}	 	 t          t          |  d| dt          j                                                                                            }n9# t          t          f$ r% t                       t          j
        d           Y nw xY w|s|S |dv rdS |dv rd	S t          d
           )z=Prompt for yes/no. Ctrl+C exits, empty input returns default.zY/nzy/NTrv   rw   ry   )yyes)nnoFzPlease enter 'y' or 'n')r|   r]   r\   r{   r   rK   r}   r~   r`   rk   r   rd   )rs   r   default_strr   s       r   prompt_yes_nor     s    "-%%K/	ex;;;;;;V]KKLL E
 "8, 	 	 	GGGHQKKKKK	  	NL  4K5-...#/s   AA 3BBitemspre_selectedc                     |g }ddl m}  || |t          |          t          |                    }t          |          S )u  
    Display a multi-select checklist and return the indices of selected items.

    Each item in `items` is a display string. `pre_selected` is a list of
    indices that should be checked by default. A "Continue →" option is
    appended at the end — the user toggles items with Space and confirms
    with Enter on "Continue →".

    Falls back to a numbered toggle interface when simple_term_menu is
    unavailable.

    Returns:
        List of selected indices (not including the Continue option).
    Nr   )curses_checklist)r   )r   r   setsorted)r^   r   r   r   chosens        r   prompt_checklistr   #  sb     555555L<((	  F &>>r   varc           
      t   |                      dg           }d                    |dd                   }t          |          dk    r|dt          |          dz
   dz  }t                       t          t	          d|                      d| d	                    d
t
          j                             t                       |rt          d|            |                      d          rt          d| d                     t                       |                      d          r/t          d|                      d| d	                    d          }n,t          d|                      d| d	                              }|r't          | d	         |           t          d           dS t          d           dS )zEDisplay a nicely formatted API key input screen for a single env var.tools, N   z, +z more     ─── r   name
    ───z  Enables: urlz  Get your key at: rt   r   r   Trt        ✓ Savedz/  Skipped (configure later with 'hermes setup'))r   joinr   r`   r]   r\   ra   re   r   rX   rf   rg   )r   r   	tools_strr   s       r   _prompt_api_keyr   @  s   GGGR  E		%)$$I
5zzA~~03u::>0000		GGG	%Nsww}c&kBBNNNPVP[
\
\]]]	GGG .,,,---
wwu~~ 75U55666	GGG
wwz ><CGGHc&k::<<tLLL<CGGHc&k::<<== Is6{E***m$$$$$GHHHHHr   c                 ,   t                       t          d           g }t          |           }	 ddlm}  |            }n# t
          $ r g }Y nw xY w|r|                    d           n|                    d           t          d          r|                    d           n|                    d           |j        j	        r|                    d	           nX|j        j
        r7d
}|j        j        rd|j        j         d}|                    |ddf           n|                    d           |j        j        }|j        j	        r|                    d           nl|j        j
        r#d}|rd| d}|                    |ddf           n=d}|dk    rd}n|dk    rd}n|dk    rd}n|dk    rd}|                    dd|f           |j        j	        r|                    d           n|j        j
        r|                    d           nd}		 ddlm}
 dd lm}  |              |
            D ]<}|j        d!k    r	 |                                r	|j        }	 n-# t
          $ r Y 9w xY wn# t
          $ r Y nw xY w|	r|                    d"|	 dddf           n|                    d#           t+          | d$d%d&'          }|j        j	        r|                    d(           n|d)k    r&t          d*          r|                    d+           n|d,k    r5t          d-          st          d.          r|                    d/           ns|d0k    r&t          d1          r|                    d2           nG|d3k    r&t          d4          r|                    d5           n|d6k    r4t          d7          st          d8          r|                    d9           n|d:k    r^	 |j                            d:          du}n# t
          $ r d}Y nw xY w|r|                    d;           n|                    d<           n}|d=k    rb	 ddl}|j                            d=          du}n# t
          $ r d}Y nw xY w|r|                    d>           n+|                    d?           n|                    d@           |j        j	        r|                    dA           nwt+          | dBdC          dDk    r8|j        j        r|                    dE           n@|                    dF           n*t9                      r|j        r|                    dG           t          dH          r%t          dI          r|                    dJ           n:t          dH          r|                    dK           n|                    dL           t          dM          r|                    dN           	 ddOlm}  |dP          pi }|                     dQ          s|                     dR          r|                    dS           n# t
          $ r Y nw xY wt          dT          r|                    dU           n|                    dV           |                    dW           |                    dX           |                    dY           tC          dZ |D                       }tE          |          }tG          | d[| d\           t                       |D ]\  }}}|r.t          d]tI          d^tJ          j&                   d_|            6t          d]tI          d`tJ          j'                   d_| d_tI          da| dtJ          j(                              t                       db |D             }|r>tS          dc           dddl*m+} tS          de |             df           t                       t                       t          tI          dgtJ          j&                             t          tI          dhtJ          j&                             t          tI          ditJ          j&                             t                       dddl*m+} t          tI          dj |             dktJ          j,        tJ          j-                             t                       t          d]tI          dltJ          j.                   dmt_                                  t          d]tI          dntJ          j.                   dmta                                  t          d]tI          dotJ          j.                   dp| dq           t                       t          tI          drtJ          j(                             t                       t          tI          dstJ          j,        tJ          j-                             t                       t          d]tI          dttJ          j&                   du           t          d]tI          dvtJ          j&                   dw           t          d]tI          dxtJ          j&                   dy           t          d]tI          dztJ          j&                   d{           t          d]tI          d|tJ          j&                   d}           t                       t          d]tI          d~tJ          j&                   d           t          d]tI          dtJ          j&                   d           t          d]tI          dtJ          j&                              t          d           t                       t          d           t          d]tI          dt_                       tJ          j(                              t          d]tI          dta                       tJ          j(                              t                       t          tI          drtJ          j(                             t                       t          tI          dtJ          j,        tJ          j-                             t                       t          d]tI          dtJ          j&                   d           t          d]tI          dtJ          j&                   d           t          d]tI          dtJ          j&                   d           t                       dS )z#Print the setup completion summary.zTool Availability Summaryr   get_available_vision_backends)Vision (image analysis)TN)r   Fzrun 'hermes setup' to configureOPENROUTER_API_KEY)Mixture of AgentsTN)r   Fr   )z(Web Search & Extract (Nous subscription)TNWeb Search & ExtractzWeb Search & Extract ()TN)r   FzUEXA_API_KEY, PARALLEL_API_KEY, FIRECRAWL_API_KEY/FIRECRAWL_API_URL, or TAVILY_API_KEY)z%Browser Automation (Nous Browser Use)TNzBrowser AutomationzBrowser Automation (zVnpm install -g agent-browser, set CAMOFOX_URL, or configure Browser Use or BrowserbaseBrowserbasezOnpm install -g agent-browser and set BROWSERBASE_API_KEY/BROWSERBASE_PROJECT_IDzBrowser Usez8npm install -g agent-browser and set BROWSER_USE_API_KEYCamofoxCAMOFOX_URLzLocal browserznpm install -g agent-browserF)z$Image Generation (Nous subscription)TN)Image GenerationTN)list_providers)_ensure_plugins_discoveredfalzImage Generation ()r   FzFAL_KEY or OPENAI_API_KEYttsr   edger   )z-Text-to-Speech (OpenAI via Nous subscription)TN
elevenlabsELEVENLABS_API_KEY)zText-to-Speech (ElevenLabs)TNopenaiVOICE_TOOLS_OPENAI_KEYOPENAI_API_KEY)zText-to-Speech (OpenAI)TNrB   MINIMAX_API_KEY)zText-to-Speech (MiniMax)TNmistralMISTRAL_API_KEY)z Text-to-Speech (Mistral Voxtral)TNr<   GEMINI_API_KEYGOOGLE_API_KEY)zText-to-Speech (Google Gemini)TNneutts)zText-to-Speech (NeuTTS local)TN)u)   Text-to-Speech (NeuTTS — not installed)Frun 'hermes setup tts'	kittentts)z Text-to-Speech (KittenTTS local)TN)u,   Text-to-Speech (KittenTTS — not installed)Fr   )zText-to-Speech (Edge TTS)TN)z#Modal Execution (Nous subscription)TNterminalbackendmodal)zModal Execution (direct Modal)TN)zModal ExecutionFzrun 'hermes setup terminal')z0Modal Execution (optional via Nous subscription)TNTINKER_API_KEYWANDB_API_KEY)RL Training (Tinker)TN)r   Fr   )r   Fr   
HASS_TOKEN)zSmart Home (Home Assistant)TN)get_provider_auth_statespotifyaccess_tokenrefresh_token)zSpotify (PKCE OAuth)TNGITHUB_TOKEN)Skills Hub (GitHub)TN)r   Fr   )zTerminal/CommandsTN)zTask Planning (todo)TN)zSkills (view, create, edit)TNc              3   &   K   | ]\  }}}|d V  dS )ry   N ).0_avails      r   	<genexpr>z'_print_setup_summary.<locals>.<genexpr>  s-      DD5!eD!DDDDDDr   /z tool categories available:z   u   ✓r   u   ✗z	(missing c                 "    g | ]\  }}}|||fS r   r   )r   r   r   r   s       r   
<listcomp>z(_print_setup_summary.<locals>.<listcomp>#  s(    SSS&6dE3UStSkSSSr   zDSome tools are disabled. Run 'hermes setup tools' to configure them,display_hermes_homezor edit z+/.env directly to add the missing API keys.   ┌─────────────────────────────────────────────────────────┐uA   │              ✓ Setup Complete!                          │   └─────────────────────────────────────────────────────────┘u   📁 All your files are in z/:z	Settings:r   z	API Keys:zData:      z/cron/, sessions/, logs/u   ────────────────────────────────────────────────────────────u    📝 To edit your configuration:zhermes setupz           Re-run the full wizardzhermes setup modelz    Change model/providerzhermes setup terminalz Change terminal backendzhermes setup gatewayz  Configure messagingzhermes setup toolsz    Configure tool providerszhermes configz         View current settingszhermes config editz    Open config in your editorzhermes config set <key> <value>z.                          Set a specific valuez   Or edit the files directly:znano u   🚀 Ready to go!hermesz              Start chattingzhermes gatewayz      Start messaging gatewayzhermes doctorz       Check for issues)1r`   rc   r   agent.auxiliary_clientr   rn   appendrZ   webmanaged_by_nous	availablecurrent_providerbrowser	image_genagent.image_gen_registryr   hermes_cli.pluginsr   r   is_availabledisplay_namerQ   r   util	find_specimportlib.utilr   direct_overrider   nous_auth_presentr*   r   r   sumr   re   r]   r\   r   REDr   rg   hermes_constantsr   ra   rb   r{   rT   rU   )r   hermes_hometool_statussubscription_featuresr   _vision_backendslabelbrowser_providermissing_browser_hint_img_backendr   r   _ptts_provider	importlib	neutts_okkittentts_okr   _spotify_stateavailable_counttotal_countr   r   missing_vardisabled_tools_dhhs                             r   _print_setup_summaryr  \  s    
GGG,---K:6BBHHHHHH88::     bBCCCC`aaa )** O<====MNNN  0 USTTTT		"	, U& $5 	[Z-B-F-WZZZEE4.////  T  	U  	U  	U -4E$4 
PQQQQ		&	0 
$ 	?>+;>>>EE4.////w},,= !  ..J !  **#0  00#A !5*>?	
 	
 	
 &6 YOPPPP		(	2 Y;<<<< 	??????EEEEEE&&((($n&&  7e##(( ') !   H 	 	 	D	 	Y D\ D D DdDQRRRRWXXX 65*fEEEL 0 "FXYYYY		%	%-8L*M*M	%FGGGG		!	!.// 
"3@AQ3R3R 
" 	BCCCC		"	"}5F'G'G	"CDDDD		"	"}5F'G'G	"KLLLL		!	!}5E'F'F	!-XhJiJi	!IJJJJ		!	!	!00::$FII 	 	 	III	 	oLMMMMmnnnn		$	$	!!!!!$>33K@@LLL 	! 	! 	! LLL	! 	rOPPPPpqqqqDEEE"2 ]NOOOO	Y	/	/7	:	: &6 	ZMNNNNXYYYY	#	%	% ]*?*Q ][\\\ %&& N=+I+I N?@@@@	'	(	( NKLLLLLMMM \"" HFGGG;;;;;;00;;Arn-- 	E1C1CO1T1T 	ECDDD    ^$$ K>????IJJJ 8999 ;<<< BCCC DD{DDDDDOk""K/LLKLLLMMM	GGG(3  $i 	;eV\22;;T;;<<<<geE6:..gggg>X+>X>X>XZ`Zd8e8egg    
GGGSS+SSSN R	
 	
 	
 	A@@@@@TTTTUUU 
GGG	 @  BH  BN	
 	
  
 
OQWQ]	
 	
  
 
 @  BH  BN	
 	
  
 
GGG =<<<<<	%8ddff888&+v{
S
STTT	GGG	
Hk6=11
H
H_5F5F
H
HIII	
Ek6=11
E
E\^^
E
EFFF	XeGV]++XX;XXX   
GGG	%
FJ
'
'(((	GGG	%2FK
M
MNNN	GGG	
Unfl33
U
U
UVVV	
T*FL99
T
T
TUUU	
V-v|<<
V
V
VWWW	
R,fl;;
R
R
RSSS	
W*FL99
W
W
WXXX	GGG	
Tov|44
T
T
TUUU	We(&,77WWW   

H7FF
H
HIII	
:;;;	GGG	
*+++	
@1o//116:>>
@
@AAA	
=.lnn..
;;
=
=>>>	GGG	%
FJ
'
'(((	GGG	%#V[&+
>
>???	GGG	
Kh--
K
K
KLLL	
T&55
T
T
TUUU	
Mov|44
M
M
MNNN	GGGGGs~   A AA.I3 I"I3 "
I/,I3 .I//I3 3
J ?J -P
 
PP Q2 2R R3AY 
YYc                 <   |                      di           }t                       t          d           |                    dd          }|rdnd}t          d           t          d           t	          d	|          }|                                d
v |d<   |                    dd          }t	          dt          |                    }	 t          |          |d<   n# t          $ r Y nw xY w|                    dd          }t	          dt          |                    }	 t          |          |d<   n# t          $ r Y nw xY w|                    dd          }	t	          dt          |	                    }
	 t          |
          |d<   dS # t          $ r Y dS w xY w)zMPrompt for container resource settings (Docker, Singularity, Modal, Daytona).r   zContainer Resource Settings:container_persistentTr   r   z5  Persistent filesystem keeps files between sessions.z;  Set to 'no' for ephemeral sandboxes that reset each time.z.  Persist filesystem across sessions? (yes/no)r   truer   1container_cpury     CPU corescontainer_memory     Memory in MB (5120 = 5GB)container_disk   z  Disk in MB (51200 = 50GB)N)

setdefaultr`   re   r   r   rK   r   floatr   r   )r   r   current_persistpersist_labelpersist_strcurrent_cpucpu_strcurrent_memmem_strcurrent_diskdisk_strs              r   _prompt_container_resourcesr1  j  s     R00H	GGG-... ll#94@@O,6EE$MFGGGLMMM8- K (3'8'8':':>W'WH#$ ,,22K]C$4$455G$)'NN!!    ,,1488K2C4D4DEEG'*7||#$$    << 0%88L3S5F5FGGH%(]]!"""   s6   C 
C+*C+"D5 5
EE9F 
FFc                 6   |                      di           }t                       t          d           t          d           t          d           ddlm} |                    d          pd}d	                    |          }t          d
| d|                                          p|}||vrt          d| d| d           ||v r|nd}||d<   t          d|           |                    dd          }|rdnd}t          d|                                          dv |d<   |                    dd          }t          dt          |                    }		 t          |	          |d<   n# t          $ r Y nw xY w|                    dd          }
t          dt          |
                    }	 t          |          |d<   n# t          $ r Y nw xY w|                    dd          dvrt          d           d|d<   t                       t          d            t          d!           t!                      }|rt          d"           t#          d#           t          d$t%          d%          pd&d'          }t          d(t%          d)          p|                    d*d&                    }t          d+t%          d,          p|                    d-d&                    }|rt          d%|           |rt          d)|           |rt          d,|           d.S d.S )/zLPrompt for Vercel Sandbox settings without exposing unsupported disk sizing.r   zVercel Sandbox settings:z/  Filesystem persistence uses Vercel snapshots.zX  Snapshots restore files only; live processes do not continue after sandbox recreation.r   )_SUPPORTED_VERCEL_RUNTIMESvercel_runtimenode24r   z  Runtime (r   zUnsupported Vercel runtime 'z', keeping .TERMINAL_VERCEL_RUNTIMEr  Tr   r   z-  Persist filesystem with snapshots? (yes/no)r  r  ry   r   r!  r"  r#  r$  r%  )r   r%  zVVercel Sandbox does not support custom disk sizing; resetting container_disk to 51200.zVercel authentication:z=  Use a long-lived Vercel access token plus project/team IDs.z1  Found defaults in nearest .vercel/project.json.VERCEL_OIDC_TOKENz    Vercel access tokenVERCEL_TOKENrJ   r   z    Vercel project IDVERCEL_PROJECT_ID	projectIdz    Vercel team IDVERCEL_TEAM_IDorgIdN)r&  r`   re   tools.terminal_toolr3  r   r   r   r   rg   rX   rK   r   r'  r   r   _read_nearest_vercel_projectrY   rZ   )r   r   r3  current_runtimesupported_labelruntimer(  r)  r+  r,  r-  r.  linked_projecttokenprojectteams                   r   _prompt_vercel_sandbox_settingsrG    s     R00H	GGG)***@AAAijjj>>>>>>ll#344@Oii :;;O5?555GGMMOObSbG000[W[[[[[\\\%48R%R%R//X`!(H,g666ll#94@@O,6EE$M'-7( (egg*(+H#$ ,,22K]C$4$455G$)'NN!!    ,,1488K2C4D4DEEG'*7||#$$    ||$e,,J>>nooo!&H	GGG'(((NOOO133N HFGGG())),mN.K.K.Qr\`aaaE)**Qn.@.@b.Q.Q G &''J>+=+=gr+J+J D  .~u--- 5*G444 /'...../ /s$   E- -
E:9E:1G 
GGstartc                 6   | pt          j                                                    }|                                r|j        }|g|j        R D ]}|dz  dz  }|                                s	 t          j        |	                    d                    }n # t          t          j        f$ r i cY c S w xY wt          |t                    si c S d |                    d          |                    d          d                                D             c S i S )	z=Read project/team defaults from the nearest Vercel link file.z.vercelzproject.jsonutf-8encodingc                 l    i | ]1\  }}t          |t                    |                                .||2S r   )r   r   r   )r   keyr   s      r   
<dictcomp>z0_read_nearest_vercel_project.<locals>.<dictcomp>  sR     
 
 
U %%%
 +0++--

 
 
r   r;  r=  )r;  r=  )r   cwdresolveis_fileparentparentsexistsjsonloads	read_textOSErrorJSONDecodeErrorr   r   r   r   )rH  current	directoryproject_filedatas        r   r?  r?    sO   "

++--G !.000 
 
	 9,~=""$$ 		:l44g4FFGGDD-. 	 	 	IIIII	$%% 	III
 
 "XXk22'**  egg
 
 
 	
 	
 	
 Is   .(BB43B4quickr`  c                   ddl m}m} t          d           t	          d           t	          dt
           d           t                       ddlm} 	  |             n# t          t          f$ r  t                       t	          d           Y nRt          $ rF}t                              d	|           t          d
|            t	          d           Y d}~nd}~ww xY w |            }|                    d|                     d                    | d<   d|v r|d         | d<   n|                     dd           d}|                     d          }t#          |t$                    r|                    d          }|s:t'          |          r*	 ddlm}	 ddlm}
 ddlm}  |
|          }|                                }t7          |          }t9          d |D                       }||z
  }t                       t          d           t	          d           t	          d           t	          d           t                       |dk    rt	          d| d| d| d| d	           nt	          d| d|            t;          dd          rp | |	|ddddddddd ddd!"                      |
|          }t7          |                                          }t	          d#| d$           t;          dd          p|d%k    rg d&}t=          |                               |d'          }dd%d(d)                    |d          }t?          d*||          }g d)|         }tA          | ||           tC          d+| d,|            n2# t          $ r%}t                              d-|           Y d}~nd}~ww xY w|rd}nS	 dd.l"m#} tI           |                      }n# t          $ r tI                      }Y nw xY wtK          |           }||v rd}|rDd/d0d1d2d3d4d5d6d7d8d9d:d;}|                    ||pd<          }t                       t          d=           t	          d>|            t	          d?           t	          d@           t                       g dA}t?          dB|d(          }|dk    rWtM          dCdDE          '                                }|r!tQ          dF|           tC          dG           nat	          dH           nP|d%k    r:tM          dI          '                                pdJ}dK}tS          |          dLk    } | rdM}tM          |dDE          '                                }!|!rtQ          dN|!           | *                    dOi           *                    dPi           }"||"dQ<   | r9g dR}#|#dSgz   }$t?          dT|$d          }%|%t7          |#          k     r|#|%         ndU}&n!tM          dV          '                                }&tQ          dW|&           tC          dX| |&rd|& dYndz              nt	          dH           nt	          dZ            ||            |s|d[k    rtW          |            dS dS dS )\u  Configure the inference provider and default model.

    Delegates to ``cmd_model()`` (the same flow used by ``hermes model``)
    for provider selection, credential prompting, and model picking.
    This ensures a single code path for all provider setup — any new
    provider added to ``hermes model`` is automatically available here.

    When *quick* is True, skips credential rotation, vision, and TTS
    configuration — used by the streamlined first-time quick setup.
    r   )rV   rW   zInference Providerz.Choose how to connect to your main chat model.
   Guide: z/integrations/providers)select_provider_and_modelzProvider setup skipped.z0select_provider_and_model error during setup: %sz%Provider setup encountered an error: z*You can try again later with: hermes modelNr   custom_providersr   )SimpleNamespace)	load_pool)auth_add_commandc              3   |   K   | ]7}t          t          |d d                                        d          3dV  8dS )sourcerJ   manualry   N)r   rj   
startswith)r   entrys     r   r   z'setup_model_provider.<locals>.<genexpr>8  sK      ppUWUHVX=Y=Y9Z9Z9e9efn9o9opqppppppr   z!Same-Provider Fallback & RotationzHHermes can keep multiple credentials for one provider and rotate betweenzCthem when a credential is exhausted or rate-limited. This preserveszEyour primary provider while reducing interruptions from quota issues.zCurrent pooled credentials for rx   z (z	 manual, z$ auto-detected from env/shared auth)z2Add another credential for same-provider fallback?FrJ   g      .@,  )r   r+   r
  r(   
portal_urlinference_url	client_idscope
no_browsertimeoutinsecure	ca_bundlemin_key_ttl_secondszProvider pool now has z credential(s).ry   )uU   Fill-first / sticky — keep using the first healthy credential until it is exhausteduJ   Round robin — rotate to the next healthy credential after each selectionu5   Random — pick a random healthy credential each time
fill_first   )rw  round_robinrandomz'Select same-provider rotation strategy:zSaved z rotation strategy: z7Could not configure same-provider fallback in setup: %sr   zNous Portal API keyzGitHub CopilotzGitHub Copilot ACPz
Z.AI / GLMzKimi / MoonshotzKimi / Moonshot (China)zStepFun Step PlanMiniMaxz
MiniMax CN	AnthropiczVercel AI Gatewayzyour custom endpoint)znous-apir;   r.   r=   r>   r?   r@   rB   rC   	anthropicrD   r$   zyour providerz"Vision & Image Analysis (optional)z+Vision uses a separate multimodal backend. z=doesn't currently provide one Hermes can auto-use for vision,z4so choose a backend now or skip and configure later.)u<   OpenRouter — uses Gemini (free tier at openrouter.ai/keys)uB   OpenAI-compatible endpoint — base URL, API key, and vision modelzSkip for nowzConfigure vision:z  OpenRouter API keyTr   r   u/   OpenRouter key saved — vision will use Geminiu%   Skipped — vision won't be availablez  Base URL (blank for OpenAI)zhttps://api.openai.com/v1z	  API keyzapi.openai.comz  OpenAI API keyr   	auxiliaryvisionbase_url)r2   r3   r1   zgpt-4.1-minizgpt-4.1-nanozUse default (gpt-4o-mini)zSelect vision model:r3   z0  Vision model (blank = use main/custom default)AUXILIARY_VISION_MODELzVision configured with r   uR   Skipped — add later with 'hermes setup' or configure AUXILIARY_VISION_* settingsnous),hermes_cli.configrV   rW   rc   re   
_DOCS_BASEr`   hermes_cli.mainrc  
SystemExitr}   rn   loggerdebugrg   r   popr   r   r-   typesre  agent.credential_poolrf  hermes_cli.auth_commandsrg  entriesr   r  r   r   r   r"   rf   r   r   r   rl   r   r   rX   r	   r&  _setup_tts_provider)'r   r`  rV   rW   rc  exc
_refreshedselected_provider_mre  rf  rg  poolr  entry_countmanual_count
auto_countstrategy_labelscurrent_strategydefault_strategy_idxstrategy_idxstrategy_value_vision_needs_setupr   r	  _prov_names_prov_display_vision_choices_vision_idx_or_key	_base_url_api_key_label_is_native_openai_oai_key_vaux_oai_vision_models_vm_choices_vm_idx_selected_vision_models'                                          r   setup_model_providerr    s	    ;:::::::%&&&?@@@?J???@@@	GGG :99999A!!####)* . . .,----- A A AGMMMCcCCDDD?@@@@@@@@A J nnWfjj.A.ABBF7OZ''%/0B%C!""

%t,,, 	G		B"d /FF:..  JY78IJJ JYI	Y------777777AAAAAA9.//DllnnGg,,KppgpppppL$|3JGGG<===Z   U   W   GGGA~~`6G ` `; ` `$` `/9` ` `   
 _=N__R]__``` TV[\\ R  #O!2"$" $#'&*"&"#( $!&"&,2    " !y!233!$,,..11PKPPPQQQ)   TV[\\ R, Q# # #
 $C6#J#J#N#NO`bn#o#o "##$( ( #&**	 %
  -=#(   
 "I!H!H!V-f6GXXX^'8^^n^^___ 	Y 	Y 	YLLRTWXXXXXXXX	Y  (#	%LLLLLL"#@#@#B#BCC 	% 	% 	%"uu	% #''7"8"88 000"' Em-'/,7* &$-,
 
 $(9;L;_P_``9:::PPPQQQRSSSIJJJ
 
 

 $$7!LL!3dCCCIIKKG D3W===OPPPPBCCCCA>??EEGGfKfI(N 1) < <@P P  4!3nt<<<BBDDH D/:::))+r::EEhPRSS$-j!$ 
p)m)m)m&"48S7T"TK+,BKQRSSG #S);%<%<<< +733* +* .44f-g-g-m-m-o-o*79OPPP9i999OW525555UWY   
 BCCCCklll K $&&00F#####$ $00sI   
A .C	C<CCG6N	 	
N8N33N8O O:9O:c                  Z    t          j        d          dupt          j        d          duS )z Check if espeak-ng is installed.	espeak-ngNespeak)shutilwhichr   r   r   _check_espeak_ngr    s,    <$$D0VFL4J4JRV4VVr   c            	         ddl } ddl}t                      sCt                       t	          d           |j        dk    rt          d           n*|j        dk    rt          d           nt          d           t                       t          d	d
          r	 |j        dk    r|                     g dd
           n>|j        dk    r|                     g dd
           n|                     g dd
           t          d           nO# | j
        t          f$ r,}t	          d|            t          d           Y d}~dS d}~ww xY wt	          d           t                       t          d           t          d           t                       	 |                     |j        ddddddgd
d           t          d           d
S # | j
        | j        f$ r,}t          d|            t          d            Y d}~dS d}~ww xY w)!zHInstall NeuTTS dependencies with user approval. Returns True on success.r   Nz,NeuTTS requires espeak-ng for phonemization.darwinz$Install with: brew install espeak-ngwin32z%Install with: choco install espeak-ngz(Install with: sudo apt install espeak-ngzInstall espeak-ng now?T)brewinstallr  )check)chocor  r  -y)sudoaptr  r  r  zespeak-ng installedz+Could not install espeak-ng automatically: z,Please install it manually and re-run setup.FzJespeak-ng is required for NeuTTS. Install it manually before using NeuTTS.z#Installing neutts Python package...z<This will also download the TTS model (~300MB) on first use.-mpipr  -Uzneutts[all]--quietrm  r  rs  zneutts installed successfullyzFailed to install neutts: z2Try manually: python -m pip install -U neutts[all])
subprocessrk   r  r`   rg   platformre   r   runrf   CalledProcessErrorFileNotFoundError
executableTimeoutExpiredrd   )r  rk   es      r   _install_neutts_depsr    s   JJJ  hDEEE<8##=>>>>\W$$>????ABBB1488 	h<8++NN#C#C#C4NPPPP\W,,NN#J#J#JRVNWWWWNN#P#P#PX\N]]]3444413DE   OAOOPPPIJJJuuuuu
 fggg 
GGG4555MNNN	GGG
^T5)T=)T 	 	
 	
 	
 	5666t):+DE   444555GHHHuuuuus1   A2D E	!EE	3G H!HHc            
      b   ddl } ddl}d}t                       t          d           t                       	 |                     |j        dddd|d	d
gdd           t          d           dS # | j        | j        f$ r0}t          d|            t          d| d           Y d}~dS d}~ww xY w)zKInstall KittenTTS dependencies with user approval. Returns True on success.r   Nz^https://github.com/KittenML/KittenTTS/releases/download/0.8.1/kittentts-0.8.1-py3-none-any.whlzOInstalling kittentts Python package (~25-80MB model downloaded on first use)...r  r  r  r  	soundfiler  Trm  r  z kittentts installed successfullyzFailed to install kittentts: z(Try manually: python -m pip install -U 'z' soundfileF)
r  rk   r`   re   r  r  rf   r  r  rd   )r  rk   	wheel_urlr  s       r   _install_kittentts_depsr    s    JJJ	1  
GGG`aaa	GGG
^T5)T9kS\] 	 	
 	
 	
 	8999t):+DE   7A77888TiTTTUUUuuuuus   4A- -B.>%B))B.c           
         |                      di           }|                     dd          }t          |           }dddddd	d
ddd	}|                     ||          }t                       t          d           t	          d|            t                       g }g }t                      r1|j        r*|                    d           |                    d           |                    g d           |                    g d           |                    d| d           t          |          dz
  }t          d||          }	|	|k    rdS ||	         }
|
dk    }|
dk    r>d}
t	          d           t          d          st          d          rt          d           |
dk    r	 |j                            d          du}n# t          $ r d}Y nw xY w|rt!          d           nt                       t	          d            t	          d!           t	          d"           t                       t#          d#d$          r!t%                      st          d%           d}
n=t	          d&           d}
n*|
d'k    rft          d(          }|sSt                       t'          d)d$*          }|r!t)          d(|           t!          d+           nt          d,           d}
n|
dk    rw|sut          d          pt          d          }|sSt                       t'          d-d$*          }|r!t)          d|           t!          d.           nTt          d,           d}
nA|
d/k    rt          d0          }|sdt                       t'          d1d$*          }|r t)          d0|           t!          d2           n#d3d4lm} t          d5 |             d6           d}
|
d/k    rt                       t'          d7          }|rw|                                rc|                                |                     di                               d/i           d8<   t!          d9|                                            n'|
d:k    rft          d;          }|sSt                       t'          d<d$*          }|r!t)          d;|           t!          d=           nt          d,           d}
n|
d>k    rft          d?          }|sSt                       t'          d@d$*          }|r!t)          d?|           t!          dA           nbt          d,           d}
nO|
dBk    rt          dC          pt          dD          }|sat                       t	          dE           t'          dFd$*          }|r t)          dC|           t!          dG           nt          d,           d}
n|
dHk    r	 d3dl}|j                            dH          du}n# t          $ r d}Y nw xY w|rt!          dI           n{t                       t	          dJ           t	          dK           t                       t#          dLd$          r t5                      st          dM           d}
nt	          dN           d}
d| vri | d<   |
| d         d<   t7          |            t!          dO|                     |
|
                      dS )Pz@Interactive TTS provider selection with install flow for NeuTTS.r   r   r   zEdge TTS
ElevenLabsz
OpenAI TTSzxAI TTSzMiniMax TTSzMistral Voxtral TTSzGoogle Gemini TTSNeuTTS	KittenTTS)	r   r   r   xairB   r   r<   r   r   z"Text-to-Speech Provider (optional)z	Current: zCNous Subscription (managed OpenAI TTS, billed to your subscription)znous-openai)	z-Edge TTS (free, cloud-based, no setup needed)z+ElevenLabs (premium quality, needs API key)z(OpenAI TTS (good quality, needs API key)z$xAI TTS (Grok voices, needs API key)z<MiniMax TTS (high quality with voice cloning, needs API key)z>Mistral Voxtral TTS (multilingual, native Opus, needs API key)zJGoogle Gemini TTS (30 prebuilt voices, prompt-controllable, needs API key)z5NeuTTS (local on-device, free, ~300MB model download)z<KittenTTS (local on-device, free, lightweight ~25-80MB ONNX)Keep current (r   ry   zSelect TTS provider:Nr   zKOpenAI TTS will use the managed Nous gateway and bill to your subscription.r   r   ziDirect OpenAI credentials are still configured and may take precedence until removed from ~/.hermes/.env.r   FzNeuTTS is already installedzNeuTTS requires:uH     • Python package: neutts (~50MB install + ~300MB model on first use)u,     • System package: espeak-ng (phonemizer)z Install NeuTTS dependencies now?Tz9NeuTTS installation incomplete. Falling back to Edge TTS.zISkipping install. Set tts.provider to 'neutts' after installing manually.r   r   zElevenLabs API keyr   zElevenLabs API key savedz.No API key provided. Falling back to Edge TTS.zOpenAI API key for TTSzOpenAI TTS API key savedr  XAI_API_KEYzxAI API key for TTSzxAI TTS API key savedr   r   zQNo xAI API key provided for TTS. Configure XAI_API_KEY via hermes setup model or z//.env to use xAI TTS. Falling back to Edge TTS.z:xAI voice_id (Enter for 'eve', or paste a custom voice ID)voice_idzxAI voice_id set to: rB   r   zMiniMax API key for TTSzMiniMax TTS API key savedr   r   zMistral API key for TTSzMistral TTS API key savedr<   r   r   z<Get a free API key at https://aistudio.google.com/app/apikeyzGemini API key for TTSzGemini TTS API key savedr   zKittenTTS is already installedzCKittenTTS is lightweight (~25-80MB, CPU-only, no API key required).z:Voices: Jasper, Bella, Luna, Bruno, Rosie, Hugo, Kiki, LeozInstall KittenTTS now?z<KittenTTS installation incomplete. Falling back to Edge TTS.zLSkipping install. Set tts.provider to 'kittentts' after installing manually.zTTS provider set to: )r   r   r`   rc   re   r   r  r   extendr   r   rZ   rg   r   r   rn   rf   r   r  r   rX   r  r   r   r&  r   r  rW   )r   
tts_configr   r  provider_labelscurrent_labelr   	providerskeep_current_idxr   r   selected_via_nousr  already_installedexistingr(   r  r  s                     r   r  r  .  s4   E2&&J!~~j&99:6BB " (% 
 
O $''(8:JKKM	GGG5666*=**+++	GGGGI!## ((=(O (\]]]'''NN
	
 
	
 
	
   ssstttNN4M4445557||a'
.9I
J
JC
~H M1=  `aaa122 	mDT6U6U 	{   8	& ) 8 8 B B$ N 	& 	& 	& %	&  	"78888GGG)***abbbEFFFGGG?FF "+-- &!"]^^^%Hfggg!	\	!	! !566 	"GGG1DAAAG "3W===89999NOOO!	X		&7	 !9::]mL\>]>] 	"GGG5EEEG "7AAA89999NOOO!	U		 // 	"GGG2TBBBG 
"}g66656666HHHHHH0-1TVV0 0 0  
 "uGGGZ[[H JHNN,, JQYQ_Q_QaQa!!%,,77rBB:NHhnn6F6FHHIII 
Y		 !233 	"GGG6FFFG "0':::9::::NOOO!	Y		 !233 	"GGG6FFFG "0':::9::::NOOO!	X		 !122UmDT6U6U 		"GGGUVVV5EEEG "/99989999NOOO!	[	 	 	&!!!! ) 8 8 E ET Q 	& 	& 	& %	&  	":;;;;GGG\]]]STTTGGG5t<< ".00 &!"`aaa%Hijjj! Fu (F5M*S/*=*=h*Q*QSSTTTTTs$   )G GG" X XXc                 $    t          |            dS )z.Standalone TTS setup (for 'hermes setup tts').N)r  r   s    r   	setup_ttsr    s    r   c           	      6   ddl }t          d           t          d           t          d           t          dt           d           t	                       t          | dd	d
          }|                                dk    }g d}d
dddddd}ddddddd}d}|r$|                    d           d||<   ||d<   |dz  }|}|                    d| d           |||<   t          d||          }	|	                    |	          }
|	|k    rt          d |            dS |
| 
                    di           d	<   |
d
k    rt          d!           t          d"           t	                       t          d#           t          d$           t          d%           t          | dd&d'          }t          d(|pt          t          j                                        }|r|| d         d&<   t	                       t!          d)          }|rt          d*           
n`t#          d+d,          r2t          d-d./          }|rt%          d)|           t          d0           
n|
dk    rt          d1           t'          j        d          }|st+          d2           t          d3           nt          d4|            t          | dd5d6          }t          d7|          }|| d         d5<   t%          d8|           t-          |            	nq|
dk    rt          d9           t'          j        d:          pt'          j        d          }|st+          d;           t          d<           nt          d=|            t          | dd>d?          }t          d@|          }|| d         d><   t%          dA|           t-          |            n|
dk    rt          dB           t          dC           ddDlm} ddElm} t7          t9                      ot;          |           j        o
 |d                    } |t          | ddF                    }d,}|r@dGdHg}|dIk    rd}n|dJk    rd}nt!          dK          rdnd}t          dL||          }|dk    }|rIdI| d         dF<   t          dM           t!          dK          st!          dN          rt          dO           ndJ| d         dF<   t          dP           	 t?          d           n# t@          $ r t          dQ           ddl!}t'          j        dR          }|r)|"                    |dSdTdUtF          j$        dgd.d.V          }n'|"                    tF          j$        dWdSdTdgd.d.V          }|j%        dk    rt          dX           nt+          dY           Y nw xY wt	                       t          dZ           t          d[           t!          dK          }|rft          d\           t#          d]d,          rFt          d^d./          }t          d_d./          } |rt%          dK|           | rt%          dN|            nFt          d^d./          }t          d_d./          } |rt%          dK|           | rt%          dN|            t-          |            n|
dk    r:t          d`           t          da           t          db           t          dc           	 t?          d           n# t@          $ r t          dd           ddl!}t'          j        dR          }|r)|"                    |dSdTdUtF          j$        dgd.d.V          }n'|"                    tF          j$        dWdSdTdgd.d.V          }|j%        dk    rt          de           nWt+          df           |j&        rAt          dg|j&        '                                (                                dh                     Y nw xY wt	                       t!          di          }!|!rRt          dj           t#          dkd,          r2t          dld./          }"|"rt%          di|"           t          dm           n2t          dld./          }"|"rt%          di|"           t          dn           t          | ddod6          }t          dp|          }|| d         do<   t%          dq|           t-          |            n|
dk    rJt          dr           t          ds           t          dt           	 t?          du           n# t@          $ r t          dv           ddl!}t'          j        dR          }|r)|"                    |dSdTdUtF          j$        dugd.d.V          }n'|"                    tF          j$        dWdSdTdugd.d.V          }|j%        dk    rt          dw           nWt+          dx           |j&        rAt          dg|j&        '                                (                                dh                     Y nw xY wtS          |            n4|
dk    r-t          dy           t          dz           t!          d{          pd'}#t          d||#          }$|$rt%          d{|$           t!          d}          pd'}%t          d~|%ptU          j+        dd'                    }&|&rt%          d}|&           t!          d          pd}'t          d|'          }(|(r|(dk    rt%          d|(           t!          d          pd'})t          t          j                    dz  dz            }*t          d|)p|*          }+|+rt%          d|+           |$rt#          dd.          rt          d           ddl!}g d},|+r|,,                    d|+g           |(r|(dk    r|,,                    d|(g           |,                    |&r|& d|$ n|$           |,                    d           |"                    |,d.d.d          }|j%        dk    rt          d           n8t+          d|j&        '                                            t          d           t%          d|
           |
dk    r*t%          d| d         	                    dFd                     |
dk    r*t%          d| d         	                    dd                     t[          |            t	                       t          d|
            dS )z)Configure the terminal execution backend.r   NTerminal Backendz1Choose where Hermes runs shell commands and code.z8This affects tool execution, file access, and isolation.rb  z/developer-guide/environmentsr   r   localr   Linux)z.Local - run directly on this machine (default)z7Docker - isolated container with configurable resourcesz Modal - serverless cloud sandboxzSSH - run on a remote machinez2Daytona - persistent cloud development environmentzCVercel Sandbox - cloud microVM with snapshot filesystem persistencedockerr   sshdaytonavercel_sandbox)r   ry   rx  r         ry   rx  r   r  r  )r  r  r   r  r  r     z.Singularity/Apptainer - HPC-friendly containersingularityr  r   zSelect terminal backend:zKeeping current backend: zTerminal backend: Localz&Commands run directly on this machine.z)Working directory for messaging sessions:z7  When using Hermes via Telegram/Discord, this is wherezD  the agent starts. CLI mode always starts in the current directory.rP  rJ   z  Messaging working directorySUDO_PASSWORDzSudo password: configuredz<Enable sudo support? (stores password for apt install, etc.)Fz  Sudo passwordTr   zSudo password savedzTerminal backend: DockerzDocker not found in PATH!z3Install Docker: https://docs.docker.com/get-docker/zDocker found: docker_imagez*nikolaik/python-nodejs:python3.11-nodejs20z  Docker imageTERMINAL_DOCKER_IMAGEz'Terminal backend: Singularity/Apptainer	apptainerz(Singularity/Apptainer not found in PATH!z@Install: https://apptainer.org/docs/admin/main/installation.htmlzFound: singularity_imagez3docker://nikolaik/python-nodejs:python3.11-nodejs20z  Container imageTERMINAL_SINGULARITY_IMAGEzTerminal backend: Modalz@Serverless cloud sandboxes. Each session gets its own container.)is_managed_tool_gateway_ready)normalize_modal_mode
modal_modezUse my Nous subscriptionzUse my own Modal accountmanageddirectMODAL_TOKEN_IDz,Select how Modal execution should be billed:zPModal execution will use the managed Nous gateway and bill to your subscription.MODAL_TOKEN_SECRETzZDirect Modal credentials are still configured, but this backend is pinned to managed mode.z+Requires a Modal account: https://modal.comzInstalling modal SDK...uvr  r  --pythoncapture_outputtextr  zmodal SDK installedu2   Install failed — run manually: pip install modalzModal authentication:z/  Get your token at: https://modal.com/settingsz!  Modal token: already configuredz  Update Modal credentials?z    Modal Token IDz    Modal Token SecretzTerminal backend: Daytonaz*Persistent cloud development environments.zBEach session gets a dedicated sandbox with filesystem persistence.zSign up at: https://daytona.iozInstalling daytona SDK...zdaytona SDK installedu4   Install failed — run manually: pip install daytona	  Error: r   DAYTONA_API_KEYz%  Daytona API key: already configuredz  Update API key?z    Daytona API keyz    Updatedz    Configureddaytona_imagez  Sandbox imageTERMINAL_DAYTONA_IMAGEz Terminal backend: Vercel SandboxzDCloud microVM sandboxes with snapshot-backed filesystem persistence.z=Requires the optional SDK: pip install 'hermes-agent[vercel]'vercelzInstalling vercel SDK...zvercel SDK installeduC   Install failed — run manually: pip install 'hermes-agent[vercel]'zTerminal backend: SSHz)Run commands on a remote machine via SSH.TERMINAL_SSH_HOSTz  SSH host (hostname or IP)TERMINAL_SSH_USERz
  SSH userUSERTERMINAL_SSH_PORT22z
  SSH portTERMINAL_SSH_KEYz.sshid_rsaz  SSH private key pathz  Test SSH connection?z  Testing connection...)r  -ozBatchMode=yesr  zConnectTimeout=5z-iz-p@zecho ok
   )r  r  rs  z  SSH connection successful!z  SSH connection failed: z'  Check your SSH key and host settings.TERMINAL_ENVTERMINAL_MODAL_MODEautor7  r4  r5  zTerminal backend set to: ).r  rc   re   r  r`   rQ   systemr   r   r   r&  rf   r   r   r   homerZ   r   rX   r  r  rg   r1  tools.managed_tool_gatewayr  tools.tool_backend_helpersr  rl   r   r   r  
__import__ImportErrorr  r  rk   r  
returncodestderrr   
splitlinesrG  osgetenvr  rW   )-r   	_platformcurrent_backendis_linuxterminal_choicesidx_to_backendbackend_to_idxnext_idxr  terminal_idxselected_backendcurrent_cwdrP  existing_sudo	sudo_pass
docker_bincurrent_imageimagesing_binr  r  managed_modal_availabler  use_managed_modalmodal_choicesdefault_modal_idxmodal_mode_idxr  uv_binresultexisting_tokentoken_idtoken_secretexisting_keyr(   current_hosthostcurrent_userusercurrent_portportcurrent_keydefault_keyssh_keyssh_cmds-                                                r   setup_terminal_backendrB    s       #$$$BCCCIJJJEJEEEFFF	GGGfj)WMMMO!!W,H   !X'e	VfggN A!PQefggNH  PQQQ#0x (0}%A  ?_???@@@'6N#$ "$46F L &)),77'''@@@AAA3CFj"%%i07""/000;<<< 	>???LMMMR	
 	
 	
 fj%DDD4k6USEUEUVV 	,(+F:u% 	%o66 		923333NPU  9 ##4tDDD	 9"?I>>>!"7888	X	%	%0111 \(++
 	65666LMMMM4
44555  
NLxyyy'77-2z>*.666#F++++	]	*	*?@@@ <,,K]0K0K 	-DEEER    +++,,,
4G  RG  H  H  H*M::27z./3U;;;#F++++	W	$	$/000UVVVLLLLLLCCCCCC"&&(( 7*622D7 .-g66	#
 #
 *)'&*l*S*STT
!" 	4**M Y&&$%!!x''$%!!)67G)H)H$OAAa!*>! N
 !/! 3 ?	G/8F:|,ijjj-.. -@T2U2U p   08F:|,DEEEX7#### X X X4555!!!!d++ '^^"!%&N# (,! ,  FF (^^uiI'+! ,  F
 $))!"78888!"VWWW7X< GGG.///HIII*+;<<N G>??? !>FF K%&:TJJJH#)*BT#R#R#RL C&'7BBB# K&';\JJJ!"6FFF%&>NNN ?"#3X>>> G"#7FFF#F++++	Y	&	&1222?@@@WXXX3444	Uy!!!! 	U 	U 	U2333\$''F #UIz3>9U#' (   $^T5)YG#' (  
  A%%56666TUUU= US6=+>+>+@+@+K+K+M+Mb+QSSTTT-	U2 	$%677 	0>???0%88 1 !6FFF 1"#4g>>>!-0002TBBBG 00':::.///  
OMyzzz(-88.3z?+/777#F++++	-	-	-8999YZZZRSSS	Ux     	U 	U 	U1222\$''F #UIz3>8T#' (   $^T5)XF#' (  
  A%%45555cddd= US6=+>+>+@+@+K+K+M+Mb+QSSTTT-	U0 	(////	U	"	"-...>??? %%899?R3\BB 	6.555 %%899?RlL$IBIfb4I4IJJ 	6.555 %%899ATlL11 	6DDLL.555 $$677=2$)++.9::1;3M+NN 	8-w777  	FM":DAA 	F0111NNNG 0g/// -d|,,,NNt=d++T+++>>>NN9%%%^^GDtUW^XXF A%%<====Q&-:M:M:O:OQQRRRDEEE >#34447"",fZ.@.D.D\SY.Z.Z[[[+++0&2D2H2HIY[c2d2deee	GGG@.>@@AAAAAs9   7T B-V76V78\ C5` ?` *d: :C5h21h2c                    d|                      di           d<   t          d           d|                      di           d<   d|                      d	i           d
<   d| d	         d<   |                      di                               dddd           t          |            t	          d           t          d           t          d           t          d           t          d           t          d           dS )zDApply recommended defaults for all agent settings without prompting.Z   rH   	max_turnsHERMES_MAX_ITERATIONSallr   tool_progressTcompressionenabled      ?	thresholdsession_resetboth  r  )modeidle_minutesat_hourzApplied recommended defaults:z  Max iterations: 90z  Tool progress: allz  Compression threshold: 0.50z5  Session reset: inactivity (1440 min) + daily (4:00)z.  Run `hermes setup agent` later to customize.N)r&  rY   updaterW   rf   re   r  s    r   _apply_default_agent_settingsrT  r  s   24Fgr"";/
 ,---8=Fi$$_56:FmR((3)-F=+&
or**113 3    1222%&&&%&&&.///FGGG?@@@@@r   c           	      X   t          d           t          dt           d           t                       t	          t          | ddd                    }t          d           t          d	           t          d
| d           t          d|          }	 t          |          }|dk    rP||                     di           d<   | 	                    dd           t          d           t          d|            n# t          $ r t          d           Y nw xY wt          d           t          d           t          d           t          d           t          d           t          d           t          d           t          | ddd          }t          d|          }|                                dv rZd| vri | d<   |                                | d         d<   t          |            t          d|                                            nt          d| d | d!           t          d"           t          d#           t          d$           d%|                     d&i           d'<   t          | d&d(d)          }t          d*t	          |                    }	 t!          |          }d)|cxk    rd+k    rn n|| d&         d(<   n# t          $ r Y nw xY wt          d,| d&                             d(d)                      t          d-           t          d.           t          d/           t          d           t          d0           t          d1           t          d2           t          d           t          d3           t          d           g d4}	|                     d5i           }
|
                    d6d7          }|
                    d8d9          }|
                    d:d;          }dd<d=d>d?                    |d          }t%          d@|	|          }|                     d5i            |dk    rd7| d5         d6<   t          dAt	          |                    }	 t          |          }|dk    r|| d5         d8<   n# t          $ r Y nw xY wt          dBt	          |                    }	 t          |          }d|cxk    rdCk    rn n|| d5         d:<   n# t          $ r Y nw xY wt          dD| d5                             d8d9           dE| d5                             d:d;           dF           nU|d<k    rdG| d5         d6<   t          dAt	          |                    }	 t          |          }|dk    r|| d5         d8<   n# t          $ r Y nw xY wt          dD| d5                             d8d9           dH           n|d=k    rdI| d5         d6<   t          dBt	          |                    }	 t          |          }d|cxk    rdCk    rn n|| d5         d:<   n# t          $ r Y nw xY wt          dJ| d5                             d:d;           dF           n/|d>k    r)dK| d5         d6<   t          dL           t          dM           t          |            dS )NzSConfigure agent behavior: iterations, progress display, compression, session reset.Agent Settingsrb  z/user-guide/configurationrH   rE  rD  r   z1Maximum tool-calling iterations per conversation.z3Higher = more complex tasks, but costs more tokens.zPress Enter to keep z5. Use 90 for most tasks or 150+ for open exploration.zMax iterationsr   NrF  zMax iterations set to z%Invalid number, keeping current valuerJ   zTool Progress Displayz=Controls how much tool activity is shown (CLI and messaging).u-     off     — Silent, just the final responseu>     new     — Show tool name only when it changes (less noise)u7     all     — Show every tool call with a short previewu0     verbose — Full args, results, and debug logsr   rH  rG  zTool progress mode)offnewrG  verbosezTool progress set to: zUnknown mode 'z', keeping ''zContext CompressionzAAutomatically summarizes old messages when context gets too long.zNHigher threshold = compress later (use more context). Lower = compress sooner.TrI  rJ  rL  rK  z Compression threshold (0.5-0.95)gffffff?z%Context compression threshold set to zSession Reset PolicyzJMessaging sessions (Telegram, Discord, etc.) accumulate context over time.zMEach message adds to the conversation history, which means growing API costs.zMTo manage this, sessions can automatically reset after a period of inactivityzLor at a fixed time each day. When a reset happens, the agent saves importantuR   things to its persistent memory first — but the conversation context is cleared.z=You can also manually reset anytime by typing /reset in chat.)zDInactivity + daily reset (recommended - reset whichever comes first)z6Inactivity only (reset after N minutes of no messages)z+Daily only (reset at a fixed hour each day)zDNever auto-reset (context lives until /reset or context compression)zKeep current settingsrM  rP  rN  rQ  rO  rR  r  ry   rx  r   )rN  idledailynonezSession reset mode:z  Inactivity timeout (minutes)z%  Daily reset hour (0-23, local time)   zSessions reset after z min idle or daily at z:00r[  z min of inactivityr\  zSessions reset daily at r]  zGSessions will never auto-reset. Context is managed only by compression.zFLong conversations will grow in cost. Use /reset manually when needed.)rc   re   r  r`   r   rQ   r   r   r&  r  rY   rf   r   rg   rK   rW   r'  r   r   )r   current_maxmax_iter_strmax_itercurrent_moderP  current_thresholdthreshold_strrL  reset_choicescurrent_policycurrent_idlecurrent_hourdefault_reset	reset_idxidle_stridle_valhour_strhour_vals                      r   setup_agent_settingsro    sF    !"""AJAAABBB	GGG gfg{BGGGHHKBCCCDEEEa{aaa   *K88L?|$$a<<
 ;CFgr**;7JJ{D)))4555=8==>>> ? ? ?=>>>>>? rNNN&'''NOOO>???OPPPHIIIABBB69ouMMML&55Dzz||777F"" "F9-1ZZ\\y/*F=tzz||==>>>>HtHHHHHIII &'''RSSSX   7;FmR((3{DQQQ=sCT?U?UVVM-((	)####t#####1:F=!+.    ^}0E0I0I+W[0\0\^^  
 '(((T   W   rNNNW   V   \   rNNNNOOOrNNN  M ZZ44N!%%ff55L!%%nd;;L!%%i33LAqAAEElTUVVM3]MRRI
or***A~~*0':C<M<MNN	8}}H!||:B'7 	 	 	D	A3|CTCTUU	8}}HH"""""""""5='	2 	 	 	D	 \F?$;$?$?PT$U$U  \  \ms  uD  nE  nI  nI  JS  UV  nW  nW  \  \  \	
 	
 	
 	
 
a*0':C<M<MNN	8}}H!||:B'7 	 	 	D	iF?$;$?$?PT$U$Uiii	
 	
 	
 	
 
a*1'A3|CTCTUU	8}}HH"""""""""5='	2 	 	 	D	Uvo'>'B'B9a'P'PUUU	
 	
 	
 	
 
a*0'U	
 	
 	
 	T	
 	
 	

 sm   A%C> >DD&*K 
KK0 R 
RR?*S* *
S76S75 V 
V#"V#*X. .
X;:X;c                     t          d           t          d          } | rt          d           t          dd          st          d          srt          d           t          dd	          rSt          d
           t	          d          }|r3t          d|                    dd                     t          d           dS t          d           ddl}	 t	          dd	          }|sdS |	                    d|          st          d           <	 t          d|           t          d           t                       t          d           t          d           t          d           t          d           t                       t	          d          }|r4t          d|                    dd                     t          d           nt          d           t                       t          d           t          d           t          d            |r-|                    d!          d                                         nd}|r]t          d"| d#d	          r$t          d$|           t          d%|            dS t	          d&          }|rt          d$|           dS dS t          d'           t	          d(          }|rt          d$|           dS dS ))z1Configure Telegram bot credentials and allowlist.TelegramTELEGRAM_BOT_TOKENzTelegram: already configuredzReconfigure Telegram?FTELEGRAM_ALLOWED_USERSuA   ⚠️  Telegram has no user allowlist - anyone can use your bot!Add allowed users now?Tz6   To find your Telegram user ID: message @userinfobot"Allowed user IDs (comma-separated)r   rJ   zTelegram allowlist configuredNz'Create a bot via @BotFather on Telegramr   zTelegram bot tokenr   z^\d+:[A-Za-z0-9_-]{30,}$znInvalid token format. Expected: <numeric_id>:<alphanumeric_hash> (e.g., 123456789:ABCdefGHI-jklMNOpqrSTUvwxYZ)zTelegram token saved,   🔒 Security: Restrict who can use your botz!   To find your Telegram user ID:z&   1. Message @userinfobot on Telegramz:   2. It will reply with your numeric ID (e.g., 123456789)?Allowed user IDs (comma-separated, leave empty for open access)zATelegram allowlist configured - only listed users can use the botu@   ⚠️  No allowlist set - anyone who finds your bot can use it!:   📬 Home Channel: where Hermes delivers cron job results,.   cross-platform messages, and notifications.z:   For Telegram DMs, this is your user ID (same as above).,zUse your user ID (z) as the home channel?TELEGRAM_HOME_CHANNELzTelegram home channel set to zHHome channel ID (or leave empty to set later with /set-home in Telegram)zI   You can also set this later by typing /set-home in your Telegram chat.z*Home channel ID (leave empty to set later))rc   rZ   re   r   r   rX   replacerf   rematchrd   r`   splitr   )r  allowed_usersr}  rD  first_user_idhome_channels         r   _setup_telegramr  @  s[   122H 12224e<< 
	 !9:: G^___ !94@@ GWXXX$*+O$P$PM$ G&'?AVAVWZ\^A_A_```%&EFFFF8999III
+d;;; 	Fxx3U;; 	@   '///()))	GGG=>>>23337888KLLL	GGGI M  W/1F1FsB1O1OPPPYZZZZUVVV	GGGKLLL?@@@KLLL;HPM'',,Q/55777bM BSmSSSUYZZ 	F2MBBBI-IIJJJJJ!"lmmL F6EEEEEF F 	^___JKK 	B2LAAAAA	B 	Br   c                     t          d           t          d          } | rt          d           t          dd          st          d          st          d           t          dd	          rat          d
           t	          d          }|rAt          |          }t          dd                    |                     t          d           dS t          d           t	          dd	          }|sdS t          d|           t          d           t                       t          d           t          d           t          d           t          d           t                       t          d           t                       t	          d          }|rBt          |          }t          dd                    |                     t          d           nt          d           t                       t          d           t          d           t          d           t          d           t          d           t	          d          }|rt          d |           dS dS )!z0Configure Discord bot credentials and allowlist.DiscordDISCORD_BOT_TOKENzDiscord: already configuredzReconfigure Discord?FDISCORD_ALLOWED_USERSu@   ⚠️  Discord has no user allowlist - anyone can use your bot!rt  TuJ      To find Discord ID: Enable Developer Mode, right-click name → Copy IDru  rz  zDiscord allowlist configuredNz;Create a bot at https://discord.com/developers/applicationszDiscord bot tokenr   zDiscord token savedrv  z    To find your Discord user ID:z/   1. Enable Developer Mode in Discord settingsu'      2. Right-click your name → Copy IDzB   You can also use Discord usernames (resolved on gateway start).zLAllowed user IDs or usernames (comma-separated, leave empty for open access)uF   ⚠️  No allowlist set - anyone in servers with your bot can use it!rx  ry  uA      To get a channel ID: right-click a channel → Copy Channel IDz0   (requires Developer Mode in Discord settings)zH   You can also set this later by typing /set-home in a Discord channel.9Home channel ID (leave empty to set later with /set-home)DISCORD_HOME_CHANNEL)
rc   rZ   re   r   r   _clean_discord_user_idsrX   r   rf   r`   )r  r  cleaned_idsrD  r  s        r   _setup_discordr    s   011H 01113U;; 
	 !899 F]^^^ !94@@ Fklll$*+O$P$PM$ F&=m&L&L&'>@U@UVVV%&DEEEFLMMM&666E &...'(((	GGG=>>>1222@AAA8999	GGGSTTT	GGGV M  ]-m<<.0E0EFFF45555[\\\	GGGKLLL?@@@RSSSABBBYZZZUVVL =-|<<<<<= =r   rawc                    g }|                      dd                              d          D ]}|                                }|                    d          r=|                    d          r(|                    d                              d          }|                                                    d          r
|dd	         }|r|                    |           |S )
zGStrip common Discord mention prefixes from a comma-separated ID string.r   rJ   rz  z<@>z<@!zuser:r  N)	r|  r  r   rk  endswithlstriprstriprK   r   )r  cleaneduids      r   r  r    s    G{{3##))#..    iikk>>$ 	0CLL$5$5 	0**U##**3//C99;;!!'** 	abb'C 	 NN3Nr   c                     t          d           t          d          } | r?t          d           t          dd          s t          dd          rt	                       dS t          d	           t          d
           t          d           t          d           t          d           t          d           t          d           t                       t          d           t                       t	                       t                       t          dd          }|sdS t          d|           t          dd          }|rt          d|           t          d           t                       t          d           t          d           t                       t          d          }|r5t          d|	                    dd                     t          d           dS t          d           t          d           dS )z Configure Slack bot credentials.SlackSLACK_BOT_TOKENzSlack: already configuredzReconfigure Slack?FzcRegenerate the Slack app manifest with the latest command list? (recommended after `hermes update`)TNzSteps to create a Slack app:u9      1. Go to https://api.slack.com/apps → Create New AppuG         Pick 'From an app manifest' — we'll generate one for you below.u=      2. Enable Socket Mode: Settings → Socket Mode → EnableuB         • Create an App-Level Token with 'connections:write' scopeu4      3. Install to Workspace: Settings → Install AppzD   4. After installing, invite the bot to channels: /invite @YourBotzU   Full guide: https://hermes-agent.nousresearch.com/docs/user-guide/messaging/slack/zSlack Bot Token (xoxb-...)r   zSlack App Token (xapp-...)SLACK_APP_TOKENzSlack tokens savedrv  u\      To find a Member ID: click a user's name → View full profile → ⋮ → Copy member IDzTAllowed user IDs (comma-separated, leave empty to deny everyone except paired users)SLACK_ALLOWED_USERSr   rJ   zSlack allowlist configureduJ   ⚠️  No Slack allowlist set - unpaired users will be denied by default.zw   Set SLACK_ALLOW_ALL_USERS=true or GATEWAY_ALLOW_ALL_USERS=true only if you intentionally want open workspace access.)rc   rZ   re   r   "_write_slack_manifest_and_instructr`   r   rX   rf   r|  rg   )r  	bot_token	app_tokenr  s       r   _setup_slackr    s=   .//H .///1599 		 <  5
 3444F-...JKKKXYYYNOOOSTTTEFFFUVVV	GGGfggg	GGG
 '(((	GGG3dCCCI $i0003dCCCI 5()444&'''	GGG=>>>mnnn	GGG^ M  N,m.C.CC.L.LMMM233333bccc  M  	N  	N  	N  	N  	Nr   c                     	 ddl m}  ddlm}  | dd          }t	           |                      dz  }|j                            dd	           dd
l}|                    |	                    |dd          dz   d           t          d|            t          d           t          d           d
S # t          $ r,}t          d|            t          d           Y d
}~d
S d
}~ww xY w)u  Generate the Slack manifest, write it under HERMES_HOME, and print
    paste-into-Slack instructions.

    Exposed as its own helper so both the initial setup flow and the
    "reconfigure? → no" branch can refresh the manifest without the user
    re-entering tokens. Failures are non-fatal — if the manifest write
    fails for any reason, we print a warning and skip rather than abort
    the whole Slack setup.
    r   )_build_full_manifest)rS   HermeszYour Hermes agent on Slack)bot_namebot_descriptionzslack-manifest.jsonT)rT  exist_okNrx  F)indentensure_ascii
rJ  rK  zSlack app manifest written to: u      Paste it into https://api.slack.com/apps → your app → Features → App Manifest → Edit, then Save.  Slack will prompt to reinstall if scopes or slash commands changed.z\   Re-run `hermes slack manifest --write` anytime to refresh after Hermes adds new commands.zCouldn't write Slack manifest: zI   You can generate it manually later with: hermes slack manifest --write)hermes_cli.slack_clir  r  rS   r   rS  mkdirrV  
write_textdumpsrf   re   rn   rg   )r  rS   manifesttarget_jsonr  s         r   r  r    s   
======444444''8
 
 
 oo''((+@@D4888KKK??$F 	 	
 	
 	
 	@@@AAA=	
 	
 	

 	(	
 	
 	
 	
 	
  
 
 
===>>>,	
 	
 	
 	
 	
 	
 	
 	
 	

s   B3B7 7
C-!C((C-c            	         t          d           t          d          pt          d          } | r!t          d           t          dd          sdS t          d           t          d	           t          d
           t	                       t          d          }|r#t          d|                    d                     t	                       t          d           t          dd          }|rAt          d|           t          d          }|rt          d|           t          d           nSt          d          }|rt          d|           t          dd          }|rt          d|           t          d           |st          d          rIt	                       t          dd          }|rt          dd           t          d           |rdnd}	 t          d           n# t          $ r t          d| d           d dl}t          j        d!          }|r)|                    |d"d#d$t          j        |gdd%          }	n'|                    t          j        d&d"d#|gdd%          }	|	j        d k    rt          | d'           n[t%          d(| d)           |	j        rAt          d*|	j                                                                        d+                     Y nw xY wt	                       t          d,           t          d-           t	                       t          d.          }
|
r4t          d/|
                    d0d1                     t          d2           nt          d3           t	                       t          d4           t          d5           t          d6           t          d7          }|rt          d8|           dS dS dS )9zConfigure Matrix credentials.MatrixMATRIX_ACCESS_TOKENMATRIX_PASSWORDzMatrix: already configuredzReconfigure Matrix?FNzMWorks with any Matrix homeserver (Synapse, Conduit, Dendrite, or matrix.org).zC   1. Create a bot user on your homeserver, or use your own accountzE   2. Get an access token from Element, or provide user ID + passwordz0Homeserver URL (e.g. https://matrix.example.org)MATRIX_HOMESERVERr   zCAuth: provide an access token (recommended), or user ID + password.z-Access token (leave empty for password login)Tr   u9   User ID (@bot:server — optional, will be auto-detected)MATRIX_USER_IDzMatrix access token savedzUser ID (@bot:server)PasswordzMatrix credentials savedz$Enable end-to-end encryption (E2EE)?MATRIX_ENCRYPTIONr  zE2EE enabledzmautrix[encryption]mautrixzInstalling z...r   r  r  r  r  r  r  z
 installedu.   Install failed — run manually: pip install 'rZ  r   r   rv  z-   Matrix user IDs look like @username:serverrw  MATRIX_ALLOWED_USERSr   rJ   zMatrix allowlist configuredE   ⚠️  No allowlist set - anyone who can message the bot can use it!uI   📬 Home Room: where Hermes delivers cron job results and notifications.zE   Room IDs look like !abc123:server (shown in Element room settings)zD   You can also set this later by typing /set-home in a Matrix room.z6Home room ID (leave empty to set later with /set-home)MATRIX_HOME_ROOM)rc   rZ   re   r   r`   r   rX   r  rf   r  r  r  r  r  r  rk   r  r  rg   r  r   r  r|  )r  
homeserverrD  user_idrt   	want_e2ee
matrix_pkgr  r2  r3  r  	home_rooms               r   _setup_matrixr  0  sk   233W}EV7W7WH /0002E:: 	F^___TUUUVWWW	GGGJKKJ D*J,=,=c,B,BCCC	GGGTUUUBTRRRE 6,e444TUU 	6+W55512222011 	6+W555*t444 	6,h7774555 0:/00 0:!"H%PP	 	*.777.))).7F**Y
	Uy!!!! 	U 	U 	U4Z444555\$''F 	#UIz3>:V#'d (  
 $^T5)ZH#'d (    A%%7778888\z\\\]]]= US6=+>+>+@+@+K+K+M+Mb+QSSTTT'	U* 	ABBBBCCC`aa 	`1=3H3Hb3Q3QRRR78888^___^___Z[[[YZZZSTT	 	:-y99999a0: 0:^	: 	:s   G- -D K0/K0c                     t          d           t          d          } | r!t          d           t          dd          sdS t          d           t          d           t          d	           t	                       t          d
          }|r#t          d|                    d                     t          dd          }|sdS t          d|           t          d           t	                       t          d           t          d           t          d           t	                       t          d          }|r4t          d|	                    dd                     t          d           nt          d           t	                       t          d           t          d           t          d           t          d          }|rt          d|           t          d           dS ) z%Configure Mattermost bot credentials.
MattermostMATTERMOST_TOKENzMattermost: already configuredzReconfigure Mattermost?FNz/Works with any self-hosted Mattermost instance.uF      1. In Mattermost: Integrations → Bot Accounts → Add Bot Accountz   2. Copy the bot tokenz3Mattermost server URL (e.g. https://mm.example.com)MATTERMOST_URLr   z	Bot tokenTr   zMattermost token savedrv  u6      To find your user ID: click your avatar → Profilez'   or use the API: GET /api/v4/users/merw  MATTERMOST_ALLOWED_USERSr   rJ   zMattermost allowlist configuredr  uL   📬 Home Channel: where Hermes delivers cron job results and notifications.uH      To get a channel ID: click channel name → View Info → copy the IDzK   You can also set this later by typing /set-home in a Mattermost channel.r  MATTERMOST_HOME_CHANNEL2   Open config in your editor:  hermes config edit)
rc   rZ   re   r   r`   r   rX   r  rf   r|  )r  mm_urlrD  r  r  s        r   _setup_mattermostr    s    /00H 34446>> 	F@AAAWXXX)***	GGGIJJF ='s););<<<;...E %u---*+++	GGG=>>>GHHH8999	GGG\]]M \1=3H3Hb3Q3QRRR78888Z[[[	GGG]^^^YZZZ\]]]UVVL @0,???CDDDDDr   c                     t          d           t          d          } | r!t          d           t          dd          sdS t          d           t          d           t          d	           t          d
           t	                       t          d           t	                       t          d          }|st          d           dS t          d|                    d                     t          dd          }|st          d           dS t          d|           t          d           t	                       t          d           t          d           t	                       t          d          }|r4t          d|
                    dd                     t          d           nt          d           t	                       t          d           t          d           t          d          }|rt          d |           t	                       t          d!           t          d"d          rnt          d#          }|r]	 t          d$t          t          |                               t          d%|            n# t          $ r t          d&           Y nw xY wt	                       t          d'           t          d(           t          d)           dS )*z'Configure BlueBubbles iMessage gateway.zBlueBubbles (iMessage)BLUEBUBBLES_SERVER_URLzBlueBubbles: already configuredzReconfigure BlueBubbles?FNuC   Connects Hermes to iMessage via BlueBubbles — a free, open-sourcez1macOS server that bridges iMessage to any device.z4   Requires a Mac running BlueBubbles Server v1.0.0+z%   Download: https://bluebubbles.app/uN   In BlueBubbles Server → Settings → API, note your Server URL and Password.z6BlueBubbles server URL (e.g. http://192.168.1.10:1234)u5   Server URL is required — skipping BlueBubbles setupr   zBlueBubbles server passwordTr   u3   Password is required — skipping BlueBubbles setupBLUEBUBBLES_PASSWORDzBlueBubbles credentials savedu0   🔒 Security: Restrict who can message your botzJ   Use iMessage addresses: email (user@icloud.com) or phone (+15551234567)zIAllowed iMessage addresses (comma-separated, leave empty for open access)BLUEBUBBLES_ALLOWED_USERSr   rJ   z BlueBubbles allowlist configureduI   ⚠️  No allowlist set — anyone who can iMessage you can use the bot!uJ   📬 Home Channel: phone or email for cron job delivery and notifications.zD   You can also set this later with /set-home in your iMessage chat.z/Home channel address (leave empty to set later)BLUEBUBBLES_HOME_CHANNELz6Advanced settings (defaults are fine for most setups):z$Configure webhook listener settings?z%Webhook listener port (default: 8645)BLUEBUBBLES_WEBHOOK_PORTWebhook port set to z'Invalid port number, using default 8645zBRequires the BlueBubbles Private API helper for typing indicators,zGread receipts, and tapback reactions. Basic messaging works without it.zC   Install: https://docs.bluebubbles.app/helper-bundle/installation)rc   rZ   re   r   r`   r   rg   rX   r  rf   r|  r   r   r   )r  
server_urlrt   r  r  webhook_ports         r   _setup_bluebubblesr    s   )***566H 45557?? 	FTUUUBCCCEFFF6777	GGG_```	GGGPQQJ MNNN+Z->->s-C-CDDD3dCCCH KLLL)84441222	GGGABBB[\\\	GGGfggM `2M4I4I#r4R4RSSS89999^___	GGG[\\\UVVVKLLL A1<@@@	GGGGHHH;UCC IEFF 	II93s<?P?P;Q;QRRRC\CCDDDD I I IGHHHHHI 
GGGSTTTXYYYTUUUUUs   <J J$#J$c                  &    ddl m}   |              dS )z5Configure QQ Bot (Official API v2) via gateway setup.r   )_setup_qqbotN)hermes_cli.gatewayr  )_gateway_setup_qqbots    r   r  r    s)    GGGGGGr   c                  <   t          d           t          d          } | r!t          d           t          dd          sdS t	                       t          d           t          d           t          d	           t	                       t          d
           t	                       t          d          }|r]	 t          dt          t          |                               t          d|            n# t          $ r t          d           Y nw xY wt          dd          }|r t          d|           t          d           nt          d           t          dd           t	                       t          d           ddlm} t          d |             d           t          d           t          d           t	                       t          d           t          d           t	                       t          d           t          d           dS ) zConfigure webhook integration.WebhooksWEBHOOK_ENABLEDzWebhooks: already configuredzReconfigure webhooks?FNuD   ⚠  Webhook and SMS platforms require exposing gateway ports to thezE   internet. For security, run the gateway in a sandboxed environmentzB   (Docker, VM, etc.) to limit blast radius from prompt injection.zX   Full guide: https://hermes-agent.nousresearch.com/docs/user-guide/messaging/webhooks/zWebhook port (default 8644)WEBHOOK_PORTr  z'Invalid port number, using default 8644z-Global HMAC secret (shared across all routes)Tr   WEBHOOK_SECRETzWebhook secret saveduE   No secret set — you must configure per-route secrets in config.yamlr  zWebhooks enabled! Next steps:r   r   z   1. Define webhook routes in z/config.yamlz3   2. Point your service (GitHub, GitLab, etc.) at:z3      http://your-server:8644/webhooks/<route-name>z   Route configuration guide:z_   https://hermes-agent.nousresearch.com/docs/user-guide/messaging/webhooks/#configuring-routesr  )rc   rZ   re   r   r`   rg   r   rX   r   r   rf   r   r  r   )r  r=  secretr  s       r   _setup_webhooksr    sH   .//H 12224e<< 	F	GGGXYYYYZZZVWWW	GGGijjj	GGG/00D E	E>3s4yy>>:::7778888 	E 	E 	ECDDDDD	E CdSSSF _'000,----]^^^$f---	GGG1222<<<<<<EEEEFFFDEEEDEEE	GGG.///pqqq	GGGCDDDCDDDDDs   :<C7 7DDc           	      @  () ddl m}m)m} t	          d           t          d           t          d           t                        |            }g }g }t          |          D ]U\  }} )|          }|                    |d          d|d          d	| d
           |dk    r|                    |           Vt          d||          }	|	st          d           dS |	D ]}
 |||
                    dt          dt          fd(t          ()fd |            D                       }|rt                       t          d           t          d           g }t          d          r$t          d          s|                    d           t          d          r$t          d          s|                    d           t          d          r$t          d          s|                    d           t          d          r$t          d          s|                    d            t          d!          r3t          d"          s$t          d#          s|                    d$           |rt                       t          d%d&                    |                      t          d'           t          d(           t          d)           |D ]'}t          d*|                                 d+           (ddl}|                                d,k    }|                                d-k    }dd.l m}m}m}m}m}m}m}m}m}m}m}m}m }m!}  |            } |            } |            } | p|}!t                       | r" |            r |             t                       | r" |            r |             t                       |rtE          d/d0          r	 | r |             n|r
 |             n# |$ rP}"tG          d1           t          |"          $                                D ]}#t          d2|#            Y d}"~"nd}"~"wtJ          $ r}"tG          d3|"            Y d}"~"nd}"~"ww xY wn|rtE          d4d0          r	 | r |             n|r
 |             np# |$ rP}"tG          d5           t          |"          $                                D ]}#t          d2|#            Y d}"~"n d}"~"wtJ          $ r}"tG          d6|"            Y d}"~"nd}"~"ww xY wn|!re| rd7nd8}$tE          d9|$ d:d0          r	 d}%d;}&| r |d;<          \  }%}&n |d;<           d0}&t                       |&rtE          d=d0          r	 | r ||%d>k    ?           n|r
 |             n{# |$ rO}"tG          d5           t          |"          $                                D ]}#t          d2|#            Y d}"~"n,d}"~"wtJ          $ r}"tG          d6|"            Y d}"~"nd}"~"ww xY wn# tJ          $ r+}"tG          d@|"            t          dA           Y d}"~"nd}"~"ww xY wt          dB           | rt          dC           t          dD           nddEl&m'}'  |'            r[t          dF           t          dG           t          dH           t          dI           t          dJ           t          dK           nt          dF           t          dL           t          d           dS dS )Mz*Configure messaging platform integrations.r   )_all_platforms_platform_status_configure_platformMessaging PlatformszAConnect to messaging platforms to chat with Hermes from anywhere.z&Toggle with Space, confirm with Enter.emojir   r
  z  (r   
configuredzSelect platforms to configure:zENo platforms selected. Run 'hermes setup gateway' later to configure.Nstatusr   c                     |                                  }|dk    p)|                    d          p|                    d           S )Nnot configured	partiallyzplugin disabled)rK   rk  )r  ss     r   _is_progressz#setup_gateway.<locals>._is_progressI	  sK    LLNN!! /||K((/||-..
 	
r   c              3   @   K   | ]}  |                    V  d S Nr   )r   pr  r  s     r   r   z setup_gateway.<locals>.<genexpr>Q	  sJ        ./%%a(())     r   u   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━zMessaging platforms configured!rr  r{  rq  r  r  r  r  SLACK_HOME_CHANNELr  r  r  BlueBubbles	QQ_APP_IDQQBOT_HOME_CHANNELQQ_HOME_CHANNELQQBotzNo home channel set for: r   z7   Without a home channel, cron jobs and cross-platformz2   messages can't be delivered to those platforms.z1   Set one later with /set-home in your chat, or:z     hermes config set z_HOME_CHANNEL <channel_id>r  Darwin)_is_service_installed_is_service_runningsupports_systemd_serviceshas_conflicting_systemd_unitshas_legacy_hermes_units install_linux_gateway_from_setup$print_systemd_scope_conflict_warningprint_legacy_unit_warningsystemd_startsystemd_restartlaunchd_installlaunchd_startlaunchd_restartUserSystemdUnavailableErrorz)  Restart the gateway to pick up changes?Tu0     Restart failed — user systemd not reachable:r   z  Restart failed: z  Start the gateway service?u.     Start failed — user systemd not reachable:z  Start failed: systemdlaunchdz  Install the gateway as a z. service? (runs in background, starts on boot)F)forcez  Start the service now?r  )r  z  Install failed: z.  You can try manually: hermes gateway installz/  You can install later: hermes gateway installzA  Or as a boot-time service: sudo hermes gateway install --systemz'  Or run in foreground:  hermes gateway)is_containerz,Start the gateway to bring your bots online:z>   hermes gateway run          # Run as container main processrJ   z4For automatic restarts, use a Docker restart policy:z*   docker run --restart unless-stopped ...z/   docker restart <container>  # Manual restartz2   hermes gateway              # Run in foreground)(r  r  r  r  rc   re   r`   r   r   r   r   rl   anyrf   rZ   rg   r   upperr  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r   rd   r  rn   r  r  )*r   r  r  	platformsr   r   r   platr  r   r   any_messagingmissing_homer  	_is_linux	_is_macosr  r  r  r  r  r  r  r  r  r  r  r   r  r  service_installedservice_runningsupports_systemdsupports_service_managerr  linesvc_nameinstalled_scopedid_installr  r  r  s*                                           @@r   setup_gatewayr  (	  s:
   XXXXXXXXXX&'''RSSS7888	GGG  I ELY'' # #4!!$''WCCWCC&CCCDDD\!!""" @%VVH Z[[[ , ,IcN++++
S 
T 
 
 
 
      3A>3C3C    M  R:7888 -.. 	,}#8
 8
 	, 
+++,-- 	+m"7
 7
 	+ 	****++ 	)MBV4W4W 	)(((122 	/=Ic;d;d 	/...%% 	).//	)3@AR3S3S	) ((( 		GGGOdii6M6MOOPPPPQQQKLLLJKKK$  VdjjllVVV   
 	%$$$$$&&'1	$$&&(2		
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
" 2133--//4466#3#@y  	 = = ? ? 	00222GGG 	 7 7 9 9 	%%'''GGG H	QH$OO :
:' *'))))" *')))2 + + + RSSS #A 1 1 3 3 + +k4kk****+ + + + +  : : : 8Q 8 899999999::  ;	Q;TBB 8
8' (%" (%2 + + + PQQQ #A 1 1 3 3 + +k4kk****+ + + + +  8 8 8 61 6 67777777788 & .	Q$4Cyy)Hfhfff   FQ&*O"'K' +7W7W^c7d7d7d4'e4444&*GGG" @}5OQU'V'V @
@/ 0 -_5P Q Q Q Q Q!* 0 -: 3 3 3'(XYYY(+A(9(9(;(; 3 3 %k4kk 2 2 2 23 3 3 3 3( @ @ @'(>1(>(>????????@  Q Q Q 8Q 8 8999OPPPPPPPPQ LMMM# dbcccDEEEE555555|~~ 	QIJJJ[\\\2QRRRGHHHLMMMMIJJJOPPP:eR Rs   O0 0Q*5AQ  Q*Q%%Q*R T"AS--T:TT;AX  V  X  X%AW/*X /X<XX XX 
Y&!YYfirst_installc                 ,    ddl m}  |||            dS )u  Configure tools — delegates to the unified tools_command() in tools_config.py.

    Both `hermes setup tools` and `hermes tools` use the same flow:
    platform selection → toolset toggles → provider/API key configuration.

    Args:
        first_install: When True, uses the simplified first-install flow
            (no platform menu, prompts for all unconfigured API keys).
    r   )tools_command)r  r   N)hermes_cli.tools_configr  )r   r  r  s      r   setup_toolsr  	  s1     655555Mf======r   c                    	 ddl m}  |            rdS n# t          $ r Y nw xY w	 ddl m} n# t          $ r i }Y nw xY wdt          fd}t          | t                    r|                     d          nd}t          |t                    ro|                    d	          pd
                                	                                }||v r |||                   rdS |dk    rdD ]}t          |          r dS dD ]}t          |          r dS |                                D ]\  }}|dk    r ||          r dS dS )u  Return True when any known inference provider has usable credentials.

    Sources of truth:
      * ``PROVIDER_REGISTRY`` in ``hermes_cli.auth`` — lists every supported
        provider along with its ``api_key_env_vars``.
      * ``active_provider`` in the auth store — covers OAuth device-code /
        external-OAuth providers (Nous, Codex, Qwen, Gemini CLI, ...).
      * The legacy OpenRouter aggregator env vars, which route generic
        ``OPENAI_API_KEY`` / ``OPENROUTER_API_KEY`` values through OpenRouter.
    r   get_active_providerTr&   r   c                 L    | j         D ]}|dk    r	t          |          r dS dS )NCLAUDE_CODE_OAUTH_TOKENTF)api_key_env_varsrZ   )r,   env_vars     r   _has_keyz0_model_section_has_credentials.<locals>._has_key
  sF    / 	 	G 333W%% ttur   r   Nr   rJ   r%   )r   r   r;   F)r*   r  rn   r'   rl   r   r   r   r   rK   rZ   r   )	r   r  r'   r$  	model_cfgprovider_idr#  pidr,   s	            r   _model_section_has_credentialsr(  
  s   777777   	4	   5555555   T     (2&$'?'?I

7###TI)T""   }}Z006B==??EEGG+++x)+677 t,&&C     ))  44  <  !! 	44	 *//11  W )8G 	44	5s    
""- <<r
  c                 f    |                      dd          d                                         }|p| S )zFStrip trailing parenthetical qualifiers from a gateway platform label.(ry   r   )r  r   )r
  bases     r   _gateway_platform_short_labelr,  @
  s0    ;;sAq!''))D=5r   section_keyc                    |dk    rt          |           sdS |                     d          }t          |t                    r(|                                r|                                S t          |t
                    r9t          |                    d          p|                    d          pd          S dS |dk    rt          | ddd          }d	| S |d
k    rt          | d
dd          }d| S |dk    r7ddlm}m	 fd |            D             }|rd
                    |          S dS |dk    rg }t          d          r|                    d           t          d          r|                    d           t          d          r|                    d           |rd
                    |          S dS dS )a)  Return a short summary if a setup section is already configured, else None.

    Used after OpenClaw migration to detect which sections can be skipped.
    ``get_env_value`` is the module-level import from hermes_cli.config
    so that test patches on ``setup_mod.get_env_value`` take effect.
    r   Nr   r  r   r   r  r   z	backend: rH   rE  rD  zmax turns: gatewayr   )r  r  c                 n    g | ]1} |          r$ |          d k    t          |d                   2S )r  r
  )r,  )r   r
  r  s     r   r   z/_get_section_config_summary.<locals>.<listcomp>e
  s[     
 
 
%%
 +;*:4*@*@DT*T*T *$w-88*T*T*Tr   r   r   r   zTTS/ElevenLabsBROWSERBASE_API_KEYBrowserFIRECRAWL_API_KEY	Firecrawl)r(  r   r   r   r   r   rQ   r  r  r  r   rZ   r   )	r   r-  r   r   rE  r  r  r   r  s	           @r   _get_section_config_summaryr5  F
  s    g-f55 	4

7##eS!! 	!ekkmm 	!;;== eT"" 	Suyy++Quyy/A/AQ\RRR|	
	"	"&*iIII$7$$$			FG["EEE	(Y(((			!	!GGGGGGGG

 
 
 
&((
 
 


  	)99Z(((t			-.. 	+LL)***.// 	$LL###,-- 	&LL%%% 	$99U###t4r   c                     t          | |          }|sdS t                       t          d| d|            t          d|                                 dd           S )zShow an already-configured section summary and offer to skip.

    Returns True if the user chose to skip, False if the section should run.
    Fr   rx   z  Reconfigure ?r   )r5  r`   rf   r   rK   )r   r-  r
  summarys       r   _skip_configured_sectionr9  }
  sr     *&+>>G u	GGG)u))))***>ekkmm>>>NNNNNr   zoptional-skills	migrationzopenclaw-migrationscriptszopenclaw_to_hermes.pyc                     t                                           sdS t          j                            dt                     } | | j        dS t          j                            |           }ddl}||j        | j	        <   	 | j        
                    |           n/# t          $ r" |j                            | j	        d            w xY w|S )zLoad the openclaw_to_hermes migration script as a module.

    Returns the loaded module, or None if the script can't be loaded.
    Nopenclaw_to_hermesr   )_OPENCLAW_SCRIPTrU  r  r   spec_from_file_locationloadermodule_from_specrk   modulesr   exec_modulern   r  )specmod_syss      r   _load_openclaw_migration_modulerG  
  s    
 ""$$ t>11. D |t{*t
.
)
)$
/
/C !DL$$$$   D))) Js   ?B ,Cu\   ⚠ Gateway/messaging — this will configure Hermes to use your OpenClaw messaging channelsuE   ⚠ Telegram — this will point Hermes at your OpenClaw Telegram botuE   ⚠ Slack — this will point Hermes at your OpenClaw Slack workspaceuC   ⚠ Discord — this will point Hermes at your OpenClaw Discord botuL   ⚠ WhatsApp — this will point Hermes at your OpenClaw WhatsApp connectionuM   ⚠ Config values — OpenClaw settings may not map 1:1 to Hermes equivalentsuO   ⚠ Instruction file — may contain OpenClaw-specific setup/restart proceduresuJ   ⚠ Memory/context file — may reference OpenClaw-specific infrastructureu?   ⚠ Context file — may contain OpenClaw-specific instructions)	r/  telegramslackdiscordwhatsappr   soulmemorycontextreportc                 4   |                      dg           }|st          d           dS d |D             }d |D             }d |D             }t                      }|rEt          t	          dt
          j                             |D ]}|                     dd	          }|                     d
d          }|rXt          |                              t          t          j
                              d          }	t          d|dd|	            nt          d|            |                                }
t          |                                          }t                                          D ]"\  }}||
v s||v r|                    |           #t                       |r|t          t	          dt
          j                             |D ]D}|                     dd	          }|                     dd          }t          d|dd|            Et                       |r|t          t	          dt
          j                             |D ]D}|                     dd	          }|                     dd          }t          d|dd|            Et                       |rt          t	          dt
          j                             t#          |          D ],}t          t	          d| t
          j                             -t                       t          t	          dt
          j                             t          t	          dt
          j                             t          t	          dt
          j                             t                       dS dS )zPrint a detailed dry-run preview of what migration would do.

    Groups items by category and adds explicit warnings for high-impact
    changes like gateway token takeover and config value differences.
    r   zNothing to migrate.Nc                 D    g | ]}|                     d           dk    |S )r  migratedr   r   r   s     r   r   z,_print_migration_preview.<locals>.<listcomp>
  ,    HHHA!%%//Z*G*Ga*G*G*Gr   c                 D    g | ]}|                     d           dk    |S )r  conflictrS  rT  s     r   r   z,_print_migration_preview.<locals>.<listcomp>
  rU  r   c                 D    g | ]}|                     d           dk    |S )r  skippedrS  rT  s     r   r   z,_print_migration_preview.<locals>.<listcomp>
  s,    FFF1xI)E)EQ)E)E)Er   z  Would import:kindunknowndestinationrJ   ~r   z<22s    → z:  Would overwrite (conflicts with existing Hermes config):rp   zalready existsr   z  Would skip:u     ── Warnings ──z    zF  Note: OpenClaw config values may have different semantics in Hermes.uM     For example, OpenClaw's tool_call_execution: "auto" ≠ Hermes's yolo mode.zL  Instruction files (.md) from OpenClaw may contain incompatible procedures.)r   re   r   r`   r]   r\   r   r   r|  r   r  rK   _HIGH_IMPACT_KIND_KEYWORDSr   addr{   r   r   )rO  r   migrated_itemsconflict_itemsskipped_itemswarnings_shownitemrZ  dest
dest_short
kind_lower
dest_lowerkeywordwarningrp   s                  r   _print_migration_previewrl  
  s    JJw##E ()))HHHHHNHHHHHNFFFFFMUUN e%v|44555" 	0 	0D88FI..D88M2..D ' YY..s49;;/?/?EE
;t;;;z;;<<<<otoo&&& JT**J$>$D$D$F$F 0 0 j((Gz,A,A"&&w///0 	 ePRXR_``aaa" 	2 	2D88FI..DXXh(899F04000001111 eOVZ00111! 	2 	2D88FI..DXXh++F04000001111  e.>>???n-- 	: 	:G%(w((&-889999e\^d^kllmmmeegmgtuuvvvebdjdqrrsss r   r  c                 	   t          j                    dz  }|                                sdS t                                          sdS t                       t          d           t          d|            t          d           t                       t          dd          st          d	           dS t                      }|                                st          t                                 	 t                      }|t          d           dS nF# t          $ r9}t          d|            t                              dd           Y d
}~dS d
}~ww xY w	 |                    d
d
d          }|                    |                                |                                 dd
ddd
|d	  	        }|                                }nF# t          $ r9}t          d|            t                              dd           Y d
}~dS d
}~ww xY w|                    di           }|                    dd          }	|	dk    rt                       t          d           dS t                       t          d|	 d           t          d           t                       t-          |           t          dd          s t          d           t          d           dS 	 |                    |                                |                                 dd
ddd
|d	  	        }
|
                                }nF# t          $ r9}t          d|            t                              dd           Y d
}~dS d
}~ww xY w|                    di           }|                    dd          }|                    d d          }|                    d!d          }|                    d"d          }t                       |rt/          d#| d$           |rt          d%| d&           |rt          d%| d'           |rt          | d(           |                    d)          }|rt          d*|            t/          d+           dS ),a  Detect ~/.openclaw and offer to migrate during first-time setup.

    Runs a dry-run first to show the user exactly what would be imported,
    overwritten, or taken over. Only executes after explicit confirmation.

    Returns True if migration ran successfully, False otherwise.
    z	.openclawFzOpenClaw Installation DetectedzFound OpenClaw data at zDHermes can preview what would be imported before making any changes.z+Would you like to see what can be imported?Tr   zLSkipping migration. You can run it later with: hermes claw migrate --dry-runNz Could not load migration script.z!Could not load migration script: z$OpenClaw migration module load error)exc_infofull)preset)	source_roottarget_rootexecuteworkspace_target	overwritemigrate_secrets
output_dirselected_optionspreset_namezMigration preview failed: z OpenClaw migration preview errorr8  rR  r   z Nothing to import from OpenClaw.u   Migration Preview — z item(s) would be importedz5No changes have been made yet. Review the list below:zProceed with migration?zCMigration cancelled. You can run it later with: hermes claw migratezIUse --dry-run to preview again, or --preset minimal for a lighter import.zMigration failed: zOpenClaw migration errorrY  rW  errorz	Imported z item(s) from OpenClaw.zSkipped zU item(s) that already exist in Hermes (use hermes claw migrate --overwrite to force).z" item(s) (not found or unchanged).u3    item(s) had errors — check the migration report.rw  zFull report saved to: z,Migration complete! Continuing with setup...)r   r  is_dirr>  rU  r`   rc   re   r   rT   rW   rV   rG  rg   rn   r  r  resolve_selected_optionsMigratorrQ  migrater   rl  rf   )r  openclaw_dirconfig_pathrE  r  r   dry_migratorpreview_reportpreview_summarypreview_countmigratorrO  r8  rR  rY  	conflictserrorsrw  s                     r   _offer_openclaw_migrationr    s4    9;;,L   u""$$ u	GGG1222777888UVVV	GGGFPTUUU Z	
 	
 	
 u "##K #KMM"""-//;<===5     =!==>>>;dKKKuuuuu//d6/JJ||$,,..#++--! % $ 

 

 &--//   61667777$GGGuuuuu %((B77O#''
A66M5666u	GGGS-SSSTTTFGGG	GGG^,,, 2EBBB Q	
 	
 	
 	W	
 	
 	
 u<<$,,..#++--! %   

 

 !!##   .1..////$???uuuuu jjB''G{{:q))Hkk)Q''GJ**I[[!$$F	GGG EC(CCCDDD @~i~~~ KIgIIIJJJ VTTTUUUL))J :8J88999@AAA4sJ   4D 
E .EEA.G 
H.H

H"AL9 9
M<.M77M<r   Model & Providerr   zText-to-Speechr   r  r/  zMessaging Platforms (Gateway)r   ToolsrH   rV  c                 |   ddl m}m}  |            r |d           dS t                       t	          t          | dd                    }|r5t          t          j        t                               t          d           t	          t          | dd                    }t	          t          | d	d                    }t                      }t                      }t          | d
d          }|st                      sd}|rt          d           dS t          | dd          }	|	r!t          D ]\  }
}}|
|	k    rt!                       t!          t#          dt$          j                             t!          t#          d|ddt$          j                             t!          t#          dt$          j                              ||           t          |           t!                       t          | d            dS t)          d|	            t+          dd                    d t          D                                   dS ddlm}  |            }t	          t3          d                    pt	          t3          d                    p|du}t!                       t!          t#          dt$          j                             t!          t#          dt$          j                             t!          t#          dt$          j                             t!          t#          dt$          j                             t!          t#          dt$          j                             t!          t#          dt$          j                             d}|r|rt5          ||           dS t!                       t7          d           t          d            t+          d!           t+          d"           t+          d#           t+          d$           t+          d%           nzt!                       |s|rt+          d&           t!                       t9          |          }|rt                      }t;          d'd(d)gd          }|dk    rt=          |||           dS t7          d*           t+          d+t?                                  t+          d,tA                                  t+          d-|            t+          d.tB                      t!                       t+          d/           |r;t!                       t+          d0           t+          d1           t+          d2           |rtE          |d3d4          stG          |           |rtE          |d5d6          stI          |           |rtE          |d7d8          stK          |           |rtE          |d9d:          stM          |           |rtE          |d;d<          stO          || =           t          |           tQ          ||           tS                       dS )>u  Run the interactive setup wizard.

    Supports full, quick, and section-specific setup:
      hermes setup           — full or quick (auto-detected)
      hermes setup model     — just model/provider
      hermes setup tts       — just text-to-speech
      hermes setup terminal  — just terminal backend
      hermes setup gateway   — just messaging platforms
      hermes setup tools     — just tool configuration
      hermes setup agent     — just agent settings
    r   )
is_managedmanaged_errorzrun setup wizardNresetFz Configuration reset to defaults.reconfigurer`  non_interactiveTz;Running in a non-interactive environment (no TTY detected).sectionr   u   │     ⚕ Hermes Setup — z<34su    │r   z configuration complete!zUnknown setup section: zAvailable sections: r   c              3   "   K   | ]
\  }}}|V  d S r  r   )r   kr   s      r   r   z#run_setup_wizard.<locals>.<genexpr>  s(      3T3T'!QA3T3T3T3T3T3Tr   r  r   OPENAI_BASE_URLu@   │             ⚕ Hermes Agent Setup Wizard                │u   ├─────────────────────────────────────────────────────────┤u>   │  Let's configure your Hermes Agent installation.       │u>   │  Press Ctrl+C at any time to exit.                     │Reconfigurez#You already have Hermes configured.uA   Running the full wizard — each prompt shows your current value.z9Press Enter to keep it, or type a new value to change it.rJ   zBTip: jump straight to a section with 'hermes setup model|terminal|zC     gateway|tools|agent', or fill only missing items with --quick.u=   No existing configuration found — running first-time setup.z$How would you like to set up Hermes?u9   Quick setup — provider, model & messaging (recommended)u#   Full setup — configure everythingzConfiguration LocationzConfig file:  zSecrets file: zData folder:  zInstall dir:  z=You can edit these files directly or use 'hermes config edit'z%Settings were imported from OpenClaw.uG   Each section below will show what was imported — press Enter to keep,z#or choose to reconfigure if needed.r   r  r   r  rH   rV  r/  r  r   r  )r  )*r  r  r  r[   rl   rj   rW   copydeepcopyrR   rf   rV   rS   ro   rr   SETUP_SECTIONSr`   r]   r\   MAGENTArd   re   r   r*   r  rZ   _run_quick_setuprc   r  r   _run_first_time_quick_setuprT   rU   PROJECT_ROOTr9  r  rB  ro  r  r  r  _offer_launch_chat)argsr  r  reset_requestedreconfigure_requestedquick_requestedr   r  r  r  rN  r
  funcr  active_provideris_existingmigration_ran
setup_modes                     r   run_setup_wizardr    s    <;;;;;;;z|| ()))74%8899O :DM.112228999 }e!D!DEE74%8899O]]F!##K d$5u==O #7#9#9  +I	
 	
 	
 	 dIt,,G  . 	 	Cg~~ L    eLELLLLfn]]^^^ L    VF###@@@AAA' * 	7g77888V$))3T3T^3T3T3T*T*TVVWWW 433333))++O]/0011 	'/0011	'$&  
GGG	 @N	
 	
   
NPVP^	
 	
  
 
 @N	
 	
   
Lfn	
 	
  
 
Lfn	
 	
  
 
 @N	
 	
   M +  	V[111F]###;<<<VWWWNOOO2WXXXXYYYY 	 ! 	O 	VWWWGGG 2+>> 	# ]]F"#IG1L
  

 ??'[IIIF )***3 1 133444000111---......///	GGGNOOO ::;;;\]]]8999  %6vwHZ[[ %V$$$  '6vzK]^^ 'v&&&  %6vwHXYY %V$$$  6vyJ_`` f  ;6vwPP ;Fk/:::: ---r   c                  j    t                       t          dd          sdS ddlm}   | dg           dS )z7Prompt the user to jump straight into chat after setup.zLaunch hermes chat now?TNr   relaunchchat)r`   r   hermes_cli.relaunchr  r  s    r   r  r  d  sM    	GGG2D99 ,,,,,,HfXr   r  c                 8   t          | d           t          |            |                     di                               dd           t          |            t	                       t          dddgd	          }|d	k    rt          |            t          |            t	                       t          d
           t	                       t          d           |d	k    rt          d           t	                       t          | |           t                       dS )u   Streamlined first-time setup: provider + model only.

    Applies sensible defaults for TTS (Edge), terminal (local), agent
    settings, and tools — the user can customize later via
    ``hermes setup <section>``.
    Tr_  r   r   r  z7Connect a messaging platform? (Telegram, Discord, etc.)z"Set up messaging now (recommended)u1   Skip — set up later with 'hermes setup gateway'r   z#Setup complete! You're ready to go.z)  Configure all settings:    hermes setupz1  Connect Telegram/Discord:  hermes setup gatewayN)r  rT  r&  rW   r`   r   r  rf   re   r  r  )r   r  r  gateway_choices       r   r  r  n  s&    t,,,, "&)))
j"%%00GDDD 
GGG"A0?	
 	
 N fF	GGG7888	GGG:;;;FGGG	GGG---r   c           
         ddl m}m}m} t	                       t          d           d  |d          D             }d  |d          D             } |            } |            \  }}	|p	|p|p||	k     }
|
s=t          d           t	                       t          d	           t          d
           dS |rt	                       t          t          |           d           |D ]}t	          d|d                     t	                       |D ]N}t	                       t	          t          d|d          t          j                             t          d|                    dd                      |                    d          rt          d|d                     |                    d          r/t          d|                    d|d                    d          }n,t          d|                    d|d                              }|r0t          |d         |           t          d|d                     6t          d|d                     Pd |D             }d |D             }|rt	                       t          d           g }|D ]o}|                    dg           }|r dd                    |dd                     nd}|                    |                    d|d                    |            pt%          d!|          }|D ]}||         }t'          |           |rJt	                       t          d"           t          d#           t          d$           g }i }|D ]b}|d         }d%|v rd&}nd'|v rd(}nd)|v rd*}n ||vr|                    |           |                    |g                               |           cd+ |D             }t%          d,|          }|D ]}||         }||         }d-d.d/d0                    |d          }t	                       t	          t          d1| d2| d3t          j                             t	                       |D ]}t          d|                    dd                      |                    d          rt          d|d                     |                    d          r/t          d|                    d|d                    d          }n,t          d|                    d|d                              }|r&t          |d         |           t          d4           nt          d5           t	                       |rht	                       t          d6t          |           d7           |D ]#}t          d8|d9          d:|d;                     $|	| d<<   t+          |            t-          | |           dS )=u6   Quick setup — only configure items that are missing.r   )get_missing_env_varsget_missing_config_fieldscheck_config_versionu"   Quick Setup — Missing Items Onlyc                 <    g | ]}|                     d           |S is_requiredrS  r   vs     r   r   z$_run_quick_setup.<locals>.<listcomp>  s9       m@T@T	  r   F)required_onlyc                 <    g | ]}|                     d           |S r  rS  r  s     r   r   z$_run_quick_setup.<locals>.<listcomp>  s9       AEE-DXDX	  r   z(Everything is configured! Nothing to do.z:Run 'hermes setup' and choose 'Full Setup' to reconfigure,z)or pick a specific section from the menu.Nz required setting(s) missing:u	        • r   r   r   rJ   r   z  Get key at: rt   r   Tr   z  Saved z
  Skipped c                 D    g | ]}|                     d           dk    |S )categorytoolrS  r  s     r   r   z$_run_quick_setup.<locals>.<listcomp>  s.    PPP1AEE*4E4E4O4OQ4O4O4Or   c                 n    g | ]2}|                     d           dk    |                     d          0|3S )r  	messagingadvancedrS  r  s     r   r   z$_run_quick_setup.<locals>.<listcomp>  sJ       55++AEE*4E4E+ 	
+++r   zTool API Keysr   r^  r   rx  z(Which tools would you like to configure?r  z7Connect Hermes to messaging apps to chat from anywhere.z:You can configure these later with 'hermes setup gateway'.TELEGRAMrq  DISCORDr  SLACKr  c                 B    g | ]}d ddd                     ||          S )u   📱 Telegramu   💬 Discordu
   💼 Slackrq  r  r  rS  )r   r  s     r   r   z$_run_quick_setup.<locals>.<listcomp>  sI     
 
 
 	 ,)%  c!Qii
 
 
r   z)Which platforms would you like to set up?u   📱u   💬u   💼r  r   r   r   r   z	  SkippedzAdding z& new config option(s) with defaults...z  Added rN  z = r   _config_version)r  r  r  r  r`   rc   rf   re   r   r]   r\   ra   r   r   rX   rg   r   r   r   r   r&  rW   r  )r   r  r  r  r  missing_requiredmissing_optionalmissing_configcurrent_ver
latest_verhas_anything_missingr   r   missing_toolsmissing_messagingchecklist_labelsr   r   selected_indicesr   platform_orderr	  r   r
  platform_labels	vars_listr  fields                               r   r  r    s}             
GGG5666 ''e<<<   ''e<<<   /.00N2244K 	 	$	$	$ #	    @AAAOPPP>???  :c*++JJJKKK# 	- 	-C+c&k++,,,,# 	: 	:CGGG%*S[**FK889998CGGM26688999wwu~~ :8CJ88999wwz"" FDCGGHc&k$B$BDDtTTTDCGGHc&k$B$BDDEE :s6{E2226V66777783v;889999 QP 0PPPM !    !_%%%  	Y 	YCGGGR((E:?G6		%) 4 4666RI##sww}c&k'J'J$WI$W$WXXXX+6
 

 $ 	! 	!C$CC      9*+++LMMMOPPP 	$ 	7 	7Cv;DT!!!d"" D9$$%%d+++  r**11#6666
 
 $
 
 
 ,7
 

 $ 	 	C!#&D!$I!'FVLLPPQUWYZZEGGG%?u??t???MMNNNGGG   <r : :<<===775>> 20CJ0011177:&& J"#H#f+(F(F#H#HSWXXXEE"#H#f+(F(F#H#HIIE /"3v;666!-0000!+...   
Qc.))QQQ	
 	
 	
 $ 	J 	JEHU5\HHeI6FHHIIII %/ !F -----r   r  )NF)r   N)T)F)o__doc__r   r  rV  loggingr  r  rk   r  pathlibr   typingr   r   r   hermes_cli.nous_subscriptionr   r  r   utilsr	   r  r
   	getLogger__name__r  __file__rS  rQ  r  r  r   r   r   r"   rl   r-   _DEFAULT_PROVIDER_MODELSrM   rP   r  rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   hermes_cli.colorsr\   r]   rc   hermes_cli.cli_outputrd   re   rf   rg   ro   rr   r   listr   r   r   r   r   r   r   r  r1  rG  r?  r  r  r  r  r  r  rB  rT  ro  r  r  r  r  r  r  r  r  r  r  r  r  r(  r,  r5  r9  r>  rG  r_  rl  r  r  r  r  r  r  r   r   r   <module>r     sm
          				  



        & & & & & & & & & & G G G G G G A A A A A A # # # # # # 4 4 4 4 4 4		8	$	$tH~~$+33559
tCH~ $sCx.    DDcN DtCH~ D D D D
6$sCx. 6C 6SV 6[_ 6 6 6 6
A 
A 
A 
A 
A 
A" 	      GFFZZZ]]] "78PPPMMMPPPwww _  _  _}}}       G( ( Vd38n     +$sCx. +# +$ + + + +                          , + + + + + + +; ; ; ; ;           d     d
 d    & S 3  #    *m mC m$ m mWZ]aWa mmp m m m m( (C ($ ( (sUYz (eh ( ( ( (V/ /C /$ /$ / / / /0 C  D D    :I I I I I8K K K K K\' ' ' ' 'TB/D B/ B/ B/ B/J t tCH~    J 9> X$ X$ X$ X$ X$ X$ X$ X$@W$ W W W W
/d / / / /d    2DU DU DU DU DUN d        kB4 kB kB kB kBfA$ A A A A:i i i i ibDB DB DBN3= 3= 3=l     7N 7N 7Nt(
 (
 (
VS: S: S:l)E )E )EX>V >V >VB  ,E ,E ,E^~$ ~ ~ ~ ~L> > >T > > > >(;4 ;D ; ; ; ;|     4 43 48C= 4 4 4 4nOO"O+.O	O O O O* L+<<==  	   @ nWTT^]]ZP
 
 =T = = = =@B4 BD B B B BT  "67
i(#%;</?g{# 45H H HV  ) ) ) ) ) )Xc.T c. c. c. c. c. c.r   