
    #j                       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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d(l=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ZA ejB        d1          ZCd2edefd3ZDdd-ed4eEd.eFd5edz  deFf
d6ZGdd-ed4eEd.eFd5edz  deFf
d7ZHdd-ed.e#de#fd9ZIdd%ed:eEd;eEdeEfd<ZJd=eKfd>ZLd
eKfd?ZMd
eKfd@ZNd,dAd
eKdBe#fdCZOde#fdDZPde#fdEZQde#fdFZRde#fdGZSde#fdHZTd
eKfdIZUd
eKfdJZVd
eKfdKZWd
eKfdLZXd
eKfdMZY ejB        dN          ZZdOede#fdPZ[dQ Z\dedz  fdRZ]dedz  fdSZ^dT Z_dU Z`dV ZadW ZbdX ZcdY ZddZ Zed
eKfd[Zfdd
eKd\e#fd]Zgd
eKde#fd^Zhd_edefd`Zid
eKdaedee         fdbZjd
eKdaed_ede#fdcZk eeddz            dez  dfz  dgz  dhz  Zldi Zmdjdkdldmdndodpdqdrds	ZndteKfduZodve
de#fdwZpdxdyeOfdzd{eVfd|d}eWfd~deffddegfddeYfgZqd
eKddfdZrd Zsd
eKde#fdZtd
eKfdZud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-codexzgpt-4.1zgpt-4ozgpt-4o-minizclaude-opus-4.6zclaude-sonnet-4.6zclaude-sonnet-4.5zclaude-haiku-4.5zgemini-2.5-pro)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)zanthropic/claude-opus-4.6zanthropic/claude-sonnet-4.6zopenai/gpt-5.4zgoogle/gemini-3-pro-previewzgoogle/gemini-3-flash-preview)r/   r0   zclaude-sonnet-4-6zgemini-3-flashr2   r4   minimax-m2.7)r3   r4   r1   r2   zmimo-v2.5-proz	mimo-v2.5zmimo-v2-prozmimo-v2-omnir5   zminimax-m2.5zqwen3.7-maxz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zaizkimi-codingzkimi-coding-cnstepfunarceeminimaxz
minimax-cn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_effortrD   r   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 )Nr?   r@   r   )r   rE   rC   s      r   _set_reasoning_effortrG   y   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)printrT   rS   CYANBOLD)rU   s    r   print_headerrZ      s5    	GGG	%uV[
9
9:::::r   )print_error
print_infoprint_successprint_warning)masked_secret_promptc                      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)ra   s    r   is_interactive_stdinrg      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)rW   rT   rS   rX   rY   r\   )rh   s    r   #print_noninteractive_setup_guidancerj      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}	 |r(t          t          |t          j                            }n't	          t          |t          j                            }t          |          }|                                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. []: : rA      N)r_   rT   rS   YELLOWinput_sanitize_pasted_inputr   KeyboardInterruptEOFErrorrW   rc   exit)rk   r   rl   displayvaluecleaneds         r   promptr{      s     "-----///
 	9(w)F)FGGEE%7788E(//}}/'/R/x(   s   A7B
 
3C Cz\x1b\[\s*200~|\x1b\[\s*201~ry   c                 j    t          | t                    r| s| S t                              d|           S )z@Strip terminal bracketed-paste control markers from pasted text.rA   )r   r   _BRACKETED_PASTE_PATTERNsub)ry   s    r   rt   rt      s6    eS!!  #''E222r   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   )rk   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 (rq   z)  Ctrl+C to exitTz  Select [1-z] (z): z$Please enter a number between 1 and zPlease enter a number)r   r\   rW   rT   rS   rr   	enumerateGREENrs   lenDIMintr[   
ValueErrorru   rv   rc   rw   )	rk   r   r   r   idxichoicemarkerry   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/NTrn   ro   rq   >   yyes>   nnoFzPlease enter 'y' or 'n')rs   rT   rS   rr   r   rB   ru   rv   rW   rc   rw   r[   )rk   r   default_strry   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 curses is
    unavailable.

    Returns:
        List of selected indices (not including the Continue option).
    Nr   )curses_checklist)r   )r   r   setsorted)rU   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: rl   r   r{   Trl        ✓ Savedz/  Skipped (configure later with 'hermes setup'))r   joinr   rW   rT   rS   rX   r\   r{   rO   r]   r^   )r   r   	tools_strry   s       r   _prompt_api_keyr   H  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#           |j        j	        r|                    d$           n	 ddlm} dd lm}  |             d} |            D ]0}	 |                                r	|j        } n!# t
          $ r Y -w xY wn# t
          $ r d}Y nw xY w|r|                    d%| dddf           t/          | d&d'd()          }|j        j	        r|                    d*           n|d+k    r&t          d,          r|                    d-           n|d.k    r5t          d/          st          d0          r|                    d1           ny|d2k    r&t          d3          r|                    d4           nM|d5k    r&t          d6          r|                    d7           n!|d8k    r4t          d9          st          d:          r|                    d;           n|d<k    rc	 t2          j                            d<          du}n# t
          $ r d}Y nw xY w|r|                    d=           n|                    d>           n~|d?k    rc	 t2          j                            d?          du}n# t
          $ r d}Y nw xY w|r|                    d@           n+|                    dA           n|                    dB           |j        j	        r|                    dC           nwt/          | dDdE          dFk    r8|j        j        r|                    dG           n@|                    dH           n*t=                      r|j        r|                    dI           t          dJ          r|                    dK           	 ddLl m!}  |dM          pi }|"                    dN          s|"                    dO          r|                    dP           n# t
          $ r Y nw xY wt          dQ          r|                    dR           n|                    dS           |                    dT           |                    dU           |                    dV           tG          dW |D                       }tI          |          }tK          | dX| dY           t                       |D ]\  }}}|r.t          dZtM          d[tN          j(                   d\|            6t          dZtM          d]tN          j)                   d\| d\tM          d^| dtN          j*                              t                       d_ |D             }|r>tW          d`           ddal,m-} tW          db |             dc           t                       t                       t          tM          ddtN          j(                             t          tM          detN          j(                             t          tM          dftN          j(                             t                       ddal,m-} t          tM          dg |             dhtN          j.        tN          j/                             t                       t          dZtM          ditN          j0                   djtc                                  t          dZtM          dktN          j0                   djte                                  t          dZtM          dltN          j0                   dm| dn           t                       t          tM          dotN          j*                             t                       t          tM          dptN          j.        tN          j/                             t                       t          dZtM          dqtN          j(                   dr           t          dZtM          dstN          j(                   dt           t          dZtM          dutN          j(                   dv           t          dZtM          dwtN          j(                   dx           t          dZtM          dytN          j(                   dz           t                       t          dZtM          d{tN          j(                   d|           t          dZtM          d}tN          j(                   d~           t          dZtM          dtN          j(                              t          d           t                       t          d           t          dZtM          dtc                       tN          j*                              t          dZtM          dte                       tN          j*                              t                       t          tM          dotN          j*                             t                       t          tM          dtN          j.        tN          j/                             t                       t          dZtM          dtN          j(                   d           t          dZtM          dtN          j(                   d           t          dZtM          dtN          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   FzbEXA_API_KEY, PARALLEL_API_KEY, FIRECRAWL_API_KEY/FIRECRAWL_API_URL, TAVILY_API_KEY, or SEARXNG_URL)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 browserzAnpm install -g agent-browser && agent-browser install --with-depsF)z$Image Generation (Nous subscription)TN)Image GenerationTN)list_providers)_ensure_plugins_discoveredfalzImage Generation ()r   FzFAL_KEY or OPENAI_API_KEY)z,Video Generation (FAL via Nous subscription)TNzVideo Generation (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)TNr;   MINIMAX_API_KEY)zText-to-Speech (MiniMax)TNmistralMISTRAL_API_KEY)z Text-to-Speech (Mistral Voxtral)TNr7   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
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 )rq   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)3rW   rZ   r   agent.auxiliary_clientr   rf   appendrQ   webmanaged_by_nous	availablecurrent_providerbrowser	image_genagent.image_gen_registryr   hermes_cli.pluginsr   r   is_availabledisplay_name	video_genagent.video_gen_registryrH   r   	importlibutil	find_specr   direct_overrider   nous_auth_presentr*   r   r   sumr   r\   rT   rS   r   REDr   r^   hermes_constantsr   rX   rY   rr   rK   rL   )r   hermes_hometool_statussubscription_featuresr   _vision_backendslabelbrowser_providermissing_browser_hint_img_backendr   r   _p_list_video_providers_ensure_plugins_video_backend_vptts_provider	neutts_okkittentts_okr   _spotify_stateavailable_counttotal_countr   r   missing_vardisabled_tools_dhhs                                r   _print_setup_summaryr  d  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 bSTTTT		"	, b& $5 	[Z-B-F-WZZZEE4.////  a  	b  	b  	b -4E$4 
PQQQQ		&	0 
$ 	?>+;>>>EE4.////w},,= !  ..J !  **#0  00S ! 	!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
 &6 UWXXXX	"XXXXXXXXXXXXO!N,,..  '')) ),)9 !   H 	" 	" 	"!NNN	" 	U F^ F F FdSTTT 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 ][\\\ \"" 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 $L. ?LL. 
L*'L. )L**L. .L=<L=!R6 6SS=!T T.-T.2AZ 
ZZ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)>   1r   r   truecontainer_cpurq   z  CPU corescontainer_memoryi   z  Memory in MB (5120 = 5GB)container_diski   z  Disk in MB (51200 = 50GB)N)

setdefaultrW   r\   r   r{   rB   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_resourcesr)    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)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          }t%          |t&                    r|                    d          } ||            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   )rM   rN   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: *You can try again later with: hermes modelNr   r   )hermes_cli.configrM   rN   rZ   r\   
_DOCS_BASErW   hermes_cli.mainr-  
SystemExitru   rf   loggerdebugr^   clearupdater   r   r   )	r   r*  rM   rN   r-  exc
_refreshedselected_provider_ms	            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
LLNNN
MM* 	G		B"d /FF:.. Ks   
A .C	C<CC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_ngrA    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)chocorF  r=  -y)sudoaptrF  rI  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piprF  -Uzneutts[all]--quiet,  rG  timeoutzneutts installed successfullyzFailed to install neutts: z2Try manually: python -m pip install -U neutts[all])
subprocessrc   rA  rW   r^   platformr\   r   runr]   CalledProcessErrorFileNotFoundError
executableTimeoutExpiredr[   )rS  rc   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)...rL  rM  rF  rN  	soundfilerO  TrP  rQ  z kittentts installed successfullyzFailed to install kittentts: z(Try manually: python -m pip install -U 'z' soundfileF)
rS  rc   rW   r\   rU  rX  r]   rV  rY  r[   )rS  rc   	wheel_urlrZ  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dl m}  t           |                                 d                    S # t          $ r Y dS w xY w)zTrue iff xAI Grok OAuth credentials are already stored locally.

    Lets TTS / STT setup skip the API-key prompt for users who logged in
    through ``hermes model`` -> xAI Grok OAuth (SuperGrok / Premium+).
    r   get_xai_oauth_auth_status	logged_inF)r*   rb  rd   r   rf   ra  s    r   _xai_oauth_logged_in_for_setuprd  D  sa    ======--//33K@@AAA   uus   /2 
A A c                     	 ddl m} m}m}m}m} n*# t          $ r}t          d|            Y d}~dS d}~ww xY w |             }t                       t          d           	  ||          } ||d         |
                    d	          |
                    d
d          |
                    d                      |d|
                    d|                      dS # t          $ r}t          d|            Y d}~dS d}~ww xY w)zRun the xAI Grok OAuth loopback login from inside the setup wizard.

    Returns True on success, False on any failure (the caller falls back
    to whatever the user picked next, e.g. Edge TTS).
    r   )DEFAULT_XAI_OAUTH_BASE_URL_is_remote_session_save_xai_oauth_tokens_update_config_for_provider_xai_oauth_loopback_loginz$xAI Grok OAuth helpers unavailable: NFz6Signing in to xAI Grok OAuth (SuperGrok / Premium+)...)open_browsertokens	discoveryredirect_urirA   last_refresh)rm  rn  ro  z	xai-oauthbase_urlTzxAI Grok OAuth login failed: )r*   rf  rg  rh  ri  rj  rf   r^   rW   r\   r   )rf  rg  rh  ri  rj  r7  rk  credss           r   _run_xai_oauth_login_from_setuprr  R  s   
	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
    BSBBCCCuuuuu *)+++L	GGGGHHH))|DDD(Oii,,>266>22		
 	
 	
 	
 	$#:/IJJ	
 	
 	
 t   ;c;;<<<uuuuus)    
838$A;C! !
D+DD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	 t          j                            d          du}n# t           $ r d}Y nw xY w|rt#          d           nJt                       t	          d            t	          d!           t	          d"           t                       t%          d#d$          r!t'                      st          d%           d}
nt	          d&           d}
n|
d'k    rft          d(          }|sSt                       t)          d)d$*          }|r!t+          d(|           t#          d+           ndt          d,           d}
nQ|
dk    rw|sut          d          pt          d          }|sSt                       t)          d-d$*          }|r!t+          d|           t#          d.           nt          d,           d}
n|
d/k    rt-                      }t          d0          }|rt#          d1           n|rt#          d2           nt                       t          d3g d4d56          }|d5k    r0t/                      rt#          d7           nt          d8           d}
nn|dk    rWt)          d9d$*          }|r t+          d0|           t#          d:           n5d5d;lm} t          d< |             d=           d}
nt          d>           d}
|
d/k    rt                       t)          d?          }|rw|                                rc|                                |                     di                               d/i           d@<   t#          dA|                                            n(|
dBk    rft          dC          }|sSt                       t)          dDd$*          }|r!t+          dC|           t#          dE           nt          d,           d}
n|
dFk    rft          dG          }|sSt                       t)          dHd$*          }|r!t+          dG|           t#          dI           nct          d,           d}
nP|
dJk    rt          dK          pt          dL          }|sat                       t	          dM           t)          dNd$*          }|r t+          dK|           t#          dO           nt          d,           d}
n|
dPk    r	 t          j                            dP          du}n# t           $ r d}Y nw xY w|rt#          dQ           n{t                       t	          dR           t	          dS           t                       t%          dTd$          r t9                      st          dU           d}
nt	          dV           d}
d| vri | d<   |
| d         d<   t;          |            t#          dW|                     |
|
                      dS )Xz@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   xair;   r   r7   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)u0   xAI TTS (Grok voices — OAuth login or 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   rq   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 savedrw  XAI_API_KEYzGxAI TTS will use your xAI Grok OAuth (SuperGrok / Premium+) credentialsz*xAI TTS will use your existing XAI_API_KEYz(How do you want xAI TTS to authenticate?)uD   Sign in with xAI Grok OAuth (SuperGrok / Premium+) — browser loginz#Paste an xAI API key (console.x.ai)u   Skip → fallback to Edge TTSr   )r   r   u6   Logged in — xAI TTS will use these OAuth credentialsz@xAI Grok OAuth login did not complete. Falling back to Edge TTS.zxAI API key for TTSzxAI TTS API key savedr   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 TTS skipped. 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: r;   r   zMiniMax API key for TTSzMiniMax TTS API key savedr   r   zMistral API key for TTSzMistral TTS API key savedr7   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   rW   rZ   r\   r   r   r   extendr   r   rQ   r^   r   r   r   rf   r]   r   r[  r{   rO   rd  rr  r   r   r   r  r_  rN   )r   
tts_configr   r  provider_labelscurrent_labelr   	providerskeep_current_idxr   r   selected_via_nousalready_installedexistingr(   oauth_logged_inexisting_api_key
choice_idxr  rz  s                       r   _setup_tts_providerr  x  s	   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		
 9::(77 ,	"     '	"FGGGGGGG&:  
   J Q244 	&!P    "4    &HHq !6FFF 
&"=':::!"9::::LLLLLL!459TVV4 4 4  
  &HHJKKK!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9!Z Z*)Z*c                 $    t          |            dS )z.Standalone TTS setup (for 'hermes setup tts').N)r  r   s    r   	setup_ttsr  d  s    r   c           	      f   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}|r$|                    d           d||<   ||d<   |dz  }|}|                    d| d           |||<   t          d||          }	|	                    |	          }
|	|k    rt          d|            dS |
| 
                    di           d	<   |
d
k    rZt          d           t          d            | d         
                    d!t          t          j                                         n*|
dk    rtt          d"           t          j        d          }|st#          d#           t          d$           nt          d%|            | d         
                    d&d'           n|
dk    rt          d(           t          j        d)          pt          j        d          }|st#          d*           t          d+           nt          d,|            | d         
                    d-d.           n"|
dk    rt          d/           t          d0           dd1lm} dd2lm} t-          t/                      ot1          |           j        o
 |d                    } |t          | dd3                    }d4}|r@d5d6g}|d7k    rd}n|d8k    rd}nt5          d9          rdnd}t          d:||          }|dk    }|rId7| d         d3<   t          d;           t5          d9          st5          d<          rt          d=           nd8| d         d3<   t          d>           	 t7          d           n# t8          $ r t          d?           ddl}t          j        d@          }|r)|                    |dAdBdCt>          j         dgdDdDE          }n'|                    t>          j         dFdAdBdgdDdDE          }|j!        dk    rt          dG           nt#          dH           Y nw xY wt	                       t          dI           t          dJ           t5          d9          }|rgt          dK           tE          dLd4          rFtG          dMdDN          }tG          dOdDN          }|rtI          d9|           |rtI          d<|           ntG          dMdDN          }tG          dOdDN          }|rtI          d9|           |rtI          d<|           nD|
dk    r	t          dP           t          dQ           t          dR           t          dS           	 t7          d           n# t8          $ r t          dT           ddl}t          j        d@          }|r)|                    |dAdBdCt>          j         dgdDdDE          }n'|                    t>          j         dFdAdBdgdDdDE          }|j!        dk    rt          dU           nWt#          dV           |j%        rAt          dW|j%        &                                '                                dX                     Y nw xY wt	                       t5          dY          }|rRt          dZ           tE          d[d4          r2tG          d\dDN          }|rtI          dY|           t          d]           n2tG          d\dDN          }|rtI          dY|           t          d^           | d         
                    d_d'           n4|
dk    r-t          d`           t          da           t5          db          pdc}tG          dd|          }|rtI          db|           t5          de          pdc}tG          df|ptQ          j)        dgdc                    } | rtI          de|            t5          dh          pdi}!tG          dj|!          }"|"r|"dik    rtI          dh|"           t5          dk          pdc}#t          t          j                    dlz  dmz            }$tG          dn|#p|$          }%|%rtI          dk|%           |rtE          dodD          rt          dp           ddl}g dq}&|%r|&*                    dr|%g           |"r|"dik    r|&*                    ds|"g           |&                    | r|  dt| n|           |&                    du           |                    |&dDdDdvw          }|j!        dk    rt          dx           n8t#          dy|j%        &                                            t          dz           tI          d{|
           |
dk    r*tI          d|| d         	                    d3d}                     tW          |            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.r,  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 environmentdockerr   sshdaytona)r   rq      r      rq   r  r   r  )r  r  r   r  r     z.Singularity/Apptainer - HPC-friendly containersingularityrx  r   zSelect terminal backend:zKeeping current backend: zTerminal backend: Localz&Commands run directly on this machine.cwdz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'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Terminal backend: Modalz@Serverless cloud sandboxes. Each session gets its own container.)is_managed_tool_gateway_ready)normalize_modal_mode
modal_modeFz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...uvrM  rF  --pythonTcapture_outputtextrL  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 IDr   z    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Terminal backend: SSHz)Run commands on a remote machine via SSH.TERMINAL_SSH_HOSTrA   z  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  rR  z  SSH connection successful!z  SSH connection failed: z'  Check your SSH key and host settings.TERMINAL_ENVTERMINAL_MODAL_MODEautozTerminal backend set to: ),rT  rZ   r\   r0  rW   rH   systemr   r   r   r  r]   r   r   homer?  r@  r^   tools.managed_tool_gatewayr  tools.tool_backend_helpersr  rd   r   r   r   rQ   
__import__ImportErrorrS  rU  rc   rX  
returncoder   r{   rO   stderrr   
splitlinesosgetenvr{  rN   )'r   	_platformcurrent_backendis_linuxterminal_choicesidx_to_backendbackend_to_idxnext_idxr  terminal_idxselected_backend
docker_binsing_binr  r  managed_modal_availabler  use_managed_modalmodal_choicesdefault_modal_idxmodal_mode_idxrS  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_backendr  n  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	RRN A!PQRRN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;<<< 	z%%eS-=-=>>>>	X	%	%0111 \(++
 	65666LMMMM4
44555 	z%%H	
 	
 	
 	
 
]	*	*?@@@ <,,K]0K0K 	-DEEER    +++,,, 	z%%A	
 	
 	
 	

 
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	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':::./// 	z%%I	
 	
 	
 	
 
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[[[	GGG@.>@@AAAAAs&   O B-RRW C5[
	[
c                    d|                      di           d<   t          d           d|                      di           d<   d|                      d	i           d
<   d| d	         d<   d|                      di           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.   r?   	max_turnsHERMES_MAX_ITERATIONSallrx   tool_progressTcompressionenabled      ?	thresholdnonesession_resetmodezApplied recommended defaults:z  Max iterations: 150z  Tool progress: allz  Compression threshold: 0.50z2  Session reset: never (use /reset or compression)z.  Run `hermes setup agent` later to customize.N)r  rP   rN   r]   r\   r  s    r   _apply_default_agent_settingsr    s    25Fgr"";/
 ,---8=Fi$$_56:FmR((3)-F=+&
 6<For**621222&'''%&&&.///CDDD?@@@@@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 Settingsr,  z/user-guide/configurationr?   r  Z   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   Nr  zMax iterations set to z%Invalid number, keeping current valuerA   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 logsrx   r  r  zTool progress mode>   r  newoff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.Tr  r  r  r  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 settingsr  r  bothidle_minutesi  at_hourr  rq   r  r   )r  idledailyr  z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.)rZ   r\   r0  rW   r   rH   r{   r   r  poprP   r]   r   r^   rB   rN   r  r   r   )r   current_maxmax_iter_strmax_itercurrent_moder  current_thresholdthreshold_strr  reset_choicescurrent_policycurrent_idlecurrent_hourdefault_reset	reset_idxidle_stridle_valhour_strhour_vals                      r   setup_agent_settingsr    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;z^\d+:[A-Za-z0-9_-]{30,}$tokenc                 P    t          t                              |                     S N)rd   _TELEGRAM_BOT_TOKEN_REmatchr  s    r   _is_valid_telegram_bot_tokenr  m  s    &,,U33444r   c                     	 ddl m}  n# t          $ r Y dS w xY wd}	 t          t	                                }d|v r/|                    d                              dd          d         }n# t          $ r Y nw xY w | |          S )	zBAttempt automatic Telegram bot creation via managed QR onboarding.r   )auto_setup_telegram_bot_resultNz
/profiles/r   rq   r   )profile_name)hermes_cli.telegram_managed_botr  r  r   rJ   rstriprsplitrf   )r  r  r   s      r   _setup_telegram_auto_resultr  q  s    RRRRRRR   tt  $L/++,,;&&&--c2299#qAA"EL    *)|DDDDs   	 
AA, ,
A98A9c                  4    t                      } | r| j        ndS )zBAttempt automatic Telegram bot creation and return only the token.N)r  r  )r  s    r   _setup_telegram_autor    s    (**F!+6<<t+r   c                      t          d           	 t          dd          } | sd S t          |           st          d           5| S )Nz'Create a bot via @BotFather on TelegramTzTelegram bot tokenr   znInvalid token format. Expected: <numeric_id>:<alphanumeric_hash> (e.g., 123456789:ABCdefGHI-jklMNOpqrSTUvwxYZ))r\   r{   r  r[   r  s    r   _prompt_telegram_bot_tokenr     sh    8999
+d;;; 	4+E22 	@   r   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           t                       t          d           t          d           t          d           t                       t          d           t          d           t                       t	          dd          }d}d}|	                                dk    rit                      }|r*|j        }t          |          st          d           d}d}nd}|s+t                       t          d           t                       |st                      }|sdS t          d|           t          d           t                       t          d           t          d           t          d           t          d           t                       t          |d d          }|rt!          |          }t          d!|            t          d"d	          rot	          d#          }|g}|                    dd                              d$          D ]}	|	r|	|vr|                    |	           d$                    |          }nt	          d%          }nt	          d%          }|r6|                    dd          }t          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	          d0          }|rt          d.|           dS dS t          d1           t	          d2          }|rt          d.|           dS dS )3z1Configure 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!zAdd allowed users now?Tz6   To find your Telegram user ID: message @userinfobotz"Allowed user IDs (comma-separated)r   rA   zTelegram allowlist configuredNz/How would you like to create your Telegram bot?z  [1] Automatic (recommended)u6         Scan a QR code → confirm in Telegram → done.z!      No token copy-paste needed.z  [2] Manualz?      Create a bot via @BotFather yourself and paste the token.zChoice [1/2]r  r   z7Automatic setup returned an invalid Telegram bot token.zFalling back to manual setup...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)owner_user_idz Detected your Telegram user ID: z+Allow this Telegram account to use the bot?z7Additional allowed user IDs (comma-separated, optional),?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).r   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))rZ   rQ   r\   r   r{   rO   replacer]   rW   r   r  r  r  r[   r   rb   r   splitr   r   )r  allowed_usersr   r  setup_resultdetected_user_iddetected_idextraidsuidfirst_user_idhome_channels               r   _setup_telegramr7    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@AAA	GGG.///GHHH2333	GGG~PQQQ	GGGNC000FEL||~~244 	 &E/66 $UVVV#E 	GGG8999GGG -*,, '///()))	GGG=>>>23337888KLLL	GGG|_dCC 
*++FFFGGGFMM 
	TUUE-C}}S"--33C88 $ $ $3c>>JJsOOOHHSMMMM"Q MM M
 
  W%--c266/???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          } | 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          }|r4t          d|	                    dd                     t          d           nt          d           t          d           t                       t          d           t          d            t          d!           t          d"           t          d#           t          d$          }|r$t          d%|                                           dS 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 savedr%  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   rA   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.r)  r*  zC   To get a channel ID: open the channel in Slack, then right-clickuN      the channel name → Copy link — the ID starts with C (e.g. C01ABC2DE3F).zF   You can also set this later by typing /set-home in a Slack channel.z9Home channel ID (leave empty to set later with /set-home)SLACK_HOME_CHANNEL)rZ   rQ   r\   r   "_write_slack_manifest_and_instructrW   r{   rO   r]   r,  r^   r   )r  	bot_token	app_tokenr.  r6  s        r   _setup_slackrA    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bccc  M  	N  	N  	N	GGGKLLL?@@@TUUU_```WXXXUVVL C+\-?-?-A-ABBBBBC C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)rJ   HermeszYour Hermes agent on Slack)bot_namebot_descriptionzslack-manifest.jsonT)parentsexist_okNr  F)indentensure_ascii
zutf-8)encodingz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_clirC  r   rJ   r   parentmkdirjson
write_textdumpsr]   r\   rf   r^   )rC  rJ   manifesttarget_jsonr7  s         r   r>  r>  J  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          rt	                       t          dd          }|rt          dd           t          d           |rdnd}	 ddl	m
}m}  |d           }	|	r|t          d!| d"t          |	           d#           	  |d d$           t          | d%           n8# t          $ r+}
t          d&           t          d'|
            Y d}
~
nd}
~
ww xY wn)# t          $ r 	 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/| d0           |j        rAt          d'|j                                                                        d1                     Y nw xY wY nw xY wt	                       t          d2           t          d3           t	                       t          d4          }|r4t          d5|                    d6d7                     t          d8           nt          d9           t	                       t          d:           t          d;           t          d<           t          d=          }|rt          d>|           dS dS dS )?z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]mautrixr   )ensurefeature_missingzplatform.matrixzInstalling z (+ z runtime deps)...)r{   z
 installeduk   Install failed — run manually: pip install 'mautrix[encryption]' asyncpg aiosqlite Markdown aiohttp-socksr  z...r  rM  rF  r  r  rL  u.   Install failed — run manually: pip install 'z*' asyncpg aiosqlite Markdown aiohttp-socksr   r%  z-   Matrix user IDs look like @username:serverr(  MATRIX_ALLOWED_USERSr   rA   zMatrix allowlist configureduE   ⚠️  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)rZ   rQ   r\   r   rW   r{   rO   r  r]   tools.lazy_depsr_  r`  r   rf   r^   r  r  rS  r?  r@  rU  rc   rX  r  r  r   r  r,  )r  
homeserverr  user_idrl   	want_e2ee
matrix_pkg_lazy_ensurer`  _missing_beforer7  rS  r  r  r.  	home_rooms                   r   _setup_matrixrk  u  s   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 N:/00 N:!"H%PP	 	*.777.))).7F**Y
-	YOOOOOOOO-o.?@@O 2Y*YY#o2F2FYYY  	2 L!25AAAA!Z";";";<<<<  2 2 2!)  
 0300111111112  	Y 	Y 	YY9%%%% Y Y Y8888999!!!!d++ 	'^^	:s~zZ'+$ ,  FF
 (^^uiL'+$ ,  F $))!Z";";";<<<<!S&S S S   } Y"#Wv}/B/B/D/D/O/O/Q/QRT/U#W#WXXX-Y	Y< 	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9]N: N:Z	: 	:sa   8I/ H5 4I/ 5
I*?!I% I/ %I**I/ /N;J
ND NNNNN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   rA   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)rZ   rQ   r\   r   rW   r{   r^   rO   r  r]   r,  r   r   r   )r  
server_urlrl   r.  r6  webhook_ports         r   _setup_bluebubblesru    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.gatewayrw  )_gateway_setup_qqbots    r   rw  rw  *  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_PORTrr  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-routesz2   Open config in your editor:  hermes config edit)rZ   rQ   r\   r   rW   r^   r{   rO   r   r   r]   r   r   r   )r  r  secretr  s       r   _setup_webhooksr  0  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                       }|r+t                       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.k    }dd/l m}m}m}m}m}m}m}m}m}m}m}m}m }m!}m"}m#} m$}!  |            }" |            }# |            }$|$p|p|}%t                       |$r" |            r |             t                       |$r" |            r |             t                       |#r|$r |             r |!d0           nJtK          d1d2          r	 |$r |             n)|r |             n|rdd3l&m'}& |&(                                 n# |$ rP}'tS          d4           t          |'          *                                D ]}(t          d5|(            Y d}'~'nd}'~'w|$ r(}'tS          d6|'             |!d0           Y d}'~'nd}'~'wtV          $ r}'tS          d6|'            Y d}'~'nad}'~'ww xY wnW|"r|$r |             r |!d7           n;tK          d8d2          r	 |$r |             n)|r |             n|rdd3l&m'}& |&,                                 n# |$ rP}'tS          d9           t          |'          *                                D ]}(t          d5|(            Y d}'~'nd}'~'w|$ r(}'tS          d:|'             |!d7           Y d}'~'nwd}'~'wtV          $ r}'tS          d:|'            Y d}'~'nRd}'~'ww xY wnH|%r|$rd;})n|rd<})nd=})tK          d>|) d?d2          rk	 d}*d@}+d@},|$r |d@A          \  }*}+n1|r |d@A           d2}+n dd3l&m'}& |&-                    d@A           d2}+d2},t                       |+r|,stK          dBd2          r	 |$r ||*dCk    D           n|r
 |             n# |$ rO}'tS          d9           t          |'          *                                D ]}(t          d5|(            Y d}'~'nVd}'~'w|$ r'}'tS          d:|'             |!d7           Y d}'~'n,d}'~'wtV          $ r}'tS          d:|'            Y d}'~'nd}'~'ww xY wn# tV          $ r+}'tS          dE|'            t          dF           Y d}'~'nd}'~'ww xY wt          dG           |$rt          dH           t          dI           nddJl.m/}-  |-            r[t          dK           t          dL           t          dM           t          dN           t          dO           t          dP           nt          dK           t          dQ           t          d           dS dS )Rz*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)rB   
startswith)r  ss     r   _is_progressz#setup_gateway.<locals>._is_progress  sK    LLNN!! /||K((/||-..
 	
r   c              3   @   K   | ]}  |                    V  d S r  r   )r   pr  r  s     r   r   z setup_gateway.<locals>.<genexpr>  sJ        ./%%a(())     r   u   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━zMessaging platforms configured!r#  r+  r"  DISCORD_BOT_TOKENDISCORD_HOME_CHANNELDiscordr:  r=  r9  rm  rp  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Windows)_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UserSystemdUnavailableErrorSystemScopeRequiresRootError$_system_scope_wizard_would_need_root_print_system_scope_remediationrestartz)  Restart the gateway to pick up changes?T)gateway_windowsu0     Restart failed — user systemd not reachable:r   z  Restart failed: startz  Start the gateway service?u.     Start failed — user systemd not reachable:z  Start failed: systemdlaunchdzScheduled Taskz  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 processrA   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)0rx  r  r  r  rZ   r\   rW   r   r   r   r   rd   anyr]   rQ   r^   r   upperrT  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   
hermes_clir  r  r[   r  rf   r  rF  r   r  )0r   r  r  	platformsr   r   r   platr  r   r   any_messagingmissing_homer  	_is_linux	_is_macos_is_windowsr  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  service_installedservice_runningsupports_systemdsupports_service_managerr  rZ  linesvc_nameinstalled_scopedid_installstarted_inliner  r  r  s0                                                 @@r   setup_gatewayr  _  sy   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  |: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	&&((I5	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
( 2133--//4466#3#Oy#OK  	 = = ? ? 	00222GGG 	 7 7 9 9 	%%'''GGG n	Q :$H$H$J$J ://	::::JDQQ ::' 2'))))" 2'))))$ 2>>>>>>'//1112 + + + RSSS #A 1 1 3 3 + +k4kk****+ + + + +3 ? ? ?
   8Q 8 899933I>>>>>>>>  : : : 8Q 8 899999999:):,  U	Q 8$H$H$J$J 8//8888=tDD 88' 0%" 0%$ 0>>>>>>'--///2 + + + PQQQ #A 1 1 3 3 + +k4kk****+ + + + +3 = = = 61 6 677733G<<<<<<<<  8 8 8 61 6 6777777778!8$ & @	Q ,$ ,$+fhfff  -F$Q&*O"'K%*N' .7W7W^c7d7d7d4" .'e4444&* ?>>>>>'//e/<<<&*)-GGG" @> @mLfhl>m>m @@/ 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; E E E'(>1(>(>???;;GDDDDDDDD( @ @ @'(>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:y| |s   6Q S,ARS,SS,S''S,6U W;AV&&W;.WW;W66W;%A+] Z1 0] 1]6A\ ;]  ]\*%] *]7]	] ]] 
^!!^^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  O	  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_varsrQ   )r,   env_vars     r   _has_keyz0_model_section_has_credentials.<locals>._has_keyz	  sF    / 	 	G 333W%% ttur   r   Nr   rA   r%   )r   r   r6   F)r*   r  rf   r'   rd   r   r   r   r   rB   rQ   r   )	r   r  r'   r  	model_cfgprovider_idr  pidr,   s	            r   _model_section_has_credentialsr  c	  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.(rq   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: r?   r  r  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>	  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   rH   rx  r  r  r   rQ   r   )	r   r  r   r   r  r  r  r   r  s	           @r   _get_section_config_summaryr  	  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   rp   z  Reconfigure ?r   )r  rW   r]   r   rB   )r   r  r  summarys       r   _skip_configured_sectionr  	  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_SCRIPTexistsr   r   spec_from_file_locationloadermodule_from_specrc   modulesr   exec_modulerf   r  )specmod_syss      r   _load_openclaw_migration_moduler  	  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>2
  ,    HHHA!%%//Z*G*Ga*G*G*Gr   c                 D    g | ]}|                     d           dk    |S )r  conflictr  r  s     r   r   z,_print_migration_preview.<locals>.<listcomp>3
  r  r   c                 D    g | ]}|                     d           dk    |S )r  skippedr  r  s     r   r   z,_print_migration_preview.<locals>.<listcomp>4
  s,    FFF1xI)E)EQ)E)E)Er   z  Would import:kindunknowndestinationrA   ~r   z<22s    → z:  Would overwrite (conflicts with existing Hermes config):rh   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   r\   r   rW   rT   rS   r   r   r,  r   r  rB   _HIGH_IMPACT_KIND_KEYWORDSr   addrr   r   r   )r  r   migrated_itemsconflict_itemsskipped_itemswarnings_shownitemr
  dest
dest_short
kind_lower
dest_lowerkeywordwarningrh   s                  r   _print_migration_previewr  '
  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 errorr  r  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 errorr	  r  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.r'  zFull report saved to: z,Migration complete! Continuing with setup...)r   r  is_dirr  r  rW   rZ   r\   r   rK   rN   rM   r  r^   rf   r3  r4  resolve_selected_optionsMigratorresolvemigrater   r  r]   )r   openclaw_dirconfig_pathr  rZ  r   dry_migratorpreview_reportpreview_summarypreview_countmigratorr  r  r  r	  	conflictserrorsr'  s                     r   _offer_openclaw_migrationr9  g
  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   Toolsr?   r  c                    ddl m} t                       t          t          dt          j                             t          t          dt          j                             t          t          dt          j                             t                       t          d           t          d           t          d           t                       t          d	           t                       	 dd
lm}  ||            n# t          t          t          f$ r0 t                       t          d           t          d           Y dS t          $ rU}t                              d|           t                       t          d|            t          d           Y d}~dS d}~ww xY w	  |            }t!          |t"                    r)|                                  |                     |           n# t          $ r Y nw xY wt                       t)          d           t          d           t          d           dS )u  One-shot Nous Portal setup — OAuth + model pick + provider + Tool Gateway.

    Wired into ``hermes setup --portal`` and ``hermes portal``. This is the
    Nous-Portal slice of the first-time quick setup, collapsed into a single
    shareable command so a brand-new user goes from zero to a fully working
    Hermes session — model selected, provider set, and web/image/tts/browser
    tools routed via their Portal sub — without being told to run
    ``hermes setup`` and hunt for the quick-setup option.

    The login + model selection + provider switch + Tool Gateway opt-in are all
    delegated to ``_model_flow_nous`` — the exact same flow quick setup uses
    (``_run_first_time_quick_setup``) and the same one ``hermes model`` runs
    when you pick Nous. Routing through it (instead of hand-rolling the auth +
    provider write here) means ``hermes portal`` always offers a model picker,
    and there is a single source of truth for the Nous onboarding steps.
    r   rM   r   uC   │     ⚕ Hermes Setup — Nous Portal (one-shot)             │r   z7  One subscription, 300+ models, plus the Tool Gateway:z9    web search, image generation, TTS, browser automationu0       — all routed through your Nous Portal sub.z>  Sign up: https://portal.nousresearch.com/manage-subscription_model_flow_nousz  Setup cancelled.z+  You can retry later with `hermes portal`.Nz1_model_flow_nous error during `hermes portal`: %sz*  Nous Portal setup encountered an error: zPortal setup complete.z.  Run `hermes portal info` to inspect routing.z!  Run `hermes` to start chatting.)r/  rM   rW   rT   rS   MAGENTAr\   r1  r?  ru   rv   r2  rf   r3  r4  r[   r   r   r5  r6  r]   )r   rM   r?  r7  r8  s        r   _run_portal_one_shotrA  
  so   " .-----	GGG	 @N	
 	
   
%UW]We
f
fggg	 @N	
 	
   
GGGHIIIJKKKABBB	GGGOPPP	GGG444444    x4 	 	 	 	'(((@AAA   H#NNNFFFGGG@AAA []]
j$'' 	&LLNNNMM*%%%    
GGG*+++?@@@233333s3   1D AF'		F'A
F""F'+AG4 4
H Hc                 T   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                      }|                                rldd
lm}	 |                    d|	                                                    d                     }
	 ddl} |j        ||
           n# t*          $ r d}
Y nw xY wd}
t          | dd          }|st-                      sd}|rt/          d           dS t	          t          | dd                    rt1          |           dS t          | dd          }|r!t2          D ]\  }}}||k    rt5                       t5          t7          dt8          j                             t5          t7          d|ddt8          j                             t5          t7          dt8          j                              ||           t          |           t5                       t          | d            dS t=          d|            t?          dd                     d t2          D                                   dS ddl!m"}  |            }t	          tG          d                    pt	          tG          d                    p|du}t5                       t5          t7          dt8          j                             t5          t7          dt8          j                             t5          t7          d t8          j                             t5          t7          d!t8          j                             t5          t7          d"t8          j                             t5          t7          dt8          j                             d}|r|rtI          ||           dS t5                       tK          d#           t          d$           t?          d%           t?          d&           t?          d'           t?          d(           t?          d)           nzt5                       |s|rt?          d*           t5                       tM          |          }|rt                      }tO          d+d,d-gd          }|dk    rtQ          |||           dS tK          d.           t?          d/t                                  t?          d0tS                                  t?          d1|            t?          d2tT                      t5                       t?          d3           |r;t5                       t?          d4           t?          d5           t?          d6           |rtW          |d7d8          stY          |           |rtW          |d9d:          st[          |           |st]          |           |rtW          |d;d<          st_          |           |rtW          |d=d>          sta          || ?           t          |           |
rJ|
                                r6t?          d@|
            t?          dA           t?          dB|
 dC|            tc          ||           dS )Du  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*  )datetimez
.yaml.bak.z%Y%m%d_%H%M%Snon_interactiveTz;Running in a non-interactive environment (no TTY detected).portal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.rA   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?uX   Quick Setup (Nous Portal) — free OAuth login, no API keys, model + tools (recommended)uU   Full setup — configure every provider, tool & option yourself (bring your own keys)z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  r  r  r   r;  )r  zPrevious config backed up to: z9If setup changed a value you customized, restore it with:z  cp r   )2r/  rC  rD  rR   rd   rb   rN   copydeepcopyrI   r]   rM   rJ   rK   r  rG  with_suffixnowstrftimer?  copy2rf   rg   rj   rA  SETUP_SECTIONSrW   rT   rS   r@  r[   r\   r   r*   r  rQ   _run_quick_setuprZ   r9  r   _run_first_time_quick_setuprL   PROJECT_ROOTr  r;  r  r  r  r  r  )argsrC  rD  reset_requestedreconfigure_requestedquick_requestedr   r   r1  _dt_backup_pathr?  rH  rJ  keyr  funcr  active_provideris_existingmigration_ran
setup_modes                         r   run_setup_wizardre  N  s6    <;;;;;;;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 "##K ,,,,,,"..>++O<<>>
 
	 MMMFLl3333 	  	  	 LLL	   d$5u==O #7#9#9  +I	
 	
 	
 	 GD(E**++ V$$$ 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"2jg 
 

 ??'[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&&&
  .%f---  6vyJ_`` f  ;6vwPP ;Fk/::::  9++-- 9BLBBCCCNOOO7<77+77888-----s   E E&%E&rb  c                    ddl m} t                       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 |            }|                                  |                     |           t          |            t!          |            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+          | |           dS )u  Streamlined first-time setup via Nous Portal: OAuth, model, terminal & messaging.

    Routes straight to the Nous Portal provider — runs the device-code OAuth
    login, picks a Nous model, then configures the terminal backend and (optionally)
    a messaging platform. Applies sensible defaults for everything else (agent
    settings, tools); the user can customize later via ``hermes setup <section>``
    or switch providers with ``hermes model``.
    r   r=  zNous Portalz5One subscription, 300+ models, plus the Tool Gateway:z8  web search, image generation, TTS, browser automation.z<Sign up: https://portal.nousresearch.com/manage-subscriptionr>  zNous Portal setup cancelled.z-_model_flow_nous error during quick setup: %sz(Nous Portal setup encountered an error: r.  Nz7Connect a messaging platform? (Telegram, Discord, etc.)z"Set up messaging now (recommended)u1   Skip — set up later with 'hermes setup gateway'z#Setup complete! You're ready to go.z)  Configure all settings:    hermes setupz1  Connect Telegram/Discord:  hermes setup gateway)r/  rM   rW   rZ   r\   r1  r?  ru   rv   rf   r3  r4  r^   r5  r6  r  r  rN   r   r  r]   r  )r   r   rb  rM   r?  r7  r8  gateway_choices           r   rW  rW  5  sL    .----- 
GGGFGGGIJJJMNNN	GGG	A444444    x( 3 3 3122222 A A ADcJJJFFFGGG?@@@@@@@@A J
LLNNN
MM* 6""" "&))) 
GGG"A0?	
 	
 N fF	GGG7888	GGG:;;;FGGG	GGG-----s    A2 2.C1"	C1+<C,,C1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_requiredr  r   vs     r   r   z$_run_quick_setup.<locals>.<listcomp>  s9       m@T@T	  r   F)required_onlyc                 <    g | ]}|                     d           |S rm  r  ro  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   rA   r   z  Get key at: rl   r{   Tr   z  Saved z
  Skipped c                 D    g | ]}|                     d           dk    |S )categorytoolr  ro  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 )rt  	messagingadvancedr  ro  s     r   r   z$_run_quick_setup.<locals>.<listcomp>  sJ       55++AEE*4E4E+ 	
+++r   zTool API Keysr   r  r   r  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'.TELEGRAMr"  DISCORDr  SLACKr9  c                 B    g | ]}d ddd                     ||          S )u   📱 Telegramu   💬 Discordu
   💼 Slackr"  r  r9  r  )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 r_  z = r   _config_version)r/  ri  rj  rk  rW   rZ   r]   r\   r   rT   rS   rX   r   r{   rO   r^   r   r   r   r   r  rN   r  )r   r   ri  rj  rk  missing_requiredmissing_optionalmissing_configcurrent_ver
latest_verhas_anything_missingr   ry   missing_toolsmissing_messagingchecklist_labelsr   r   selected_indicesr   platform_orderr  r   r  platform_labels	vars_listr  fields                               r   rV  rV  ~  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)v__doc__importlib.utilr   loggingr  rer?  rc   rO  pathlibr   typingr   r   r   hermes_cli.nous_subscriptionr   r  r   utilsr	   r   r
   	getLogger__name__r3  __file__rN  r.  rX  r0  r   r   r   r"   rd   r-   _DEFAULT_PROVIDER_MODELSrD   rG   r/  rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   hermes_cli.colorsrS   rT   rZ   hermes_cli.cli_outputr[   r\   r]   r^   hermes_cli.secret_promptr_   rg   rj   r{   compiler}   rt   listr   r   r   r   r   r   r   r  r)  r;  rA  r[  r_  rd  rr  r  r  r  r  r  r  r  r  r  r   r7  rA  r>  rk  ru  rw  r  r  r  r  r  r  r  r  r  r  r  r9  rU  rA  re  rW  rV  r   r   r   <module>r     s
         				 				  



        & & & & & & & & & & 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 _  _  _}}} N  N  N  C& & Rd38n     +$sCx. +# +$ + + + +                          , + + + + + + +; ; ; ; ;            : 9 9 9 9 9d     d
 d    & S 3  #    ( &2:&DEE 3# 3# 3 3 3 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8[ [ [ [ [|' ' ' ' 'h 9> 6 6 6 6 6 6 6 6|W$ W W W W
/d / / / /d    2    # # # # #LiU iU iU iU iUX d        gB4 gB gB gB gB^	A$ A A A A8i i i i ib $$?@@ 5 5 5 5 5 5E E E$,cDj , , , ,C$J    kB kB kB\AC AC ACH(
 (
 (
Vq: q: q:h>V >V >VB  ,E ,E ,E^h$ h h h h`> > >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Q4 Q4$ Q4 Q4 Q4 Q4hd. d. d.NF. F. F. F. F. F.Rc.T c. c. c. c. c. c.r   