
    i                       d Z ddlZddlZddlZddlZddlZddlZddl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  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g dg dg dg dg dg dg dg ddZ"d	eeef         d
efdZ#d	eeef         ded
dfd Z$dd!l%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z. dd"l/m0Z0m1Z1 d#efd$Z2dd%l3m4Z4m5Z5m6Z6m7Z7 d
e fd&Z8dd'edz  d
dfd(Z9dd*ed+ed,e d
efd-Z:dd*ed.e;d+e<d/edz  d
e<f
d0Z=dd*ed.e;d+e<d/edz  d
e<f
d1Z>dd*ed+e d
e fd3Z?dd#ed4e;d5e;d
e;fd6Z@d7eAfd8ZBd	eAfd9ZCd	eAfd:ZDd)d;d	eAd<e fd=ZEd
e fd>ZFd
e fd?ZGd	eAfd@ZHd	eAfdAZId	eAfdBZJd	eAfdCZKd	eAfdDZLdE ZMdF ZNdGed
e;fdHZOdI ZPdJ ZQdK ZRdL ZSdM ZTdN ZUdO ZVdP ZWdQ ZXdR ZYdS ZZdT Z[dU Z\dV Z]dW Z\dX Z^dYdZeMfd[d\eNfd]d^ePfd_d`eUfdadbeVfdcddeWfdedfeQfdgdheRfdidjeSfdkdleXfdmdneYfdodpeZfdqdre[fdsdteTfdudve]fdwdxe\fdydze^fgZ_d	eAfd{Z`dd	eAd|e fd}Zad	eAd~ed
ee         fdZbd	eAd~eded
e fdZc eedz            dz  dz  dz  dz  Zdd Zedddddddddd	ZfdeAfdZgde	d
e fdZhddeEfddeIfddeJfdde`fddeafddeLfgZig dZjd Zkd
ee;e                  fdZld Zmd	eAde fdZnd	eAfdZod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)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     8/home/agentuser/.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!   0   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+   8   sj     x8++u<t111111##H--G u @@@r   copilot-acp)gpt-5.4zgpt-5.4-miniz
gpt-5-minigpt-5.3-codexzgpt-5.2-codexgpt-4.1gpt-4ogpt-4o-minizclaude-opus-4.6zclaude-sonnet-4.6zclaude-sonnet-4.5zclaude-haiku-4.5gemini-2.5-prozgrok-code-fast-1)zgemini-3.1-pro-previewzgemini-3-flash-previewzgemini-3.1-flash-lite-previewr2   zgemini-2.5-flashzgemini-2.5-flash-litezgemma-4-31b-itzgemma-4-26b-it)glm-5.1glm-5zglm-4.7zglm-4.5zglm-4.5-flash)	kimi-k2.5zkimi-k2-thinkingzkimi-k2-turbo-preview)ztrinity-large-thinkingztrinity-large-previewztrinity-mini)zMiniMax-M2.7zMiniMax-M2.5zMiniMax-M2.1z
MiniMax-M2)anthropic/claude-opus-4.6anthropic/claude-sonnet-4.6zopenai/gpt-5zgoogle/gemini-3-flash)r6   r7   zopenai/gpt-5.4zgoogle/gemini-3-pro-previewzgoogle/gemini-3-flash-preview)r-   r.   zclaude-sonnet-4-6zgemini-3-flashr4   r5   minimax-m2.7)r3   r4   r5   zmimo-v2-prozmimo-v2-omnizminimax-m2.5r8   )zQwen/Qwen3.5-397B-A17Bz"Qwen/Qwen3-235B-A22B-Thinking-2507z#Qwen/Qwen3-Coder-480B-A35B-Instructzdeepseek-ai/DeepSeek-R1-0528zdeepseek-ai/DeepSeek-V3.2zmoonshotai/Kimi-K2.5)r,   copilotgeminizaikimi-codingkimi-coding-cnarceeminimax
minimax-cn
ai-gatewaykilocodezopencode-zenzopencode-gohuggingfacec                     |                      d          }t          |t                    rHt          |                     d          pd                                                                          S dS )Nagentreasoning_effort )r   r   r   r   r   lower)r
   	agent_cfgs     r   _current_reasoning_effortrJ   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 )NrE   rF   r   )r
   rK   rI   s      r   _set_reasoning_effortrM   y   sD    

7##Ii&& $	#w$*I !!!r   )	DEFAULT_CONFIGget_hermes_homeget_config_pathget_env_pathload_configsave_configsave_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)printrX   rW   CYANBOLD)rY   s    r   print_headerr^      s5    	GGG	%uV[
9
9:::::r   )print_error
print_infoprint_successprint_warningc                      t          t          dd          } | dS 	 t          |                                           S # t          $ r Y dS w xY w)z;Return True when stdin looks like a usable interactive TTY.stdinNF)getattrsysboolisatty	Exception)rd   s    r   is_interactive_stdinrj      sZ    C$''E}uELLNN###   uus    = 
A
Areasonc                    t                       t          t          dt          j        t          j                             t                       | rt          |            t          d           t                       t          d           t          d           t          d           t          d           t                       t          d           t          d           t                       d	S )
z8Print guidance for headless/non-interactive setup flows.u)   ⚕ Hermes Setup — Non-interactive modez+The interactive wizard cannot be used here.z@Configure Hermes using environment variables or config commands:z)  hermes config set model.provider customz;  hermes config set model.base_url http://localhost:8080/v1z1  hermes config set model.default your-model-namez?Or set OPENROUTER_API_KEY / OPENAI_API_KEY in your environment.zERun 'hermes setup' in an interactive terminal to use the full wizard.N)r[   rX   rW   r\   r]   r`   )rk   s    r   #print_noninteractive_setup_guidancerm      s    	GGG	%;V[&+
V
VWWW	GGG 6<===	GGGQRRR:;;;LMMMBCCC	GGGPQQQVWWW	GGGGGr   Fquestionr   passwordc                 ~   |r	|  d| d}n|  d}	 |r2ddl }|                     t          |t          j                            }n't	          t          |t          j                            }|                                p|pdS # t          t          f$ r& t                       t          j
        d           Y dS w xY w)z'Prompt for input with optional default. []: : r   NrG      )getpassrX   rW   YELLOWinputr   KeyboardInterruptEOFErrorr[   rf   exit)rn   r   ro   displayru   values         r   promptr}      s     "-----/// 	9NNNOOE'6=$A$ABBEE%7788E{{}}--2-x(   s   A2B 3B<;B<choicesdescriptionc                 .    ddl m}  || ||d|          S )z?Single-select menu using curses. Delegates to curses_radiolist.r   )curses_radiolist)selectedcancel_returnsr   )hermes_cli.curses_uir   )rn   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 (rt   z)  Ctrl+C to exitTz  Select [1-z] (z): z$Please enter a number between 1 and zPlease enter a number)r   r`   r[   rX   rW   rv   	enumerateGREENrw   lenDIMintr_   
ValueErrorrx   ry   rf   rz   )	rn   r~   r   r   idxichoicemarkerr|   s	            r   prompt_choicer      s+     '7
T
T
TC
axx'>>4555GGGN
	%&-
(
()))w'' * *	6w,,E<<%.V..f..==>>>>(v(((())))Ew{EEEFFF	FS\\FFgkFFF
SS E  e**q.CC&&&&#g,,&&&&&
Ms7||MMNNNN 	1 	1 	1/00000!8, 	 	 	GGGHQKKKKK	s%   6AF	 80F	 )F	 	G$2GGTc                 h   |rdnd}	 	 t          t          |  d| dt          j                                                                                            }n9# t          t          f$ r% t                       t          j
        d           Y nw xY w|s|S |dv rdS |dv rd	S t          d
           )z=Prompt for yes/no. Ctrl+C exits, empty input returns default.zY/nzy/NTrq   rr   rt   )yyes)nnoFzPlease enter 'y' or 'n')rw   rX   rW   rv   r   rH   rx   ry   r[   rf   rz   r_   )rn   r   default_strr|   s       r   prompt_yes_nor     s    "-%%K/	ex;;;;;;V]KKLL E
 "8, 	 	 	GGGHQKKKKK	  	NL  4K5-...#/s   AA 3BBitemspre_selectedc                     |g }ddl m}  || |t          |          t          |                    }t          |          S )u  
    Display a multi-select checklist and return the indices of selected items.

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

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

    Returns:
        List of selected indices (not including the Continue option).
    Nr   )curses_checklist)r   )r   r   setsorted)rY   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: ro   r   r}   Tro        ✓ Savedz/  Skipped (configure later with 'hermes setup'))r   joinr   r[   rX   rW   r\   r`   r}   rT   ra   rb   )r   r   	tools_strr|   s       r   _prompt_api_keyr   <  s   GGGR  E		%)$$I
5zzA~~03u::>0000		GGG	%Nsww}c&kBBNNNPVP[
\
\]]]	GGG .,,,---
wwu~~ 75U55666	GGG
wwz ><CGGHc&k::<<tLLL<CGGHc&k::<<== Is6{E***m$$$$$GHHHHHr   c                    t                       t          d           g }t          |           }	 ddlm}  |            }n# t
          $ r g }Y nw xY w|r|                    d           n|                    d           t          d          r|                    d           n|                    d           |j        j	        r|                    d	           nX|j        j
        r7d
}|j        j        rd|j        j         d}|                    |ddf           n|                    d           |j        j        }|j        j	        r|                    d           nl|j        j
        r#d}|rd| d}|                    |ddf           n=d}|dk    rd}n|dk    rd}n|dk    rd}n|dk    rd}|                    dd|f           |j        j	        r|                    d           n7|j        j
        r|                    d           n|                    d           |                     d i                               d!d"          }	|j        j	        r|                    d#           nt|	d$k    r&t          d%          r|                    d&           nH|	d'k    r5t          d(          st          d)          r|                    d*           n|	d+k    r%t          d,          r|                    d-           n|	d.k    r%t          d/          r|                    d0           n|	d1k    r4t          d2          st          d3          r|                    d4           n}|	d5k    rb	 ddl}
|
j                            d5          du}n# t
          $ r d}Y nw xY w|r|                    d6           n+|                    d7           n|                    d8           |j        j	        r|                    d9           n|                     d:i                               d;          d<k    r8|j        j        r|                    d=           n@|                    d>           n*t+                      r|j        r|                    d?           t          d@          r%t          dA          r|                    dB           n:t          d@          r|                    dC           n|                    dD           t          dE          r|                    dF           t          dG          r|                    dH           n|                    dI           |                    dJ           |                    dK           |                    dL           t/          dM |D                       }t1          |          }t3          | dN| dO           t                       |D ]\  }}}|r.t          dPt5          dQt6          j                   dR|            6t          dPt5          dSt6          j                   dR| dRt5          dT| dt6          j                              t                       dU |D             }|r>t?          dV           ddWl m!} t?          dX |             dY           t                       t                       t          t5          dZt6          j                             t          t5          d[t6          j                             t          t5          d\t6          j                             t                       ddWl m!} t          t5          d] |             d^t6          j"        t6          j#                             t                       t          dPt5          d_t6          j$                   d`tK                                  t          dPt5          dat6          j$                   d`tM                                  t          dPt5          dbt6          j$                   dc| dd           t                       t          t5          det6          j                             t                       t          t5          dft6          j"        t6          j#                             t                       t          dPt5          dgt6          j                   dh           t          dPt5          dit6          j                   dj           t          dPt5          dkt6          j                   dl           t          dPt5          dmt6          j                   dn           t          dPt5          dot6          j                   dp           t                       t          dPt5          dqt6          j                   dr           t          dPt5          dst6          j                   dt           t          dPt5          dut6          j                              t          dv           t                       t          dw           t          dPt5          dxtK                       t6          j                              t          dPt5          dxtM                       t6          j                              t                       t          t5          det6          j                             t                       t          t5          dyt6          j"        t6          j#                             t                       t          dPt5          dzt6          j                   d{           t          dPt5          d|t6          j                   d}           t          dPt5          d~t6          j                   d           t                       dS )z#Print the setup completion summary.zTool Availability Summaryr   get_available_vision_backends)Vision (image analysis)TN)r   Fzrun 'hermes setup' to configureOPENROUTER_API_KEY)Mixture of AgentsTN)r   Fr   )z(Web Search & Extract (Nous subscription)TNWeb Search & ExtractzWeb Search & Extract ()TN)r   FzUEXA_API_KEY, PARALLEL_API_KEY, FIRECRAWL_API_KEY/FIRECRAWL_API_URL, or TAVILY_API_KEY)z%Browser Automation (Nous Browser Use)TNzBrowser AutomationzBrowser Automation (zVnpm install -g agent-browser, set CAMOFOX_URL, or configure Browser Use or BrowserbaseBrowserbasezOnpm install -g agent-browser and set BROWSERBASE_API_KEY/BROWSERBASE_PROJECT_IDzBrowser Usez8npm install -g agent-browser and set BROWSER_USE_API_KEYCamofoxCAMOFOX_URLzLocal browserznpm install -g agent-browserF)z$Image Generation (Nous subscription)TN)Image GenerationTN)r   FFAL_KEYttsr   edge)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)TNr:   GEMINI_API_KEYGOOGLE_API_KEY)zText-to-Speech (Google Gemini)TNneutts)zText-to-Speech (NeuTTS local)TN)u)   Text-to-Speech (NeuTTS — not installed)Fzrun 'hermes setup tts')zText-to-Speech (Edge TTS)TN)z#Modal Execution (Nous subscription)TNterminalbackendmodal)zModal Execution (direct Modal)TN)zModal ExecutionFzrun 'hermes setup terminal')z0Modal Execution (optional via Nous subscription)TNTINKER_API_KEYWANDB_API_KEY)RL Training (Tinker)TN)r   Fr   )r   Fr   
HASS_TOKEN)zSmart Home (Home Assistant)TN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 )rt   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)'r[   r^   r   agent.auxiliary_clientr   ri   appendrU   webmanaged_by_nous	availablecurrent_providerbrowser	image_genr   r   importlib.utilutil	find_specr   direct_overrider   nous_auth_presentsumr   r`   rX   rW   r   REDr   rb   hermes_constantsr   r\   r]   rv   rP   rQ   )r
   hermes_hometool_statussubscription_featuresr   _vision_backendslabelbrowser_providermissing_browser_hinttts_provider	importlib	neutts_okavailable_counttotal_countr   r   missing_vardisabled_tools_dhhs                      r   _print_setup_summaryr  X  s    
GGG,---K:6BBHHHHHH88::     bBCCCC`aaa )** O<====MNNN  0 USTTTT		"	, U& $5 	[Z-B-F-WZZZEE4.////  T  	U  	U  	U -4E$4 
PQQQQ		&	0 
$ 	?>+;>>>EE4.////w},,= !  ..J !  **#0  00#A !5*>?	
 	
 	

 &6 COPPPP		(	2 C;<<<<ABBB ::eR((,,Z@@L 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DEEE"2 ]NOOOO	J	#	#	'	'		2	2g	=	= &6 	ZMNNNNXYYYY	#	%	% ]*?*Q ][\\\ %&& N=+I+I N?@@@@	'	(	( NKLLLLLMMM \"" HFGGG ^$$ 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2 N N"!N"c                 <   |                      di           }t                       t          d           |                    dd          }|rdnd}t          d           t          d           t	          d	|          }|                                d
v |d<   |                    dd          }t	          dt          |                    }	 t          |          |d<   n# t          $ r Y nw xY w|                    dd          }t	          dt          |                    }	 t          |          |d<   n# t          $ r Y nw xY w|                    dd          }	t	          dt          |	                    }
	 t          |
          |d<   dS # t          $ r Y dS w xY w)zMPrompt for container resource settings (Docker, Singularity, Modal, Daytona).r   zContainer Resource Settings:container_persistentTr   r   z5  Persistent filesystem keeps files between sessions.z;  Set to 'no' for ephemeral sandboxes that reset each time.z.  Persist filesystem across sessions? (yes/no))r   truer   1container_cpurt   z  CPU corescontainer_memoryi   z  Memory in MB (5120 = 5GB)container_diski   z  Disk in MB (51200 = 50GB)N)

setdefaultr[   r`   r   r}   rH   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                8   ddl m}m} t          d           t	          d           t	          dt
           d           t                       ddlm} 	  |             n# t          t          f$ r  t                       t	          d           Y nRt          $ rF}t                              d	|           t          d
|            t	          d           Y d}~nd}~ww xY w |            }|                    d|                     d                    | d<   d|v r|d         | d<   n|                     dd           d}|                     d          }t#          |t$                    r|                    d          }|dk    }	|s:t'          |          r*	 ddlm}
 ddlm} ddlm}  ||          }|                                }t7          |          }t9          d |D                       }||z
  }t                       t          d           t	          d           t	          d           t	          d           t                       |dk    rt	          d| d| d| d| d	           nt	          d| d|            t;          dd          rp | |
|d dddddddd!ddd"#                      ||          }t7          |                                          }t	          d$| d%           t;          dd          p|d&k    rg d'}t=          |                               |d(          }dd&d)d*                    |d          }t?          d+||          }g d*|         }tA          | ||           tC          d,| d-|            n2# t          $ r%}t                              d.|           Y d}~nd}~ww xY w|rd}nS	 dd/l"m#} tI           |                      }n# t          $ r tI                      }Y nw xY wtK          |           }||v rd}|rXd0d1d2d3d4d5d6d7d8d9d:d;}|                    ||pd<          }t                       t          d=           t	          d>|            t	          d?           t	          d@           t                       g dA}t?          dB|d)          }|dk    rWtM          dCdDE          '                                }|r!tQ          dF|           tC          dG           nvt	          dH           ne|d&k    rOtM          dI          '                                pdJ}dK} dL|)                                v rdM} tM          | dDE          '                                }!|!rtQ          dN|!           | *                    dOi           *                    dPi           }"||"dQ<   dL|)                                v r9g dR}#|#dSgz   }$t?          dT|$d          }%|%t7          |#          k     r|#|%         ndU}&n!tM          dV          '                                }&tQ          dW|&           tC          dX| |&rd|& dYnd z              nt	          dH           nt	          dZ            ||            |s|dk    rtW          |            dS dS dS )[u  Configure the inference provider and default model.

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

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

%t,,, 	G		B"d /FF:..!2f!<  JY78IJJ JYI	Y------777777AAAAAA9.//DllnnGg,,KppgpppppL$|3JGGG<===Z   U   W   GGGA~~`6G ` `; ` `$` `/9` ` `   
 _=N__R]__``` TV[\\ R  #O!2"$" $#'&*"&"#( $!&"&,2    " !y!233!$,,..11PKPPPQQQ)   TV[\\ R, Q# # #
 $C6#J#J#N#NO`bn#o#o "##$( ( #&**	 %
  -=#(   
 "I!H!H!V-f6GXXX^'8^^n^^___ 	Y 	Y 	YLLRTWXXXXXXXX	Y  (#	%LLLLLL"#@#@#B#BCC 	% 	% 	%"uu	% #''7"8"88 000"' Cm-'/,7 &$-,
 
 $(9;L;_P_``9:::PPPQQQRSSSIJJJ
 
 

 $$7!LL!3dCCCIIKKG D3W===OPPPPBCCCCA>??EEGGfKfI(N9??#4#444!3nt<<<BBDDH D/:::))+r::EEhPRSS$-j!#y'8'888)m)m)m&"48S7T"TK+,BKQRSSG #S);%<%<<< +733* +* .44f-g-g-m-m-o-o*79OPPP9i999OW525555UWY   
 BCCCCklll K $&&00F#####$ $00sI   
A .C	C<CCG6N 
N>N99N>O% %P ?P c                  R    ddl }  | j        d          dup | j        d          duS )z Check if espeak-ng is installed.r   N	espeak-ngespeak)shutilwhich)rg  s    r   _check_espeak_ngri  Q  s9    MMM6<$$D0VLFL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installre  )check)chocorn  re  -y)sudoaptrn  rq  re  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piprn  z-Uzneutts[all]z--quietr&  )ro  r,  zneutts installed successfullyzFailed to install neutts: z2Try manually: python -m pip install -U neutts[all])
subprocessrf   ri  r[   rb   platformr`   r   runra   CalledProcessErrorFileNotFoundError
executableTimeoutExpiredr_   )rv  rf   es      r   _install_neutts_depsr~  W  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           	         |                      di           }|                     dd          }t          |           }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	 ddl}|j                            d          du}n# t           $ r d}Y nw xY w|rt#          d           nPt                       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+           njt          d,           d}
nW|
dk    rw|sut          d          pt          d          }|sSt                       t)          d-d$*          }|r!t+          d|           t#          d.           nt          d,           d}
n|
d/k    rxt          d0          }|set                       t)          d1d$*          }|r!t+          d0|           t#          d2           ndd3lm} t          d4 |             d5           d}
n\|
d6k    ret          d7          }|sSt                       t)          d8d$*          }|r!t+          d7|           t#          d9           nt          d,           d}
n|
d:k    rdt          d;          }|sRt                       t)          d<d$*          }|r t+          d;|           t#          d=           nt          d,           d}
n|
d>k    rt          d?          pt          d@          }|sat                       t	          dA           t)          dBd$*          }|r t+          d?|           t#          dC           nt          d,           d}
d| vri | d<   |
| d         d<   t1          |            t#          dD|                     |
|
                      dS )Ez@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)r   r   r   xair?   r   r:   r   z"Text-to-Speech Provider (optional)z	Current: zCNous Subscription (managed OpenAI TTS, billed to your subscription)znous-openai)z-Edge TTS (free, cloud-based, no setup needed)z+ElevenLabs (premium quality, needs API key)z(OpenAI TTS (good quality, needs API key)z$xAI TTS (Grok voices, needs API key)z<MiniMax TTS (high quality with voice cloning, needs API key)z>Mistral Voxtral TTS (multilingual, native Opus, needs API key)zJGoogle Gemini TTS (30 prebuilt voices, prompt-controllable, needs API key)z5NeuTTS (local on-device, free, ~300MB model download)Keep current (r   rt   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   r   FzNeuTTS is already installedzNeuTTS requires:uH     • Python package: neutts (~50MB install + ~300MB model on first use)u,     • System package: espeak-ng (phonemizer)z Install NeuTTS dependencies now?Tz9NeuTTS installation incomplete. Falling back to Edge TTS.zISkipping install. Set tts.provider to 'neutts' after installing manually.r   r   zElevenLabs API keyr   zElevenLabs API key savedz.No API key provided. Falling back to Edge TTS.zOpenAI API key for TTSzOpenAI TTS API key savedr  XAI_API_KEYzxAI API key for TTSzxAI TTS API key savedr   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.r?   r   zMiniMax API key for TTSzMiniMax TTS API key savedr   r   zMistral API key for TTSzMistral TTS API key savedr:   r   r   z<Get a free API key at https://aistudio.google.com/app/apikeyzGemini API key for TTSzGemini TTS API key savedzTTS provider set to: )r   r   r[   r^   r`   r   r   r   extendr   r   rU   rb   r   r   r   ri   ra   r   r~  r}   rT   r   r   rS   )r
   
tts_configr   r   provider_labelscurrent_labelr~   	providerskeep_current_idxr   r   selected_via_nousr   already_installedexistingr&   r  s                    r   rF  rF    s   E2&&J!~~j&99:6BB " (%	 	O $''(8:JKKM	GGG5666*=**+++	GGGGI!## ((=(O (\]]]'''NN		
 		
 		
   fffgggNN4M4445557||a'
.9I
J
JC
~H M1=  `aaa122 	mDT6U6U 	{   8	&!!!! ) 8 8 B B$ N 	& 	& 	& %	&  	"78888GGG)***abbbEFFFGGG?FF "+-- &!"]^^^%Hfggg!	\	!	! !566 	"GGG1DAAAG "3W===89999NOOO!	X		&7	 !9::]mL\>]>] 	"GGG5EEEG "7AAA89999NOOO!	U		 // 	"GGG2TBBBG 
"}g66656666HHHHHH0-1TVV0 0 0  
 "	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! Fu (F5M*S/*=*=h*Q*QSSTTTTTs   ( G	 	GGc                 $    t          |            dS )z.Standalone TTS setup (for 'hermes setup tts').N)rF  r
   s    r   	setup_ttsr  1  s    r   c           	      &   ddl }ddl}t          d           t          d           t          d           t          dt           d           t                       |                     di                               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    r4t          d           t          d           t                       t          d            t          d!           t          d"           |                     di                               d#d$          }t          d%|pt          t          j                                        }|r|| d         d#<   t                       t!          d&          }|rt          d'           	nXt#          d(d)          r2t          d*d+,          }|rt%          d&|           t          d-           	n|dk    rt          d.            |j        d          }|st)          d/           t          d0           nt          d1|            |                     di                               d2d3          }t          d4|          }|| d         d2<   t%          d5|           t+          |            nV|dk    rt          d6            |j        d7          p |j        d          }|st)          d8           t          d9           nt          d:|            |                     di                               d;d<          }t          d=|          }|| d         d;<   t%          d>|           t+          |            n|dk    rt          d?           t          d@           ddAlm} ddBlm} t5          t7                      ot9          |           j        o
 |d                    } ||                     di                               dC                    }d)}|r@dDdEg}|dFk    rd}n|dGk    rd}nt!          dH          rdnd}t          dI||          }|dk    }|rIdF| d         dC<   t          dJ           t!          dH          st!          dK          rt          dL           ndG| d         dC<   t          dM           	 t=          d           n# t>          $ r t          dN           ddl } |j        dO          }|r)|!                    |dPdQdRtD          j#        dgd+d+S          }n'|!                    tD          j#        dTdPdQdgd+d+S          }|j$        dk    rt          dU           nt)          dV           Y nw xY wt                       t          dW           t          dX           t!          dH          }|rft          dY           t#          dZd)          rFt          d[d+,          } t          d\d+,          }!| rt%          dH|            |!rt%          dK|!           nFt          d[d+,          } t          d\d+,          }!| rt%          dH|            |!rt%          dK|!           t+          |            n|dk    rMt          d]           t          d^           t          d_           t          d`           	 t=          d           n# t>          $ r t          da           ddl } |j        dO          }|r)|!                    |dPdQdRtD          j#        dgd+d+S          }n'|!                    tD          j#        dTdPdQdgd+d+S          }|j$        dk    rt          db           nWt)          dc           |j%        rAt          dd|j%        &                                '                                de                     Y nw xY wt                       t!          df          }"|"rRt          dg           t#          dhd)          r2t          did+,          }#|#rt%          df|#           t          dj           n2t          did+,          }#|#rt%          df|#           t          dk           |                     di                               dld3          }t          dm|          }|| d         dl<   t%          dn|           t+          |            n4|dk    r-t          do           t          dp           t!          dq          pd$}$t          dr|$          }%|%rt%          dq|%           t!          ds          pd$}&t          dt|&ptQ          j)        dud$                    }'|'rt%          ds|'           t!          dv          pdw}(t          dx|(          })|)r|)dwk    rt%          dv|)           t!          dy          pd$}*t          t          j                    dzz  d{z            }+t          d||*p|+          },|,rt%          dy|,           |%rt#          d}d+          rt          d~           ddl }g d}-|,r|-*                    d|,g           |)r|)dwk    r|-*                    d|)g           |-                    |'r|' d|% n|%           |-                    d           |!                    |-d+d+d          }|j$        dk    rt          d           n8t)          d|j%        &                                            t          d           t%          d|           |dk    r*t%          d| d                             dCd                     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   local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   rt   r1  r      rt   r1  r   r  )r  r  r   r  r     z.Singularity/Apptainer - HPC-friendly containersingularityr  r   zSelect terminal backend:zKeeping current backend: zTerminal backend: Localz&Commands run directly on this machine.z)Working directory for messaging sessions:z7  When using Hermes via Telegram/Discord, this is wherezD  the agent starts. CLI mode always starts in the current directory.cwdrG   z  Messaging working directorySUDO_PASSWORDzSudo password: configuredz<Enable sudo support? (stores password for apt install, etc.)Fz  Sudo passwordTr   zSudo password savedzTerminal backend: DockerzDocker not found in PATH!z3Install Docker: https://docs.docker.com/get-docker/zDocker found: docker_imagez*nikolaik/python-nodejs:python3.11-nodejs20z  Docker imageTERMINAL_DOCKER_IMAGEz'Terminal backend: Singularity/Apptainer	apptainerz(Singularity/Apptainer not found in PATH!z@Install: https://apptainer.org/docs/admin/main/installation.htmlzFound: singularity_imagez3docker://nikolaik/python-nodejs:python3.11-nodejs20z  Container imageTERMINAL_SINGULARITY_IMAGEzTerminal backend: Modalz@Serverless cloud sandboxes. Each session gets its own container.)is_managed_tool_gateway_ready)normalize_modal_mode
modal_modezUse my Nous subscriptionzUse my own Modal accountmanageddirectMODAL_TOKEN_IDz,Select how Modal execution should be billed:zPModal execution will use the managed Nous gateway and bill to your subscription.MODAL_TOKEN_SECRETzZDirect Modal credentials are still configured, but this backend is pinned to managed mode.z+Requires a Modal account: https://modal.comzInstalling modal SDK...uvru  rn  --pythoncapture_outputtextrt  zmodal SDK installedu2   Install failed — run manually: pip install modalzModal authentication:z/  Get your token at: https://modal.com/settingsz!  Modal token: already configuredz  Update Modal credentials?z    Modal Token IDz    Modal Token SecretzTerminal backend: Daytonaz*Persistent cloud development environments.zBEach session gets a dedicated sandbox with filesystem persistence.zSign up at: https://daytona.iozInstalling daytona SDK...zdaytona SDK installedu4   Install failed — run manually: pip install daytona	  Error: r   DAYTONA_API_KEYz%  Daytona API key: already configuredz  Update API key?z    Daytona API keyz    Updatedz    Configureddaytona_imagez  Sandbox imageTERMINAL_DAYTONA_IMAGEzTerminal backend: SSHz)Run commands on a remote machine via SSH.TERMINAL_SSH_HOSTz  SSH host (hostname or IP)TERMINAL_SSH_USERz
  SSH userUSERTERMINAL_SSH_PORT22z
  SSH portTERMINAL_SSH_KEYz.sshid_rsaz  SSH private key pathz  Test SSH connection?z  Testing connection...)r  -ozBatchMode=yesr  zConnectTimeout=5z-iz-p@zecho ok
   )r  r  r,  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: ),rw  rg  r^   r`   r<  r[   r   systemr   r   r  ra   r}   r   r   homerU   r   rT   rh  rb   r  tools.managed_tool_gatewayr  tools.tool_backend_helpersr  rg   r   r   r   
__import__ImportErrorrv  rx  rf   r{  
returncodestderrr   
splitlinesosgetenvr  rS   ).r
   	_platformrg  current_backendis_linuxterminal_choicesidx_to_backendbackend_to_idxnext_idxr  terminal_idxselected_backendcurrent_cwdr  existing_sudo	sudo_pass
docker_bincurrent_imageimagesing_binr  r  managed_modal_availabler  use_managed_modalmodal_choicesdefault_modal_idxmodal_mode_idxrv  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  ;  sz       MMM#$$$BCCCIJJJEJEEEFFF	GGGjjR0044YHHO!!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;<<< 	>???LMMMR	
 	
 	
 jjR0044UB??4k6USEUEUVV 	,(+F:u% 	%o66 		923333NPU  9 ##4tDDD	 9"?I>>>!"7888	X	%	%0111 "V\(++
 	65666LMMMM4
44555 

:r2266H
 
 '77-2z>*.666#F++++	]	*	*?@@@  6<,,K]0K0K 	-DEEER    +++,,,

:r2266!V
 
 *M::27z./3U;;;#F++++	W	$	$/000UVVVLLLLLLCCCCCC"&&(( 7*622D7 .-g66	#
 #
 *)&**Z*D*D*H*H*V*VWW
!" 	4**M Y&&$%!!x''$%!!)67G)H)H$OAAa!*>! N
 !/! 3 ?	G/8F:|,ijjj-.. -@T2U2U p   08F:|,DEEEX7#### X X X4555!!!!%d++ '^^"!%&N# (,! ,  FF (^^uiI'+! ,  F
 $))!"78888!"VWWW7X< GGG.///HIII*+;<<N G>??? !>FF K%&:TJJJH#)*BT#R#R#RL C&'7BBB# K&';\JJJ!"6FFF%&>NNN ?"#3X>>> G"#7FFF#F++++	Y	&	&1222?@@@WXXX3444	Uy!!!! 	U 	U 	U2333!V\$''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':::./// 

:r2266I
 
 (-88.3z?+/777#F++++	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&   !U1 1B)XX]. .C1a"!a"c                    d|                      di           d<   t          dd           d|                      di           d<   d	|                      d
i           d<   d| d
         d<   |                      di                               dddd           t          |            t	          d           t          d           t          d           t          d           t          d           t          d           dS )zDApply recommended defaults for all agent settings without prompting.Z   rE   	max_turnsHERMES_MAX_ITERATIONS90allr{   tool_progressTcompressionenabled      ?	thresholdsession_resetboth  r  )modeidle_minutesat_hourzApplied recommended defaults:z  Max iterations: 90z  Tool progress: allz  Compression threshold: 0.50z5  Session reset: inactivity (1440 min) + daily (4:00)z.  Run `hermes setup agent` later to customize.N)r  rT   updaterS   ra   r`   r  s    r   _apply_default_agent_settingsr    s   24Fgr"";/*D1118=Fi$$_56:FmR((3)-F=+&
or**113 3    1222%&&&%&&&.///FGGG?@@@@@r   c           	         t          d           t          dt           d           t                       t	          d          p6t          |                     di                               dd                    }t          d           t          d	           t          d
           t          d|          }	 t          |          }|dk    r^t          dt          |                     || 
                    di           d<   |                     d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           |                     di                               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%<   |                     d$i                               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          d.           t          d/           t          d0           t          d           t          d1           t          d           g d2}	|                     d3i           }
|
                    d4d5          }|
                    d6d7          }|
                    d8d9          }dd:d;d<d=                    |d          }t%          d>|	|          }| 
                    d3i            |dk    rd5| d3         d4<   t          d?t          |                    }	 t          |          }|dk    r|| d3         d6<   n# t          $ r Y nw xY wt          d@t          |                    }	 t          |          }d|cxk    rdAk    rn n|| d3         d8<   n# t          $ r Y nw xY wt          dB| d3                             d6d7           dC| d3                             d8d9           dD           nU|d:k    rdE| d3         d4<   t          d?t          |                    }	 t          |          }|dk    r|| d3         d6<   n# t          $ r Y nw xY wt          dB| d3                             d6d7           dF           n|d;k    rdG| d3         d4<   t          d@t          |                    }	 t          |          }d|cxk    rdAk    rn n|| d3         d8<   n# t          $ r Y nw xY wt          dH| d3                             d8d9           dD           n/|d<k    r)dI| d3         d4<   t          dJ           t          dK           t!          |            dS )LzSConfigure agent behavior: iterations, progress display, compression, session reset.Agent Settingsr  z/user-guide/configurationr  rE   r  r  z1Maximum tool-calling iterations per conversation.z3Higher = more complex tasks, but costs more tokens.zIDefault is 90, which works for most tasks. Use 150+ for open exploration.zMax iterationsr   NzMax iterations set to z%Invalid number, keeping current valuerG   zTool Progress Displayz=Controls how much tool activity is shown (CLI and messaging).u-     off     — Silent, just the final responseu>     new     — Show tool name only when it changes (less noise)u7     all     — Show every tool call with a short previewu0     verbose — Full args, results, and debug logsr{   r  r  zTool progress mode)offnewr  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  r  r  r  r   r  rt   r1  r   )r  idledailynonezSession reset mode:z  Inactivity timeout (minutes)z%  Daily reset hour (0-23, local time)   zSessions reset after z min idle or daily at z:00r	  z min of inactivityr
  zSessions reset daily at r  zGSessions will never auto-reset. Context is managed only by compression.zFLong conversations will grow in cost. Use /reset manually when needed.)r^   r`   r<  r[   rU   r   r   r}   r   rT   r  rA  ra   r   rb   rH   rS   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    sv    !"""AJAAABBB	GGG   788 C

7B##K44= =K BCCCDEEEZ[[[*K88L?|$$a<<2CMMBBB:BFgr**;7JJ{D)))=8==>>> ? ? ?=>>>>>? rNNN&'''NOOO>???OPPPHIIIABBB::i,,00%HHL&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

="5599+tLL=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   :A3D. .E
	E
*L/ /
L<;L< S/ /
S<;S<*U 
UU W4 4
X X!*Z 
ZZc                     t          d           t          d          } | rt          d           t          dd          st          d          srt          d           t          dd	          rSt          d
           t	          d          }|r3t          d|                    dd                     t          d           dS t          d           ddl}	 t	          dd	          }|sdS |	                    d|          st          d           <	 t          d|           t          d           t                       t          d           t          d           t          d           t          d           t                       t	          d          }|r4t          d|                    dd                     t          d           nt          d           t                       t          d           t          d           t          d            |r-|                    d!          d                                         nd}|r]t          d"| d#d	          r$t          d$|           t          d%|            dS t	          d&          }|rt          d$|           dS dS t          d'           t	          d(          }|rt          d$|           dS dS ))z1Configure Telegram bot credentials and allowlist.TelegramTELEGRAM_BOT_TOKENzTelegram: already configuredzReconfigure Telegram?FTELEGRAM_ALLOWED_USERSuA   ⚠️  Telegram has no user allowlist - anyone can use your bot!Add allowed users now?Tz6   To find your Telegram user ID: message @userinfobot"Allowed user IDs (comma-separated)r   rG   zTelegram allowlist configuredNz'Create a bot via @BotFather on Telegramr   zTelegram bot tokenr   z^\d+:[A-Za-z0-9_-]{30,}$znInvalid token format. Expected: <numeric_id>:<alphanumeric_hash> (e.g., 123456789:ABCdefGHI-jklMNOpqrSTUvwxYZ)zTelegram token saved,   🔒 Security: Restrict who can use your botz!   To find your Telegram user ID:z&   1. Message @userinfobot on Telegramz:   2. It will reply with your numeric ID (e.g., 123456789)?Allowed user IDs (comma-separated, leave empty for open access)zATelegram allowlist configured - only listed users can use the botu@   ⚠️  No allowlist set - anyone who finds your bot can use it!:   📬 Home Channel: where Hermes delivers cron job results,.   cross-platform messages, and notifications.z:   For Telegram DMs, this is your user ID (same as above).,zUse your user ID (z) as the home channel?TELEGRAM_HOME_CHANNELzTelegram home channel set to zHHome channel ID (or leave empty to set later with /set-home in Telegram)zI   You can also set this later by typing /set-home in your Telegram chat.z*Home channel ID (leave empty to set later))r^   rU   r`   r   r}   rT   replacera   rematchr_   r[   splitr   )r  allowed_usersr+  tokenfirst_user_idhome_channels         r   _setup_telegramr2  U  s[   122H 12224e<< 
	 !9:: G^___ !94@@ GWXXX$*+O$P$PM$ G&'?AVAVWZ\^A_A_```%&EFFFF8999III
+d;;; 	Fxx3U;; 	@   '///()))	GGG=>>>23337888KLLL	GGGI M  W/1F1FsB1O1OPPPYZZZZUVVV	GGGKLLL?@@@KLLL;HPM'',,Q/55777bM BSmSSSUYZZ 	F2MBBBI-IIJJJJJ!"lmmL F6EEEEEF F 	^___JKK 	B2LAAAAA	B 	Br   c                     t          d           t          d          } | rt          d           t          dd          st          d          st          d           t          dd	          rat          d
           t	          d          }|rAt          |          }t          dd                    |                     t          d           dS t          d           t	          dd	          }|sdS t          d|           t          d           t                       t          d           t          d           t          d           t          d           t                       t          d           t                       t	          d          }|rBt          |          }t          dd                    |                     t          d           nt          d           t                       t          d           t          d           t          d           t          d           t          d           t	          d          }|rt          d |           dS dS )!z0Configure Discord bot credentials and allowlist.DiscordDISCORD_BOT_TOKENzDiscord: already configuredzReconfigure Discord?FDISCORD_ALLOWED_USERSu@   ⚠️  Discord has no user allowlist - anyone can use your bot!r"  TuJ      To find Discord ID: Enable Developer Mode, right-click name → Copy IDr#  r(  zDiscord allowlist configuredNz;Create a bot at https://discord.com/developers/applicationszDiscord bot tokenr   zDiscord token savedr$  z    To find your Discord user ID:z/   1. Enable Developer Mode in Discord settingsu'      2. Right-click your name → Copy IDzB   You can also use Discord usernames (resolved on gateway start).zLAllowed user IDs or usernames (comma-separated, leave empty for open access)uF   ⚠️  No allowlist set - anyone in servers with your bot can use it!r&  r'  uA      To get a channel ID: right-click a channel → Copy Channel IDz0   (requires Developer Mode in Discord settings)zH   You can also set this later by typing /set-home in a Discord channel.9Home channel ID (leave empty to set later with /set-home)DISCORD_HOME_CHANNEL)
r^   rU   r`   r   r}   _clean_discord_user_idsrT   r   ra   r[   )r  r.  cleaned_idsr/  r1  s        r   _setup_discordr;    s   011H 01113U;; 
	 !899 F]^^^ !94@@ Fklll$*+O$P$PM$ F&=m&L&L&'>@U@UVVV%&DEEEFLMMM&666E &...'(((	GGG=>>>1222@AAA8999	GGGSTTT	GGGV M  ]-m<<.0E0EFFF45555[\\\	GGGKLLL?@@@RSSSABBBYZZZUVVL =-|<<<<<= =r   rawc                    g }|                      dd                              d          D ]}|                                }|                    d          r=|                    d          r(|                    d                              d          }|                                                    d          r
|dd	         }|r|                    |           |S )
zGStrip common Discord mention prefixes from a comma-separated ID string.r   rG   r(  z<@>z<@!zuser:r  N)	r*  r-  r   r$  endswithlstriprstriprH   r   )r<  cleaneduids      r   r9  r9    s    G{{3##))#..    iikk>>$ 	0CLL$5$5 	0**U##**3//C99;;!!'** 	abb'C 	 NN3Nr   c                     t          d           t          d          } | r!t          d           t          dd          sdS t          d           t          d           t          d	           t          d
           t          d           t          d           t          d           t          d           t          d           t          d           t          d           t          d           t	          d           t	          d           t          d           t          d           t          d           t                       t          d           t                       t          dd          }|sdS t          d|           t          dd          }|rt          d|           t          d           t                       t          d           t          d            t                       t          d!          }|r5t          d"|	                    d#d$                     t          d%           dS t	          d&           t          d'           dS )(z Configure Slack bot credentials.SlackSLACK_BOT_TOKENzSlack: already configuredzReconfigure Slack?FNzSteps to create a Slack app:uH      1. Go to https://api.slack.com/apps → Create New App (from scratch)u=      2. Enable Socket Mode: Settings → Socket Mode → EnableuB         • Create an App-Level Token with 'connections:write' scopeu<      3. Add Bot Token Scopes: Features → OAuth & Permissionsz5      Required scopes: chat:write, app_mentions:read,z2      channels:history, channels:read, im:history,z<      im:read, im:write, users:read, files:read, files:writez3      Optional for private channels: groups:historyuF      4. Subscribe to Events: Features → Event Subscriptions → Enablez@      Required events: message.im, message.channels, app_mentionz3      Optional for private channels: message.groupsu>      ⚠ Without message.channels the bot will ONLY work in DMs,z     not public channels.u4      5. Install to Workspace: Settings → Install Appz8   6. Reinstall the app after any scope or event changeszD   7. 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-...)Tr   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   rG   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^   rU   r`   r   rb   r[   r}   rT   ra   r*  )r  	bot_token	app_tokenr.  s       r   _setup_slackrK    s   .//H .///1599 	F-...YZZZNOOOSTTTMNNNFGGGCDDDMNNNDEEEWXXXQRRRDEEERSSS-...EFFFIJJJUVVV	GGGfggg	GGG3dCCCI $i0003dCCCI 5()444&'''	GGG=>>>mnnn	GGG^ M  N,m.C.CC.L.LMMM233333bccc  M  	N  	N  	N  	N  	Nr   c            	         t          d           t          d          pt          d          } | r!t          d           t          dd          sdS t          d           t          d	           t          d
           t	                       t          d          }|r#t          d|                    d                     t	                       t          d           t          dd          }|rAt          d|           t          d          }|rt          d|           t          d           nSt          d          }|rt          d|           t          dd          }|rt          d|           t          d           |st          d          rIt	                       t          dd          }|rt          dd           t          d           |rdnd}	 t          d           n# t          $ r t          d| d           d dl}t          j        d!          }|r)|                    |d"d#d$t          j        |gdd%          }	n'|                    t          j        d&d"d#|gdd%          }	|	j        d k    rt          | d'           n[t%          d(| d)           |	j        rAt          d*|	j                                                                        d+                     Y nw xY wt	                       t          d,           t          d-           t	                       t          d.          }
|
r4t          d/|
                    d0d1                     t          d2           nt          d3           t	                       t          d4           t          d5           t          d6           t          d7          }|rt          d8|           dS dS dS )9zConfigure Matrix credentials.MatrixMATRIX_ACCESS_TOKENMATRIX_PASSWORDzMatrix: already configuredzReconfigure Matrix?FNzMWorks with any Matrix homeserver (Synapse, Conduit, Dendrite, or matrix.org).zC   1. Create a bot user on your homeserver, or use your own accountzE   2. Get an access token from Element, or provide user ID + passwordz0Homeserver URL (e.g. https://matrix.example.org)MATRIX_HOMESERVERr   zCAuth: provide an access token (recommended), or user ID + password.z-Access token (leave empty for password login)Tr   u9   User ID (@bot:server — optional, will be auto-detected)MATRIX_USER_IDzMatrix access token savedzUser ID (@bot:server)PasswordzMatrix credentials savedz$Enable end-to-end encryption (E2EE)?MATRIX_ENCRYPTIONr  zE2EE enabledzmautrix[encryption]mautrixzInstalling z...r   r  ru  rn  r  r  rt  z
 installedu.   Install failed — run manually: pip install 'r  r  r   r$  z-   Matrix user IDs look like @username:serverr%  MATRIX_ALLOWED_USERSr   rG   zMatrix allowlist configuredE   ⚠️  No allowlist set - anyone who can message the bot can use it!uI   📬 Home Room: where Hermes delivers cron job results and notifications.zE   Room IDs look like !abc123:server (shown in Element room settings)zD   You can also set this later by typing /set-home in a Matrix room.z6Home room ID (leave empty to set later with /set-home)MATRIX_HOME_ROOM)r^   rU   r`   r   r[   r}   rT   rA  ra   r  r  rv  rg  rh  rx  rf   r{  r  rb   r  r   r  r*  )r  
homeserverr/  user_idro   	want_e2ee
matrix_pkgrv  r  r  r.  	home_rooms               r   _setup_matrixr]    sk   233W}EV7W7WH /0002E:: 	F^___TUUUVWWW	GGGJKKJ D*J,=,=c,B,BCCC	GGGTUUUBTRRRE 6,e444TUU 	6+W55512222011 	6+W555*t444 	6,h7774555 0:/00 0:!"H%PP	 	*.777.))).7F**Y
	Uy!!!! 	U 	U 	U4Z444555\$''F 	#UIz3>:V#'d (  
 $^T5)ZH#'d (    A%%7778888\z\\\]]]= US6=+>+>+@+@+K+K+M+Mb+QSSTTT'	U* 	ABBBBCCC`aa 	`1=3H3Hb3Q3QRRR78888^___^___Z[[[YZZZSTT	 	:-y99999a0: 0:^	: 	:s   G- -D K0/K0c                     t          d           t          d          } | r!t          d           t          dd          sdS t          d           t          d           t          d	           t	                       t          d
          }|r#t          d|                    d                     t          dd          }|sdS t          d|           t          d           t	                       t          d           t          d           t          d           t	                       t          d          }|r4t          d|	                    dd                     t          d           nt          d           t	                       t          d           t          d           t          d           t          d          }|rt          d|           dS dS )z%Configure Mattermost bot credentials.
MattermostMATTERMOST_TOKENzMattermost: already configuredzReconfigure Mattermost?FNz/Works with any self-hosted Mattermost instance.uF      1. In Mattermost: Integrations → Bot Accounts → Add Bot Accountz   2. Copy the bot tokenz3Mattermost server URL (e.g. https://mm.example.com)MATTERMOST_URLr   z	Bot tokenTr   zMattermost token savedr$  u6      To find your user ID: click your avatar → Profilez'   or use the API: GET /api/v4/users/mer%  MATTERMOST_ALLOWED_USERSr   rG   zMattermost allowlist configuredrV  uL   📬 Home Channel: where Hermes delivers cron job results and notifications.uH      To get a channel ID: click channel name → View Info → copy the IDzK   You can also set this later by typing /set-home in a Mattermost channel.r7  MATTERMOST_HOME_CHANNEL)
r^   rU   r`   r   r[   r}   rT   rA  ra   r*  )r  mm_urlr/  r.  r1  s        r   _setup_mattermostre  k  s   /00H 34446>> 	F@AAAWXXX)***	GGGIJJF ='s););<<<;...E %u---*+++	GGG=>>>GHHH8999	GGG\]]M \1=3H3Hb3Q3QRRR78888Z[[[	GGG]^^^YZZZ\]]]UVVL @0,?????@ @r   c                  ^   t          d           t          d          } | rt          d           dS t          d           t          d           t                       t	          dd          r?t          dd	           t          d
           t          d           t          d           dS dS )zConfigure WhatsApp bridge.WhatsAppWHATSAPP_ENABLEDzWhatsApp: already enabledNz2WhatsApp connects via a built-in bridge (Baileys).z9Requires Node.js. Run 'hermes whatsapp' for guided setup.zEnable WhatsApp now?Tr  zWhatsApp enabledz>Run 'hermes whatsapp' to choose your mode (separate bot numberz,or personal self-chat) and pair via QR code.)r^   rU   r`   r[   r   rT   ra   )r  s    r   _setup_whatsappri    s    /00H .///CDDDJKKK	GGG+T22 C)6222()))STTTABBBBB	C Cr   c                  &    ddl m}   |              dS )z>Configure Weixin (personal WeChat) via iLink Bot API QR login.r   )_setup_weixinN)hermes_cli.gatewayrk  )_gateway_setup_weixins    r   rk  rk    )    IIIIIIr   c                  &    ddl m}   |              dS )z#Configure Signal via gateway setup.r   )_setup_signalN)rl  rp  )_gateway_setup_signals    r   rp  rp    rn  r   c                  &    ddl m}   |              dS )z"Configure Email via gateway setup.r   )_setup_emailN)rl  rs  )_gateway_setup_emails    r   rs  rs    )    GGGGGGr   c                  &    ddl m}   |              dS )z)Configure SMS (Twilio) via gateway setup.r   )
_setup_smsN)rl  rw  )_gateway_setup_smss    r   rw  rw    s)    CCCCCCr   c                  &    ddl m}   |              dS )z%Configure DingTalk via gateway setup.r   )_setup_dingtalkN)rl  rz  )_gateway_setup_dingtalks    r   rz  rz    s)    MMMMMMr   c                  &    ddl m}   |              dS )z*Configure Feishu / Lark via gateway setup.r   )_setup_feishuN)rl  r}  )_gateway_setup_feishus    r   r}  r}    rn  r   c                  &    ddl m}   |              dS )z6Configure WeCom (Enterprise WeChat) via gateway setup.r   )_setup_wecomN)rl  r  )_gateway_setup_wecoms    r   r  r    ru  r   c                  &    ddl m}   |              dS )z<Configure WeCom Callback (self-built app) via gateway setup.r   )_setup_wecom_callbackN)rl  r  )	_gw_setups    r   r  r    s#    EEEEEEIKKKKKr   c                     t          d           t          d          } | r!t          d           t          dd          sdS t          d           t          d           t          d	           t	                       t          d
          }|st          d           dS t          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          }|rt          d|           t	                       t          d           dS )zConfigure QQ Bot gateway.QQ Bot	QQ_APP_IDzQQ Bot: already configuredzReconfigure QQ Bot?FNz7Connects Hermes to QQ via the Official QQ Bot API (v2).z,   Requires a QQ Bot application at q.qq.comz7   Reference: https://bot.q.qq.com/wiki/develop/api-v2/zQQ Bot App IDu,   App ID is required — skipping QQ Bot setupzQQ Bot App SecretTr   u0   App Secret is required — skipping QQ Bot setupQQ_CLIENT_SECRETzQQ Bot credentials savedu+   🔒 Security: Restrict who can DM your botz0   Use QQ user OpenIDs (found in event payloads)zCAllowed user OpenIDs (comma-separated, leave empty for open access)QQ_ALLOWED_USERSr   rG   zQQ Bot allowlist configuredu3   ⚠️  No allowlist set — anyone can DM the bot!uB   📬 Home Channel: OpenID for cron job delivery and notifications.z.Home channel OpenID (leave empty to set later)QQ_HOME_CHANNELzQQ Bot configured!)r^   rU   r`   r   r[   r}   rb   rT   r   ra   r*  )r  app_idclient_secretr.  r1  s        r   _setup_qqbotr    s   [))H /0002E:: 	FHIII=>>>HIII	GGGO$$F DEEE;///.>>>M HIII%}555,---	GGG<===ABBB	GGG`aaM J)=+@+@b+I+IJJJ34444HIII	GGGSTTTJKKL 8(,777	GGG&'''''r   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.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   rG   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)r^   rU   r`   r   r[   r}   rb   rT   rA  ra   r*  r   r   r   )r  
server_urlro   r.  r1  webhook_ports         r   _setup_bluebubblesr    s   )***566H 45557?? 	FTUUUBCCCEFFF6777	GGG_```	GGGPQQJ MNNN+Z->->s-C-CDDD3dCCCH KLLL)84441222	GGGABBB[\\\	GGGfggM `2M4I4I#r4R4RSSS89999^___	GGG[\\\UVVVKLLL A1<@@@	GGGGHHH;UCC IEFF 	II93s<?P?P;Q;QRRRC\CCDDDD I I IGHHHHHI 
GGGSTTTXYYYTUUUUUs   <J J$#J$c                  p    ddl m}  t          d | D             d          }|rddl m}  ||           dS dS )z?Configure QQ Bot (Official API v2) via standard platform setup.r   )
_PLATFORMSc              3   2   K   | ]}|d          dk    |V  dS )keyqqbotNr   r   ps     r   r   z_setup_qqbot.<locals>.<genexpr>L  s0      EEa5W1D1D1D1D1D1DEEr   N)_setup_standard_platform)rl  r  nextr  )r  qq_platformr  s      r   r  r  I  sm    ------EE:EEEtLLK .??????  -----. .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           dS ) zConfigure webhook integration.WebhooksWEBHOOK_ENABLEDzWebhooks: already configuredzReconfigure webhooks?FNuD   ⚠  Webhook and SMS platforms require exposing gateway ports to thezE   internet. For security, run the gateway in a sandboxed environmentzB   (Docker, VM, etc.) to limit blast radius from prompt injection.zX   Full guide: https://hermes-agent.nousresearch.com/docs/user-guide/messaging/webhooks/zWebhook port (default 8644)WEBHOOK_PORTr  z'Invalid port number, using default 8644z-Global HMAC secret (shared across all routes)Tr   WEBHOOK_SECRETzWebhook secret saveduE   No secret set — you must configure per-route secrets in config.yamlr  zWebhooks enabled! Next steps:r   r   z   1. Define webhook routes in z/config.yamlz3   2. Point your service (GitHub, GitLab, etc.) at:z3      http://your-server:8644/webhooks/<route-name>z   Route configuration guide:z_   https://hermes-agent.nousresearch.com/docs/user-guide/messaging/webhooks/#configuring-routesz2   Open config in your editor:  hermes config edit)r^   rU   r`   r   r[   rb   r}   rT   r   r   ra   r   r   r   )r  r  secretr  s       r   _setup_webhooksr  R  s9   .//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DDs   :<C7 7DDr  r   r4  r5  rE  rF  SignalSIGNAL_HTTP_URLEmailEMAIL_ADDRESSzSMS (Twilio)TWILIO_ACCOUNT_SIDrM  rN  r_  r`  rg  rh  DingTalkDINGTALK_CLIENT_IDzFeishu / LarkFEISHU_APP_IDzWeCom (Enterprise WeChat)WECOM_BOT_IDzWeCom Callback (Self-Built App)WECOM_CALLBACK_CORP_IDzWeixin (WeChat)WEIXIN_ACCOUNT_IDr  r  r  r  zWebhooks (GitHub, GitLab, etc.)r  c                    t          d           t          d           t          d           t                       g }g }t          t                    D ]~\  }\  }}}t          t          |                    }|dk    r|st          t          d                    }|r| dn|}|                    |           |r|                    |           t          d||          }	|	st          d           d	S |	D ]}
t          |
         \  }}} |             t          d
          pt          d          pt          d          pt          d          pt          d          pt          d          pt          d          pt          d          pt          d          pwt          d          pht          d          pYt          d          pJt          d          p;t          d          p,t          d          pt          d          pt          d          }|rt                       t          d           t          d           g }t          d
          r$t          d          s|                    d           t          d          r$t          d          s|                    d           t          d          r$t          d           s|                    d!           t          d          r$t          d"          s|                    d#           t          d          r$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-d0lm}m}m}m}m}m}m}m}m}m}m}  |            } |            } |            } | p|}!t                       | r" |            r |             t                       |rXt7          d1d2          rF	 | r |             n|r
 |             n$# t8          $ r}"t;          d3|"            Y d	}"~"nd	}"~"ww xY wn|rXt7          d4d2          rF	 | r |             n|r
 |             n# t8          $ r}"t;          d5|"            Y d	}"~"nd	}"~"ww xY wn|!r| rd6nd7}#t7          d8|# d9d2          r	 d	}$d:}%| r |d:;          \  }$}%n |d:;           d2}%t                       |%rZt7          d<d2          rJ	 | r ||$d=k    >           n|r
 |             n)# t8          $ r}"t;          d5|"            Y d	}"~"nd	}"~"ww xY wn# t8          $ r+}"t;          d?|"            t          d@           Y d	}"~"nd	}"~"ww xY wt          dA           | rt          dB           t          dC           nd-dDlm}&  |&            r[t          dE           t          dF           t          dG           t          dH           t          dI           t          dJ           nt          dE           t          dK           t          d           d	S d	S )Lz*Configure messaging platform integrations.Messaging PlatformszAConnect to messaging platforms to chat with Hermes from anywhere.z&Toggle with Space, confirm with Enter.rM  rO  z  (configured)zSelect platforms to configure:zENo platforms selected. Run 'hermes setup gateway' later to configure.Nr   r5  rF  r  r  r  r`  rN  rh  r  r  r  r  r  r  r  u   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━zMessaging platforms configured!r)  r  r8  r4  SLACK_HOME_CHANNELrE  r  BlueBubblesr  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   r  Darwin)_is_service_installed_is_service_runningsupports_systemd_serviceshas_conflicting_systemd_units install_linux_gateway_from_setup$print_systemd_scope_conflict_warningsystemd_startsystemd_restartlaunchd_installlaunchd_startlaunchd_restartz)  Restart the gateway to pick up changes?Tz  Restart failed: z  Start the gateway service?z  Start failed: systemdlaunchdz  Install the gateway as a z. service? (runs in background, starts on boot)F)forcez  Start the service now?r  )r  z  Install failed: z.  You can try manually: hermes gateway installz/  You can install later: hermes gateway installzA  Or as a boot-time service: sudo hermes gateway install --systemz'  Or run in foreground:  hermes gateway)is_containerz,Start the gateway to bring your bots online:z>   hermes gateway run          # Run as container main processrG   z4For automatic restarts, use a Docker restart policy:z*   docker run --restart unless-stopped ...z/   docker restart <container>  # Manual restartz2   hermes gateway              # Run in foreground) r^   r`   r[   r   _GATEWAY_PLATFORMSrg   rU   r   r   ra   rb   r   upperrw  r  rl  r  r  r  r  r  r  r  r  r  r  r  r   ri   r_   r   r  )'r
   r   r   r   r   env_var_funcis_configuredr   r   r   _env_var
setup_funcany_messagingmissing_homeplatr  	_is_linux	_is_macosr  r  r  r  r  r  r  r  r  r  r  service_installedservice_runningsupports_systemdsupports_service_managerr}  svc_nameinstalled_scopedid_installr  s'                                          r   setup_gatewayr    sJ	   &'''RSSS7888	GGG EL%./A%B%B # #!!D'5]733448M /@!A!ABBM+8B4''''dU 	#""" @%VVH Z[[[  %7%<"h

 	*++ 	,,--	,*++	, *++	, ))		,
 -..	, +,,	, .//	, *++	, +,,	, -..	, ))	, ((	, ,--	, 122	, %%	,  *++# &  }:7888 -.. 	,}#8
 8
 	, 
+++,-- 	+m"7
 7
 	+ 	****++ 	)MBV4W4W 	)(((122 	/=Ic;d;d 	/...%% 	)m<M.N.N 	)((( 		GGGOdii6M6MOOPPPPQQQKLLLJKKK$  VdjjllVVV   
 	%$$$$$&&'1	$$&&(2		
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 2133--//4466#3#@y  	 = = ? ? 	00222GGG <	QH$OO ::' *'))))" *')))  : : : 8Q 8 899999999::  3	Q;TBB 88' (%" (%  8 8 8 61 6 67777777788 & *	Q$4Cyy)Hfhfff  FQ&*O"'K' +7W7W^c7d7d7d4'e4444&*GGG" @}5OQU'V'V @@/ 0 -_5P Q Q Q Q Q!* 0 -( @ @ @'(>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:{} }ss   R" "
S	,SS	!S< <
T#TT#AW V+ *W +
W5WW WW 
X
!XX
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  M	  s1     655555Mf======r   section_keyc                    |dk    rt          t          d          pt          d          pt          d                    }|s$	 ddlm}  |            rd}n# t          $ r Y nw xY w|sdS |                     d          }t          |t                    r(|                                r|                                S t          |t                    r9t          |                    d	          p|                    d          pd
          S d
S |dk    r/|                     di                               dd          }d| S |dk    r/|                     di                               dd          }d| S |dk    rFg }t          d          r|
                    d           t          d          r|
                    d           t          d          r|
                    d           t          d          r|
                    d           t          d          r|
                    d           t          d          r|
                    d           t          d           st          d!          r|
                    d"           t          d#          r|
                    d$           t          d%          r|
                    d&           t          d'          r|
                    d(           t          d)          r|
                    d*           t          d+          r|
                    d,           t          d-          r|
                    d.           t          d/          r|
                    d0           t          d1          r|
                    d2           |rd3                    |          S dS |d4k    rg }t          d5          r|
                    d6           t          d7          r|
                    d8           t          d9          r|
                    d:           |rd3                    |          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   r   r   ANTHROPIC_API_KEYr   get_active_providerTNr   
configuredr   r   r  z	backend: rE   r  r  zmax turns: gatewayr   r  r5  r4  rF  rE  SIGNAL_ACCOUNTr  r  r  r  SMSrN  rO  rM  r`  r_  WHATSAPP_PHONE_NUMBER_IDrg  r  r  r  Feishur  WeComr  Weixinr  r  r  r  r   r   r   zTTS/ElevenLabsBROWSERBASE_API_KEYBrowserFIRECRAWL_API_KEY	Firecrawl)rg   rU   r(   r  ri   r   r   r   r   r   r   r   )	r
   r  has_keyr  r   r   r  	platformsr   s	            r   _get_section_config_summaryr  a	  s    g.// 2-..2011
 

  	??????&&(( #"G    	4

7##eS!! 	!ekkmm 	!;;== eT"" 	Suyy++Quyy/A/AQ\RRR|	
	"	"**Z,,00GDD$7$$$			JJw++//R@@	(Y(((			!	!	-.. 	)Z(((,-- 	(Y'''*++ 	&W%%%)** 	'X&&&)) 	&W%%%-.. 	$U###.// 	'=AR3S3S 	'X&&&+,, 	+\***344 	)Z(((-.. 	)Z((()) 	'X&&&(( 	&W%%%,-- 	'X&&&122 	,]+++*++ 	)Z((( 	(99Y'''t			-.. 	+LL)***.// 	$LL###,-- 	&LL%%% 	$99U###t4s   A 
A%$A%r   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   rs   z  Reconfigure ?r   )r  r[   ra   r   rH   )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_specrf   modulesr   exec_moduleri   rA  )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 )statusmigratedr   r   r   s     r   r   z,_print_migration_preview.<locals>.<listcomp>
  ,    HHHA!%%//Z*G*Ga*G*G*Gr   c                 D    g | ]}|                     d           dk    |S )r  conflictr  r  s     r   r   z,_print_migration_preview.<locals>.<listcomp>
  r  r   c                 D    g | ]}|                     d           dk    |S )r  skippedr  r  s     r   r   z,_print_migration_preview.<locals>.<listcomp>
  s,    FFF1xI)E)EQ)E)E)Er   z  Would import:kindunknowndestinationrG   ~r   z<22s    → z:  Would overwrite (conflicts with existing Hermes config):rk   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   r[   rX   rW   r   r   r*  r   r  rH   _HIGH_IMPACT_KIND_KEYWORDSr   addrv   r   r   )r  r   migrated_itemsconflict_itemsskipped_itemswarnings_shownitemr  dest
dest_short
kind_lower
dest_lowerkeywordwarningrk   s                  r   _print_migration_previewr0  
  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  r[   r^   r`   r   rP   rS   rR   r
  rb   ri   r?  r@  resolve_selected_optionsMigratorresolvemigrater   r0  ra   )r   openclaw_dirconfig_pathr  r}  r   dry_migratorpreview_reportpreview_summarypreview_countmigratorr  r  r  r  	conflictserrorsr;  s                     r   _offer_openclaw_migrationrM  C
  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  Messaging Platforms (Gateway)r   ToolsrE   r  )r   r   r  r   rE   c                    ddl m}m}  |            r |d           dS t                       t	          t          | dd                    }|r5t          t          j        t                               t          d           t                      }t                      }t          | dd          }|st                      sd	}|rt          d
           dS t          | dd          }|r!t          D ]\  }}	}
||k    rt!                       t!          t#          dt$          j                             t!          t#          d|	ddt$          j                             t!          t#          dt$          j                              |
|           t          |           t!                       t          |	 d            dS t)          d|            t+          dd                    d t          D                                   dS ddlm}  |            }t	          t3          d                    pt	          t3          d                    p|du}t!                       t!          t#          dt$          j                             t!          t#          dt$          j                             t!          t#          dt$          j                             t!          t#          dt$          j                             t!          t#          dt$          j                             t!          t#          dt$          j                             d}|rt!                       t5          d           t          d           t!                       g d}t7          d |d          }|dk    rt9          ||           dS |d!k    rn|d"k    rt+          d#           dS d$|cxk    rd%k    rhn nt:          |d$z
           t=          fd&t          D             d          }|r0|\  }}	}
 |
|           t          |           t?          ||           dS nYt!                       tA          |          }|rt                      }t7          d'd(d)gd          }|dk    rtC          |||           dS t5          d*           t+          d+tE                                  t+          d,tG                                  t+          d-|            t+          d.tH                      t!                       t+          d/           |r;t!                       t+          d0           t+          d1           t+          d2           |rtK          |d3d4          stM          |           |rtK          |d5d6          stO          |           |rtK          |d7d8          stQ          |           |rtK          |d9d:          stS          |           |rtK          |d;d<          stU          || =           t          |           t?          ||           tW                       dS )>u  Run the interactive setup wizard.

    Supports full, quick, and section-specific setup:
      hermes setup           — full or quick (auto-detected)
      hermes setup model     — just model/provider
      hermes setup tts       — just text-to-speech
      hermes setup terminal  — just terminal backend
      hermes setup gateway   — just messaging platforms
      hermes setup tools     — just tool configuration
      hermes setup agent     — just agent settings
    r   )
is_managedmanaged_errorzrun setup wizardNresetFz Configuration reset to defaults.non_interactiveTz;Running in a non-interactive environment (no TTY detected).sectionr   u   │     ⚕ Hermes Setup — z<34su    │r   z configuration complete!zUnknown setup section: zAvailable sections: r   c              3   "   K   | ]
\  }}}|V  d S Nr   )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.                     │zWelcome Back!z#You already have Hermes configured.)z*Quick Setup - configure missing items onlyz#Full Setup - reconfigure everythingrN  r  rO  rP  r  ExitzWhat would you like to do?rt      z-Exiting. Run 'hermes setup' again when ready.r1     c              3   4   K   | ]}|d          k    |V  dS r   Nr   )r   sr  s     r   r   z#run_setup_wizard.<locals>.<genexpr>t  s1      MM!19L9LA9L9L9L9LMMr   z$How would you like to set up Hermes?u9   Quick setup — provider, model & messaging (recommended)u#   Full setup — configure everythingzConfiguration LocationzConfig file:  zSecrets file: zData folder:  zInstall dir:  z=You can edit these files directly or use 'hermes config edit'z%Settings were imported from OpenClaw.uG   Each section below will show what was imported — press Enter to keep,z#or choose to reconfigure if needed.r   rN  r   r  rE   r  r  r  r   rP  )r  ),r;  rR  rS  rV   rg   re   rS   copydeepcopyrN   ra   rR   rO   rj   rm   SETUP_SECTIONSr[   rX   rW   MAGENTAr_   r`   r   r(   r  rU   r^   r   _run_quick_setup RETURNING_USER_MENU_SECTION_KEYSr  r  rM  _run_first_time_quick_setuprP   rQ   PROJECT_ROOTr  rc  r  r  r  r  _offer_launch_chat)argsrR  rS  reset_requestedr
   r   rU  rV  r  r   funcr  active_provideris_existingmigration_ranmenu_choicesr   r   
setup_moder  s                      @r   run_setup_wizardrr  
  s]    <;;;;;;;z|| ()))74%8899O :DM.112228999]]F!##K d$5u==O #7#9#9  +I	
 	
 	
 	 dIt,,G  . 	 	Cg~~ L    eLELLLLfn]]^^^ L    VF###@@@AAA' * 	7g77888V$))3T3T^3T3T3T*T*TVVWWW 433333))++O]/0011 	'/0011	'$&  
GGG	 @N	
 	
   
NPVP^	
 	
  
 
 @N	
 	
   
Lfn	
 	
  
 
Lfn	
 	
  
 
 @N	
 	
   M 9_%%%;<<<	
 	
 	
 ;\1MMQ;;V[111Fq[[q[[FGGGF&A ;6A:FKMMMM~MMMtTTG :!(5$VF###$V[999F  	 2+>> 	# ]]F"#IG1L
  

 ??'[IIIF )***3 1 133444000111---......///	GGGNOOO ::;;;\]]]8999  %6vwHZ[[ %V$$$  '6vzK]^^ 'v&&&  %6vwHXYY %V$$$  6vyJ_`` f  ;6vwPP ;Fk/:::: ---r   c                      t          j        d          } | r| dgS 	 t          j                            d          t
          j        dddgS n# t          $ r Y nw xY wdS )z>Resolve argv for launching ``hermes chat`` in a fresh process.r   chat
hermes_cliNrt  zhermes_cli.main)rg  rh  r   r   r   rf   r{  ri   )
hermes_bins    r   _resolve_hermes_chat_argvrw    s}    h''J $F##>##L11=ND*;VDD >    4s   .A 
AAc                      t                       t          dd          sdS t                      } | st          d           dS t	          j        | d         |            dS )z7Prompt the user to jump straight into chat after setup.zLaunch hermes chat now?TNzDCould not relaunch Hermes automatically. Run 'hermes chat' manually.r   )r[   r   rw  r`   r  execvp)	chat_argvs    r   ri  ri    sf    	GGG2D99 )++I YZZZIilI&&&&&r   rn  c                 8   t          | d           t          |            |                     di                               dd           t          |            t	                       t          dddgd	          }|d	k    rt          |            t          |            t	                       t          d
           t	                       t          d           |d	k    rt          d           t	                       t          | |           t                       dS )u   Streamlined first-time setup: provider + model only.

    Applies sensible defaults for TTS (Edge), terminal (local), agent
    settings, and tools — the user can customize later via
    ``hermes setup <section>``.
    Tr  r   r   r  z7Connect a messaging platform? (Telegram, Discord, etc.)z"Set up messaging now (recommended)u1   Skip — set up later with 'hermes setup gateway'r   z#Setup complete! You're ready to go.z)  Configure all settings:    hermes setupz1  Connect Telegram/Discord:  hermes setup gatewayN)rc  r  r  rS   r[   r   r  ra   r`   r  ri  )r
   r   rn  gateway_choices       r   rg  rg    s&    t,,,, "&)))
j"%%00GDDD 
GGG"A0?	
 	
 N fF	GGG7888	GGG:;;;FGGG	GGG---r   c           
         ddl m}m}m} t	                       t          d           d  |d          D             }d  |d          D             } |            } |            \  }}	|p	|p|p||	k     }
|
s=t          d           t	                       t          d	           t          d
           dS |rt	                       t          t          |           d           |D ]}t	          d|d                     t	                       |D ]N}t	                       t	          t          d|d          t          j                             t          d|                    dd                      |                    d          rt          d|d                     |                    d          r/t          d|                    d|d                    d          }n,t          d|                    d|d                              }|r0t          |d         |           t          d|d                     6t          d|d                     Pd |D             }d |D             }|rt	                       t          d           g }|D ]o}|                    dg           }|r dd                    |dd                     nd}|                    |                    d|d                    |            pt%          d!|          }|D ]}||         }t'          |           |rJt	                       t          d"           t          d#           t          d$           g }i }|D ]b}|d         }d%|v rd&}nd'|v rd(}nd)|v rd*}n ||vr|                    |           |                    |g                               |           cd+ |D             }t%          d,|          }|D ]}||         }||         }d-d.d/d0                    |d          }t	                       t	          t          d1| d2| d3t          j                             t	                       |D ]}t          d|                    dd                      |                    d          rt          d|d                     |                    d          r/t          d|                    d|d                    d          }n,t          d|                    d|d                              }|r&t          |d         |           t          d4           nt          d5           t	                       |rht	                       t          d6t          |           d7           |D ]#}t          d8|d9          d:|d;                     $|	| d<<   t+          |            t-          | |           dS )=u6   Quick setup — only configure items that are missing.r   )get_missing_env_varsget_missing_config_fieldscheck_config_versionu"   Quick Setup — Missing Items Onlyc                 <    g | ]}|                     d           |S is_requiredr  r   vs     r   r   z$_run_quick_setup.<locals>.<listcomp>  s9       m@T@T	  r   F)required_onlyc                 <    g | ]}|                     d           |S r  r  r  s     r   r   z$_run_quick_setup.<locals>.<listcomp>  s9       AEE-DXDX	  r   z(Everything is configured! Nothing to do.z:Run 'hermes setup' and choose 'Full Setup' to reconfigure,z)or pick a specific section from the menu.Nz required setting(s) missing:u	        • r   r   r   rG   r   z  Get key at: ro   r}   Tr   z  Saved z
  Skipped c                 D    g | ]}|                     d           dk    |S )categorytoolr  r  s     r   r   z$_run_quick_setup.<locals>.<listcomp>>  s.    PPP1AEE*4E4E4O4OQ4O4O4Or   c                 n    g | ]2}|                     d           dk    |                     d          0|3S )r  	messagingadvancedr  r  s     r   r   z$_run_quick_setup.<locals>.<listcomp>?  sJ       55++AEE*4E4E+ 	
+++r   zTool API Keysr   r"  r   r1  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  DISCORDr4  SLACKrE  c                 B    g | ]}d ddd                     ||          S )u   📱 Telegramu   💬 Discordu
   💼 Slackr  r4  rE  r  r  s     r   r   z$_run_quick_setup.<locals>.<listcomp>q  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;  r~  r  r  r[   r^   ra   r`   r   rX   rW   r\   r   r}   rT   rb   r   r   r   r   r  rS   r  )r
   r   r~  r  r  missing_requiredmissing_optionalmissing_configcurrent_ver
latest_verhas_anything_missingr   r|   missing_toolsmissing_messagingchecklist_labelsr   r   selected_indicesr   platform_orderr  r   r  platform_labels	vars_listemojifields                               r   re  re     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   rX  )NFr_  )T)F)p__doc__r   r   loggingr  rg  rf   ra  pathlibr   typingr   r   r   hermes_cli.nous_subscriptionr   r  r   r   r	   	getLogger__name__r?  __file__parentrB  rh  r<  r   r   r   r!   rg   r+   _DEFAULT_PROVIDER_MODELSrJ   rM   r;  rN   rO   rP   rQ   rR   rS   rT   rU   rV   hermes_cli.colorsrW   rX   r^   hermes_cli.cli_outputr_   r`   ra   rb   rj   rm   r}   listr   r   r   r   r   r   r   r  r  rc  ri  r~  rF  r  r  r  r  r2  r;  r9  rK  r]  re  ri  rk  rp  rs  rw  rz  r}  r  r  r  r  r  r  r  r  r  r  r   r
  r#  r0  rM  rc  rf  rr  rw  ri  rg  re  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MMMPPPPPPMMMPPPwww _  _  _}}}sss  G( ( Vd38n     +$sCx. +# +$ + + + +
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 , + + + + + + +; ; ; ; ;           d     d
 d    & S 3  #    *m mC m$ m mWZ]aWa mmp m m m m( (C ($ ( (sUYz (eh ( ( ( (V/ /C /$ /$ / / / /0 C  D D    :I I I I I8b b b b bJ' ' ' ' 'h 9> X$ X$ X$ X$ X$ X$ X$ X$@W$ W W W W/d / / / /deU eU eU eU eUP d        OB4 OB OB OB OBn
A$ A A A A2b b b b bTDB DB DBN3= 3= 3=l     2N 2N 2NjS: S: S:l(@ (@ (@VC C C$                -( -( -(`>V >V >VB. . .+E +E +E` %7#^4. -0o|,):6$m4%'89#_5%7o}5 .,?&(@BWX+];79KL{L)&(9?K# *o$ o o o on> > >T > > > >(V V3 V8C= V V V Vr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$ $ $  S S Sl8DI#6    ' ' ') ) ) ) ) )Xc.T c. c. c. c. c. c.r   