
    i-                       U d 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
mZ ddlmZmZmZmZ ddlmZmZ ddlmZmZ ddlmZ  ej        e          Z ee          j        j                                        Zdd	l m!Z"m#Z$m%Z&m'Z(m)Z* g d
Z+h dZ,d Z-de.fdZ/ddl0m1Z2 d  e2j3                    D             Z1dddddg dddddgddddg dd d!d"d#dd$d%d&gdd d'd(d)d*d+d&gd,d-d.d"d/d0d1d2d&gd3d d4d"d5d6d7d8d&gd9d d:d;d<d=d>d?d&gd@d gdAdBdCdDdEdddFdGg ddHdIdJgdKdLdMdNdGdIdOdPd&gdQdRd"dSdTdUdVdWd&gdQdXd"dYdZd[d\d]d&gdQd^d_d`dadbdcddd&gdQdedfdgdGdJdhdigdQgdjdkdldddmg ddndogdpdqdrd"dsdodtdud&gdpdvgdAdwdxdyddzg d{dd|d}gd~d	dddg dd~ddd"ddddd&dddigdd~ddd"dd}ddd&gd{d~ddd"ddIdOdPd&gdGd~dddddddddgdddgdAdddddddiddddgdgdAddddddddd&dddd&gddgddZ4dgdgdZ5de6fdZ7de	e6         fdZ8dde9de
e	e6                  dee6ee6         f         fdZ:dde;de;fdZ<ddde9de6de;dee6         fdZ=de9de6dee6         fdÄZ>dde6de9de;fdńZ?dde6de@deAdeAfdȄZBdaCe
ee6eAf                  eDd<   dee6eAf         fdʄZEde6dee6         dee6         fd̈́ZFde6de9fd΄ZGde9de9de@e9         fdЄZHde6de9de;fdфZIde6de9de9fd҄ZJde9de9de;fdԄZKde@de9deAfdքZLdׄ ZMdpdrdneMd؜iZNde6de9de9de6fd܄ZOde6de9ddfdބZPde9de9fd߄ZQde6fdZRde9fdZSde6de9de9fdZTde9de9fdZUde6fdZVdde;de9fdZWde9fdZXde9de6de	e6         de6fdZYde9de	e6         de6dee6         fdZZdde.de9de6fdZ[d Z\dS )uY  
Unified tool configuration for Hermes Agent.

`hermes tools` and `hermes setup tools` both enter this module.
Select a platform → toggle toolsets on/off → for newly enabled tools
that need API keys, run through provider-aware configuration.

Saves per-platform tool configuration to ~/.hermes/config.yaml under
the `platform_toolsets` key.
    N)Path)DictListOptionalSet)load_configsave_configget_env_valuesave_env_value)Colorscolor)apply_nous_managed_defaultsget_nous_subscription_features)managed_nous_tools_enabled)print_error
print_infoprint_successprint_warningprompt))webu   🔍 Web Search & Scrapingzweb_search, web_extract)browseru   🌐 Browser Automationznavigate, click, type, scroll)terminalu   💻 Terminal & Processeszterminal, process)fileu   📁 File Operationszread, write, patch, search)code_executionu   ⚡ Code Executionexecute_code)visionu    👁️  Vision / Image Analysisvision_analyze)	image_genu   🎨 Image Generationimage_generate)moau   🧠 Mixture of Agentsmixture_of_agents)ttsu   🔊 Text-to-Speechtext_to_speech)skillsu   📚 Skillszlist, view, manage)todou   📋 Task Planningr%   )memoryu   💾 Memoryz!persistent memory across sessions)session_searchu   🔎 Session Searchzsearch past conversations)clarifyu   ❓ Clarifying Questionsr(   )
delegationu   👥 Task Delegationdelegate_task)cronjobu   ⏰ Cron JobszBcreate/list/update/pause/resume/run, with optional attached skills)	messagingu   📨 Cross-Platform Messagingsend_message)rlu   🧪 RL TrainingzTinker-Atropos training tools)homeassistantu   🏠 Home Assistantzsmart home device control>   r.   r    r/   c                      t          t                    } 	 ddlm}m}  |             |                      |                       n# t          $ r Y nw xY w| S )zReturn CONFIGURABLE_TOOLSETS + any plugin-provided toolsets.

    Plugin toolsets are appended at the end so they appear after the
    built-in toolsets in the TUI checklist.
    r   discover_pluginsget_plugin_toolsets)listCONFIGURABLE_TOOLSETShermes_cli.pluginsr2   r3   extend	Exception)resultr2   r3   s      ?/home/agentuser/.hermes/hermes-agent/hermes_cli/tools_config.py$_get_effective_configurable_toolsetsr;   M   s     '((FLLLLLLLL))++,,,,   Ms   /A 
AAreturnc                      	 ddl m} m}  |              d  |            D             S # t          $ r t	                      cY S w xY w)z3Return the set of toolset keys provided by plugins.r   r1   c                     h | ]\  }}}|	S  r?   .0ts_key_s      r:   	<setcomp>z+_get_plugin_toolset_keys.<locals>.<setcomp>b   s    AAA<61aAAA    )r6   r2   r3   r8   setr1   s     r:   _get_plugin_toolset_keysrG   ]   st    LLLLLLLLAA+>+>+@+@AAAA   uus   %( AA)	PLATFORMSc                 4    i | ]\  }}||j         |j        d S )labeldefault_toolsetrJ   )rA   kinfos      r:   
<dictcomp>rO   k   s;       4 0DEE  rE   zText-to-Speechu   🔊zNous Subscriptionsubscriptionz.Managed OpenAI TTS billed to your subscriptionopenaiTr"   VOICE_TOOLS_OPENAI_KEYOPENAI_API_KEY)namebadgetagenv_varstts_providerrequires_nous_authmanaged_nous_featureoverride_env_varszMicrosoft Edge TTSu   ★ recommended · freezGood quality, no API key needededge)rT   rU   rV   rW   rX   z
OpenAI TTSpaidzHigh quality voiceszOpenAI API keyz$https://platform.openai.com/api-keys)keyr   urlzxAI TTSz"Grok voices - requires xAI API keyXAI_API_KEYzxAI API keyzhttps://console.x.ai/xai)rT   rV   rW   rX   
ElevenLabszMost natural voicesELEVENLABS_API_KEYzElevenLabs API keyz+https://elevenlabs.io/app/settings/api-keys
elevenlabszMistral (Voxtral TTS)zMultilingual, native OpusMISTRAL_API_KEYzMistral API keyzhttps://console.mistral.ai/mistralzGoogle Gemini TTSpreviewz,30 prebuilt voices, controllable via promptsGEMINI_API_KEYzGemini API keyz&https://aistudio.google.com/app/apikeygemini)rT   icon	providerszWeb Search & ExtractzSelect Search Provideruc   A free DuckDuckGo search skill is also included — skip this if you don't need a premium provider.u   🔍z-Managed Firecrawl billed to your subscription	firecrawlr   FIRECRAWL_API_KEYFIRECRAWL_API_URL)rT   rU   rV   web_backendrW   rY   rZ   r[   zFirecrawl Cloudu   ★ recommendedz(Full-featured search, extract, and crawlzFirecrawl API keyzhttps://firecrawl.dev)rT   rU   rV   ro   rW   Exaz)Neural search with semantic understandingexaEXA_API_KEYzExa API keyzhttps://exa.aiParallelzAI-powered search and extractparallelPARALLEL_API_KEYzParallel API keyzhttps://parallel.aiTavilyz	free tieru4   Search, extract, and crawl — 1000 free searches/motavilyTAVILY_API_KEYzTavily API keyzhttps://app.tavily.com/homezFirecrawl Self-Hostedu   free · self-hostedz(Run your own Firecrawl instance (Docker)z9Your Firecrawl instance URL (e.g., http://localhost:3002))r^   r   )rT   setup_title
setup_noterj   rk   zImage Generationu   🎨z8Managed FAL image generation billed to your subscriptionr   FAL_KEYfal)rT   rU   rV   rW   rY   rZ   r[   imagegen_backendzFAL.aiz@Pick from flux-2-klein, flux-2-pro, gpt-image, nano-banana, etc.zFAL API keyzhttps://fal.ai/dashboard/keys)rT   rU   rV   rW   r}   zBrowser Automationu   🌐z%Nous Subscription (Browser Use cloud)z/Managed Browser Use billed to your subscriptionzbrowser-user   BROWSER_USE_API_KEYagent_browser)	rT   rU   rV   rW   browser_providerrY   rZ   r[   
post_setupzLocal Browserz$Headless Chromium, no API key neededlocal)rT   rU   rV   rW   r   r   Browserbasez&Cloud browser with stealth and proxiesBROWSERBASE_API_KEYzBrowserbase API keyzhttps://browserbase.comBROWSERBASE_PROJECT_IDzBrowserbase project IDbrowserbasezBrowser Usez#Cloud browser with remote executionzBrowser Use API keyzhttps://browser-use.com	FirecrawlCamofoxu   free · localz)Anti-detection browser (Firefox/Camoufox)CAMOFOX_URLzCamofox server URLzhttp://localhost:9377z)https://github.com/jo-inc/camofox-browser)r^   r   defaultr_   camofoxz
Smart Homeu   🏠zHome AssistantzREST API integration
HASS_TOKENz&Home Assistant Long-Lived Access TokenHASS_URLzHome Assistant URLzhttp://homeassistant.local:8123)r^   r   r   )rT   rV   rW   zRL Trainingu   🧪)      zTinker / AtroposzRL training platformTINKER_API_KEYzTinker API keyz/https://tinker-console.thinkingmachines.ai/keysWANDB_API_KEYzWandB API keyzhttps://wandb.ai/authorizerl_training)rT   rV   rW   r   )rT   rj   requires_pythonrk   )r"   r   r   r   r/   r.   )OPENROUTER_API_KEYzhttps://openrouter.ai/keys)r   r    post_setup_keyc                    ddl }| dv rt          dz  dz  }|                                s|                    d          rt	          d           ddl}|                    g dd	d	t          t                    
          }|j        dk    rt          d           dS ddl
m} t          d |             d           dS |                                st          d           dS dS | dk    r,t          dz  dz  dz  }|                                s|                    d          rjt	          d           ddl}|                    g dd	d	t          t                    
          }|j        dk    rt          d           nt          d           |                                r>t	          d           t	          d           t	          d           t	          d           dS |                    d          s t          d           t	          d           dS dS | dk    rZ	 t          d           dS # t          $ r: t          dz  }|                                r|dz                                  rt	          d            ddl}|                    d!          }|r7|                    |d"d#d$t          j        d%t          |          gd	d	&          }n5|                    t          j        d'd"d#d%t          |          gd	d	&          }|j        dk    rt          d(           Y dS t          d)           t	          d*           Y dS t          d+           t	          d,           t	          d*           Y dS w xY wdS )-zBRun post-setup hooks for tools that need extra installation steps.r   N)r   r   node_moduleszagent-browsernpmz8    Installing Node.js dependencies for browser tools...)r   installz--silentT)capture_outputtextcwdz"    Node.js dependencies installeddisplay_hermes_homez*    npm install failed - run manually: cd z/hermes-agent && npm installzV    Node.js not found - browser tools require: npm install (in hermes-agent directory)r   z@askjozcamofox-browserz(    Installing Camofox browser server...z    Camofox installedz2    npm install failed - run manually: npm installz    Start the Camofox server:z       npx @askjo/camofox-browserz4    First run downloads the Camoufox engine (~300MB)zV    Or use Docker: docker run -p 9377:9377 -e CAMOFOX_PORT=9377 jo-inc/camofox-browserz2    Node.js not found. Install Camofox via Docker:zI      docker run -p 9377:9377 -e CAMOFOX_PORT=9377 jo-inc/camofox-browserr   tinker_atroposztinker-atroposzpyproject.tomlz*    Installing tinker-atropos submodule...uvpipr   z--pythonz-e)r   r   z-mz    tinker-atropos installedz1    tinker-atropos install failed - run manually:z*      uv pip install -e "./tinker-atropos"z-    tinker-atropos submodule not found - run:z-      git submodule update --init --recursive)shutilPROJECT_ROOTexistswhich_print_info
subprocessrunstr
returncode_print_successhermes_constantsr   _print_warning
__import__ImportErrorsys
executable)	r   r   r   r   r9   r   camofox_dir
tinker_diruv_bins	            r:   _run_post_setupr     sY   MMM999#n4F""$$ 	ue)<)< 	uRSSS^^...#$C4E4E $  F  A%%CDDDDD@@@@@@L_L_LaLa  A  A  A  A  A$$&& 	usttttt	u 	u 
9	$	$"^3h>ARR!!## 
	UU(;(; 
	UBCCC^^...#$C4E4E $  F  A%%67777STTT 	e7888:;;;NOOOpqqqqqe$$ 	eOPPPcddddd	e 	e 
=	(	(	J'((((( 	J 	J 	J%(88J  "" J
5E(E'M'M'O'O JHIII!!!!d++ 	'^^	:s~tUXYcUdUde'+$ ,  FF
 (^^uis:W'+$ ,  F $))"#ABBBBBB"#VWWW LMMMMMMNOOOKLLLHIIIIII1	J 
)	(s    H1 1C0M6$M6-M65M6c                  t   dg} t          d          r|                     d           t          d          r|                     d           t          d          r|                     d           t          d          r|                     d	           t          d
          r|                     d           | S )zBReturn platform keys that are configured (have tokens or are CLI).cliTELEGRAM_BOT_TOKENtelegramDISCORD_BOT_TOKENdiscordSLACK_BOT_TOKENslackWHATSAPP_ENABLEDwhatsapp	QQ_APP_IDqqbot)r
   append)enableds    r:   _get_enabled_platformsr     s    gG)** #z"""()) "y!!!&''  w'(( #z"""[!!  wNrE   config	platformsc                 Z    |t                      }i }|D ]}t          | |          ||<   |S )zReturn a summary of enabled toolsets per platform.

    When ``platforms`` is None, this uses ``_get_enabled_platforms`` to
    auto-detect platforms. Tests can pass an explicit list to avoid relying
    on environment variables.
    )r   _get_platform_tools)r   r   summarypkeys       r:   _platform_toolset_summaryr     sC     *,,	#%G : :+FD99NrE   r   c                     | |S t          | t                    r| S t          | t                    r| dk    S t          | t                    r2|                                                                 }|dv rdS |dv rdS |S )z=Parse bool-like config values used by tool/platform settings.Nr   >   1onyestrueT>   0noofffalseF)
isinstanceboolintr   striplower)valuer   lowereds      r:   _parse_enabled_flagr     s    }% % z% ++--%%''00041115NrE   include_default_mcp_serversplatformr   c                x   ddl m} |                     di           }|                    |          }|t          |t                    st
          |         d         }|g}d |D             }d t          D             t          fd|D                       }|rfd	|D             }nt                      }	|D ] }
|		                     ||
                     !t                      }t          D ]J\  }}}t           ||                    }|r*|
                    |	          r|                    |           Kt                      rq|                     d
i           }t          |                    |g                     }D ]5}||v r|                    |           ||vr|                    |           6d t
                                          D             fd|D             }|                     d          pi }d |                                D             }d|v r+t                      }|	                    ||z
  dhz
             n||z  }|	                    ||z
             |r2|sd|v r|	                    |           n+|	                    |           n|	                    |           |S )zBResolve which individual toolset names are enabled for a platform.r   resolve_toolsetplatform_toolsetsNrL   c                 ,    g | ]}t          |          S r?   )r   )rA   tss     r:   
<listcomp>z'_get_platform_tools.<locals>.<listcomp>  s    555SWW555rE   c                     h | ]\  }}}|	S r?   r?   r@   s      r:   rD   z&_get_platform_tools.<locals>.<setcomp>      JJJLFAqJJJrE   c              3       K   | ]}|v V  	d S Nr?   rA   r   configurable_keyss     r:   	<genexpr>z&_get_platform_tools.<locals>.<genexpr>  s)      NN"b$55NNNNNNrE   c                     h | ]}|v |	S r?   r?   r   s     r:   rD   z&_get_platform_tools.<locals>.<setcomp>  s$    RRR2"@Q:Q:QB:Q:Q:QrE   known_plugin_toolsetsc                     h | ]
}|d          S rL   r?   rA   ps     r:   rD   z&_get_platform_tools.<locals>.<setcomp>9      NNNaQ01NNNrE   c                 ,    h | ]}|vr
|vr|v|S r?   r?   )rA   r   r   platform_default_keysplugin_ts_keyss     r:   rD   z&_get_platform_tools.<locals>.<setcomp>:  sH       &&&n$$+++	 	 ,++rE   mcp_serversc                     h | ]N\  }}t          |t                    t          |                    d d          d          ?t	          |          OS )r   Tr   )r   dictr   getr   )rA   rT   
server_cfgs      r:   rD   z&_get_platform_tools.<locals>.<setcomp>G  sg       D*j$''  
y$ ? ?NNN	D		  rE   no_mcp)toolsetsr   r   r   r4   rH   r5   anyrF   updateissubsetaddrG   valuesitems)r   r   r   r   r   toolset_names
default_tshas_explicit_configenabled_toolsetsall_tool_namests_namerB   rC   ts_tools	known_mapknown_for_platformptsexplicit_passthroughr   enabled_mcp_serversexplicit_mcp_serversr   r   r   s                        @@@r:   r   r     s|    )(((((

#6;;%))(33MJ}d$C$Cx():;
# 65}555MJJ4IJJJ NNNNNNNNN -RRRRRRR $ 	< 	<G!!//'":":;;;;551 	- 	-LFAq??62233H -H--n== - $$V,,, .//N 	*JJ6;;	 x!<!<==! 	* 	*Cm## $$S))))... $$S)))
 ON9;K;K;M;MNNN        **]++1rK  + 1 1 3 3   =  "uu 47J JhZ WXXXX36II 47J JKKK" 6 	98}#<#<##$89999##$78888 4555rE   enabled_toolset_keysc                    |                      di            d t          D             t                      }|z  d t                                          D             |                     di                               |g           }t          |t                    sg }fd|D             }t          ||z            | d         |<   |r.|                      di            t          |          | d         |<   t          |            dS )zSave the selected toolset keys for a platform to config.

    Preserves any non-configurable toolset entries (like MCP server names)
    that were already in the config for this platform.
    r   c                     h | ]\  }}}|	S r?   r?   r@   s      r:   rD   z'_save_platform_tools.<locals>.<setcomp>h  r   rE   c                     h | ]
}|d          S r   r?   r   s     r:   rD   z'_save_platform_tools.<locals>.<setcomp>o  r   rE   c                 $    h | ]}|v|v
|S r?   r?   )rA   entryr   r   s     r:   rD   z'_save_platform_tools.<locals>.<setcomp>x  s:       )))e;P.P.P 	.P.P.PrE   r   N)

setdefaultr5   rG   rH   r  r   r   r4   sortedr	   )r   r   r  plugin_keysexisting_toolsetspreserved_entriesr   r   s         @@r:   _save_platform_toolsr  _  sK    )2... KJ4IJJJ*,,K$
 ON9;K;K;M;MNNN 

#6;;??"MM'..     ,   -33GJ[3[,\,\F)  H126664:;4G4G&'1rE   rB   c                 @   |t                      }| dk    r*	 ddlm}  |            \  }}}|duS # t          $ r Y dS w xY w| dv r;t	          |          }|j                            |           }|r|j        s|j        rdS t                              |           }|rLt          ||          D ]9}	|	                    dg           }
|
s dS t          d	 |
D                       r dS :dS t                              | g           }|sdS t          d
 |D                       S )z6Check if a toolset's required API keys are configured.Nr   r   )resolve_vision_provider_clientF>   r"   r   r   r   TrW   c              3   @   K   | ]}t          |d                    V  dS r^   Nr
   )rA   es     r:   r   z$_toolset_has_keys.<locals>.<genexpr>  s.      ==q=5**======rE   c              3   :   K   | ]\  }}t          |          V  d S r   r#  )rA   varrC   s      r:   r   z$_toolset_has_keys.<locals>.<genexpr>  s.      ==fc1}S!!======rE   )r   agent.auxiliary_clientr   r8   r   featuresr   	availablemanaged_by_nousTOOL_CATEGORIES_visible_providersallTOOLSET_ENV_REQUIREMENTS)rB   r   r   	_providerclient_modelr(  featurecatproviderrW   requirementss               r:   _toolset_has_keysr6    s   ~	MMMMMM(F(F(H(H%Ivv%% 	 	 	55	 7771&99#''// 	) 	W-D 	4 

f
%
%C
 *377 	 	H||J33H tt==H===== ttu ,//;;L t========s   0 
>>questionchoicesc                 ,    ddl m}  || |||          S )z?Single-select menu (arrow keys). Delegates to curses_radiolist.r   )curses_radiolist)selectedcancel_returns)hermes_cli.curses_uir:  )r7  r8  r   r:  s       r:   _prompt_choicer>    s/    555555HgPWXXXXrE   _tool_token_cachec                  "   t           t           S 	 ddl} |                     d          }n3# t          $ r& t                              d           i a t           cY S w xY w	 ddl}ddlm} n3# t          $ r& t                              d           i a t           cY S w xY wi }|	                                D ]U}|
                    |          }|r<t          j        d|d          }t          |                    |                    ||<   V|a t           S )	aL  Return estimated token counts per individual tool name.

    Uses tiktoken (cl100k_base) to count tokens in the JSON-serialised
    OpenAI-format tool schema.  Triggers tool discovery on first call,
    then caches the result for the rest of the process.

    Returns an empty dict when tiktoken or the registry is unavailable.
    Nr   cl100k_basez4tiktoken unavailable; skipping tool token estimation)registryz4Tool registry unavailable; skipping token estimationfunction)typerC  )r?  tiktokenget_encodingr8   loggerdebugmodel_toolstools.registryrB  get_all_tool_names
get_schema_jsondumpslenencode)rE  encrI  rB  countsrT   schemar   s           r:   _estimate_tool_tokensrT    sY    $  !##M22 ! ! !KLLL    !
!+++++++ ! ! !KLLL    !
  F++-- 1 1$$T** 	1 ;
GGHHDszz$//00F4Ls!   * -AA
A) )-BBplatform_labelr   c                    ddl m} ddlm t	                      t                      g }D ]j\  }}}d}t          |          s6t                              |          st                              |          rd}|
                    | d| d|            kfdt                    D             }d	}	r"d
 D             dt          dt          ffd}	 |d|  ||||	          }
fd|
D             S )zIMulti-select checklist of toolsets. Returns set of selected toolset keys.r   curses_checklistr    z  [no API key]  ()c                 *    h | ]\  }\  }}}|v |S r?   r?   )rA   irB   rC   r   s       r:   rD   z,_prompt_toolset_checklist.<locals>.<setcomp>  s8       a&!QW 	
rE   Nc                     g | ]\  }}}|	S r?   r?   r@   s      r:   r   z-_prompt_toolset_checklist.<locals>.<listcomp>   s    888lfa6888rE   chosenr<   c                     t                      }| D ]&}|                     |                              't          fd|D                       }|dk    r
d|dz  ddS d| dS )Nc              3   D   K   | ]}                     |d           V  dS )r   Nr   )rA   rT   tool_tokenss     r:   r   z?_prompt_toolset_checklist.<locals>.status_fn.<locals>.<genexpr>  s1      GGTa00GGGGGGrE   i  zEst. tool context: ~z.1fzk tokensz tokens)rF   r  sum)r_  	all_toolsidxtotalr   rc  ts_keyss       r:   	status_fnz,_prompt_toolset_checklist.<locals>.status_fn  s     UUI @ @  !>!>????GGGGYGGGGGE}}HedlHHHHH8%8888rE   z
Tools for )r<  ri  c                 ,    h | ]}|         d          S r   r?   )rA   r]  	effectives     r:   rD   z,_prompt_toolset_checklist.<locals>.<setcomp>  s!    ,,,IaLO,,,rE   )r=  rX  r   r   rT  r;   r6  r+  r   r.  r   	enumeraterF   r   )rU  r   rX  labelsrB   ts_labelts_descsuffixpre_selectedri  r_  rl  r   rc  rh  s    `         @@@@r:   _prompt_toolset_checklistrs    s   555555(((((( ())K466IF%. : :!' (( 	&o.A.A&.I.I 	&MeMiMijpMqMq 	&%F88g88889999   #,Y#7#7  L I 988i888	9c 	9c 	9 	9 	9 	9 	9 	9 	9 	9 %^%%#  F -,,,V,,,,rE   c                     t                               |           }|rt          | ||           dS t          |            dS )zConfigure a toolset - provider selection + API keys.
    
    Uses TOOL_CATEGORIES for provider-aware config, falls back to simple
    env var prompts for toolsets not in TOOL_CATEGORIES.
    N)r+  r   _configure_tool_category_configure_simple_requirements)rB   r   r3  s      r:   _configure_toolsetrw    sM     

f
%
%C
 / f55555 	'v.....rE   r3  c                    t          |          }g }|                     dg           D ]X}|                    d          rt                      s&|                    d          r|j        sC|                    |           Y|S )zBReturn provider entries visible for the current auth/config state.rk   rZ   rY   )r   r   r   nous_auth_presentr   )r3  r   r(  visibler4  s        r:   r,  r,  '  s    -f55HGGGK,, ! !<<.// 	8R8T8T 	<<,-- 	h6P 	x    NrE   c                    t                               |           }|st          | |           S | dk    r0|                    di           }t          |t                     pd|vS | dk    r0|                    di           }t          |t                     pd|vS | dk    r0|                    di           }t          |t                     pd|vS | dk    rt          d           S t          | |           S )	zBReturn True when enabling this toolset should open provider setup.r"   r4  r   backendr   cloud_providerr   r{   )r+  r   r6  r   r   r
   )rB   r   r3  tts_cfgweb_cfgbrowser_cfgs         r:   #_toolset_needs_configuration_promptr  4  s   


f
%
%C 5$VV4444**UB''gt,,,I
'0II**UB''gt,,,H	0HHjjB//k4000W4DK4WW ++++ 0000rE   c                    |                     dd          }|d         }t          ||          }|                     d          r|d         }t          j        |k     rht	                       t          d| d|d          d|d	          d
t          j        j         dt          j        j         d           t          d           dS t          |          d	k    r|d         }t	                       t	          t          d| d| d|d          dt          j                             |                     d          rt          d|d                     |                     d          rt          d|d                     t          ||           dS t	                       |                     dd          }t	          t          d| d| d| dt          j                             |                     d          rt          d|d                     t	                       g }	|D ]}
|
                     d          rd|
d          dnd}|
                     d          rd|
d          nd}d}|
                     dg           }|rt          d |D                       rt          |
|          rd}n|sd}nd}|	                    |
d          | | |            |	                    d            t#          ||          }t%          d| d!|	|          }|t          |          k    rt          d"|            dS t          ||         |           dS )#z2Configure a tool category with provider selection.rj   rY  rT   r     z requires Python r   .   z+ (current: r[  z3  Upgrade Python and reinstall to enable this tool.N  ---   () ---rV   rz   ry   zChoose a providerz - z ---rU    []    — rW   c              3   @   K   | ]}t          |d                    V  dS r"  r#  rA   vs     r:   r   z+_configure_tool_category.<locals>.<genexpr>t  .      "M"Mq=5#:#:"M"M"M"M"M"MrE   	 [active] [configured]u(   Skip — keep defaults / configure later:z
  Skipped )r   r,  r   version_infoprint_print_errormajorminorr   rO  r   r   CYAN_configure_providerr-  _is_provider_activer   _detect_active_provider_indexr>  )rB   r3  r   rj   rT   rk   reqr4  titleprovider_choicesr   rU   rV   
configuredrW   default_idxprovider_idxs                    r:   ru  ru  I  s   7762Dv;D"3//I ww !! #$c!!GGG  Ed  E  ESV  E  Ec!f  E  ERURbRh  E  Eknk{  lB  E  E  E  F  F  FMNNNF
9~~Q<eCTCCDCCHV,<CCCV[QQRRR<< 	0.Xe_..///77<   	20S.00111Hf----- 	':;;e8T88D88U888&+FFGGG77<   	20S.00111  	L 	LA*+%%..@&7&&&&bE()e<$!E($$$"CJuuZ,,H 1s"M"MH"M"M"MMM 1&q&11 1!,JJ! 1!#JJ!0J##qy$J%$J$Jj$J$JKKKK 	 JKKK 4IvFF%m5mmm5E{SS 3y>>))+T++,,,FIl3V<<<<<rE   r4  c                    |                      d          }|r!t          |          }|j                             |          }|dS |dk    r|j        S |                      d          r:|j        o2|                     di                                d          | d         k    S d| v r<|                     d	i                                d
          }|j        o| d         |k    S |                      d          r<|                     di                                d          }|j        o|| d         k    S |j        S |                      d          r3|                     di                                d          | d         k    S d| v r5|                     d	i                                d
          }| d         |k    S |                      d          r5|                     di                                d          }|| d         k    S dS )z>Check if a provider entry matches the currently active config.rZ   NFr   rX   r"   r4  r   r   r}  ro   r   r|  )r   r   r(  r*  )r4  r   managed_featurer(  r2  currents         r:   r  r    s   ll#9::O '1&99#''88?5k))**<<'' 	' VJJub))--j99Xn=UU ))jjB//334DEEG*Vx8J/Kw/VV<<&& 	Rjj++//	::G*Qw(=:Q/QQ&&||N## Qzz%$$((448PPPX%%**Y++//0@AA*+w66||M"" 2**UB''++I66(=1115rE   rk   c                     t          |           D ]N\  }}t          ||          r|c S |                    dg           }|rt          d |D                       r|c S OdS )z8Return the index of the currently active provider, or 0.rW   c              3   @   K   | ]}t          |d                    V  dS r"  r#  r  s     r:   r   z0_detect_active_provider_index.<locals>.<genexpr>  s.      FFM!E(33FFFFFFrE   r   )rm  r  r   r-  )rk   r   r]  r   rW   s        r:   r  r    s    )$$  1q&)) 	HHH55R(( 	FFXFFFFF 	HHH1rE   c                      ddl m} m} | |fS )z5Lazy-load the FAL model catalog from the tool module.r   
FAL_MODELSDEFAULT_MODEL)tools.image_generation_toolr  r  r  s     r:   _fal_model_catalogr    s%    EEEEEEEE}$$rE   )display
config_key
catalog_fnmodel_idmetawidthsc           
          | d|d          d|                     dd          d|d          d|                     dd          d|d          d|                     dd           S )zIFormat a single picker row with column-aligned speed / strengths / price.<modelr  speedrY  	strengthspricerb  )r  r  r  s      r:   _format_imagegen_model_rowr    s      	#fWo 	#* 	# 	#88GR  	##)'?	#7	# 	#88K$$	#'-k':	#?	# 	# 88GR  	# 	#rE   backend_namec           	         t                               |           }|sdS  |d                     \  }sdS |d         }|                    |i           }t          |t                    si }|||<   |                    d          p|vr|t                                                    }gfd|D             z   }t          d |D                       t          fd|D             d	          t          fd
|D             d	          d}t                       ddd|d          ddd|d          ddd|d          d}	t          t          |	t          j                             g }
|D ]9}t          ||         |          }|k    r|dz  }|
                    |           :t          d|d          d|
d	          }||         }||d<   t          d|            dS )u   Prompt the user to pick a model for the given imagegen backend.

    Writes selection to ``config[backend_config_key]["model"]``. Safe to
    call even when stdin is not a TTY — curses_radiolist falls back to
    keeping the current selection.
    Nr  r  r  c                      g | ]
}|k    |S r?   r?   )rA   mcurrent_models     r:   r   z-_configure_imagegen_model.<locals>.<listcomp>  s#     L L Lqm9K9K9K9K9KrE   c              3   4   K   | ]}t          |          V  d S r   rO  )rA   r  s     r:   r   z,_configure_imagegen_model.<locals>.<genexpr>  s(      //SVV//////rE   c              3   j   K   | ]-}t          |                             d d                    V  .dS )r  rY  NrO  r   rA   r  catalogs     r:   r   z,_configure_imagegen_model.<locals>.<genexpr>   s=      JJ1c'!*.."5566JJJJJJrE      r   c              3   j   K   | ]-}t          |                             d d                    V  .dS )r  rY  Nr  r  s     r:   r   z,_configure_imagegen_model.<locals>.<genexpr>  s=      RR1#gajnn["==>>RRRRRRrE   r   )r  r  r  r  Modelr  Speedr  	Strengthsr  z  Priceu     ← currently in usez	  Choose r  z model:z  Model set to: )IMAGEGEN_BACKENDSr   r  r   r   r4   keysmaxr  r   r   r  r  r   r>  r   )r  r   r|  default_modelcfg_keycur_cfg	model_idsorderedr  headerrowsmidrowrf  r_  r  r  s                  @@r:   _configure_imagegen_modelr    s     ##L11G 2W\244G] l#G,,Ggt$$ "!wKK((9MMG##%W\\^^$$Io L L L LI L L LLG //Y/////JJJJ	JJJTUVVVRRRR	RRR\]^^^ F 
GGG	W 	vg 	+ 	 		G_	)	 		,	1	 	 	  
%
$
$%%%D  (gclFCC-++CC
/GI&///  C S\FGG.f../////rE   c           	      6   |                      dg           }|                      d          }|                      d          r't          |          }|j        st          d           dS |                      d          r3|                    di           }| d         |d<   t          |          |d	<   d
| v rd| d
         }|                    di           }|dk    rd|d<   t          d           n|r||d<   t          d|            t          |          |d	<   |                      d          rK|                    di           }| d         |d<   t          |          |d	<   t          d| d                     |r|dvrd|                    |i           d	<   n|s}t                                          D ]c\  }	}
| |
                     dg           v rF|                     |	          }t          |t                    r|                     d	          rd|d	<    nd|s}|                      d          rt          | d                    t          d| d          d           |rt          d           |                      d          }|rt          ||           dS d}|D ]}t          |d                   }|rt          d|d          d           4|                     d d!          }|rt          d"|            |                     d#d!          }|r.t          d$|                     d%|d                    |          }n.t          d$|                     d%|d                    d&          }|r&t!          |d         |           t          d'           t          d(           d}|                      d          r|rt          | d                    |rBt          d| d          d)           |                      d          }|rt          ||           dS dS dS )*zAConfigure a single provider - prompt for API keys and set config.rW   rZ   rY   E  Nous Subscription is only available after logging into Nous Portal.NrX   r"   r4  use_gatewayr   r   r   r}    Browser set to local mode!  Browser cloud provider set to: ro   r   r|    Web backend set to: )r   r"   r   Trk   Fr   r  rT    - no configuration needed!B  Requests for this tool will be billed to your Nous subscription.r}   r^   z: already configuredr_   rY    Get yours at: r       r   password	    Saved    Skippedz configured!)r   r   ry  r   r  r   r   r+  r  r   r   r   r   r  r
   _promptr   )r4  r   rW   r  r(  r~  bpr  r  cat_keyr3  sectionr|  all_configuredr&  existingr_   default_valr   s                      r:   r  r    s   ||J++Hll#9::O||()) 1&99) 	bcccF ||N## 7##E2..&~6
!%o!6!6 X%%()''	266==,3K()89999 	E,.K()CrCCDDD%)/%:%:M" ||M"" K##E2..%m4	!%o!6!6I0GIIJJJ  
?2KKK@D/2..}==  ,1133 	 	LGS377;3333 **W--gt,, 3]1K1K 3-2GM*	 4  
<<%% 	4H\2333IHV,IIIJJJ 	^\]]],,122 	7%gv666 N ' ' U,, 	'@E
@@@AAAA ''%$$C 64s44555'')R00K W FswwxU'D'D F FTT FswwxU'D'D F FQUVVV 's5z5111{++++}---!& ||L!! 0n 0./// 7:HV,:::;;;,,122 	7%gv666667 7	7 	7rE   c                 :     dk    rt          d          rdS t                       t          t          dt          j                             g d}t          d|d          }|dk    rzt          d           t          d	d
          }|rG|                                r3t          d|                                           t          d           n/t          d           n|dk    rt          d                                          pd}d|                                v rdnd}t          |d
          }|r|                                rt          d|                                           ddlm}m}  |            }	|	                    di                               di           }
||
d<    ||	           d|                                v rt          dd           t          d           nt          d           dS t"                               g           }|sdS d |D             }|sdS t'           fdt)                      D                        }t                       t          t          d| dt          j                             |D ]\  }}|rt          d|            t          d | d
          }|rF|                                r2t          ||                                           t          d           ut          d           dS )!zMSimple fallback for toolsets that just need env vars (no provider selection).r   Nz8  Vision / Image Analysis requires a multimodal backend:)u   OpenRouter — uses GeminiuB   OpenAI-compatible endpoint — base URL, API key, and vision modelSkipz  Configure vision backend   r   z(  Get key at: https://openrouter.ai/keysz    OPENROUTER_API_KEYTr  r   r  r  r  z&    OPENAI_BASE_URL (blank for OpenAI)zhttps://api.openai.com/v1zapi.openai.comz    OPENAI_API_KEYz    API keyrS   )r   r	   	auxiliarybase_urlAUXILIARY_VISION_MODELzgpt-4o-minic                 :    g | ]\  }}t          |          ||fS r?   r#  )rA   r&  r_   s      r:   r   z2_configure_simple_requirements.<locals>.<listcomp>  s-    QQQhc3mC>P>PQSzQQQrE   c              3   0   K   | ]\  }}}|k    |V  d S r   r?   rA   rM   lrC   rB   s       r:   r   z1_configure_simple_requirements.<locals>.<genexpr>  5      \\71aPQU[P[P[QP[P[P[P[\\rE   r  z requires configuration:  Get key at: r  )r6  r  r   r   YELLOWr>  r   r  r   r   r   r   r   hermes_cli.configr   r	   r  r.  r   nextr;   )rB   r8  rf  r   r  	key_labelapi_keyr   r	   _cfg_auxr5  missingro  r&  r_   s   `               r:   rv  rv    sb   X&& 	FeNPVP]^^___
 
 

 97AFF!88BCCC4tDDDE . .3U[[]]CCC{++++}----AXXGHHNNPPoToH0@HNNDTDT0T0T,,ZgIi$777G .7==?? ./AAAFFFFFFFF"{}}{B77BB8RPP#+Z D!!!#x~~'7'777"#;]KKK{++++}---+//;;L QQ,QQQG \\\\&J&L&L\\\^deeH	GGG	%7X777
G
GHHH * *S 	0...///st444 	*U[[]] 	*3...;''''=))))* *rE   c                 t   g }t                      D ]e\  }}}t                              |          }t                              |          }|s|r't	          ||           r|                    ||f           f|st          d           dS d |D             }|                    d           t          d|t          |          dz
            }|t          |          k    rdS ||         \  }}t                              |          }|rt          |||            nt          |           t          |            dS )z<Let user reconfigure an existing tool's provider or API key.z#No configured tools to reconfigure.Nc                     g | ]\  }}|S r?   r?   )rA   rC   rK   s      r:   r   z%_reconfigure_tool.<locals>.<listcomp>  s    222Eu222rE   Cancelz+  Which tool would you like to reconfigure?r  )r;   r+  r   r.  r6  r   r   r>  rO  %_configure_tool_category_for_reconfig _reconfigure_simple_requirementsr	   )	r   configurablerB   ro  rC   r3  reqsr8  rf  s	            r:   _reconfigure_toolr    sb    LCEE 8 8!!!&))'++F33 	8$ 	8 00 8##VX$6777 9:::22\222GNN8
FQTU\Q]Q]`aQa
b
bC
c,#C(FH


f
%
%C
 1-fc6BBBB(000rE   c                    |                     dd          }|d         }t          ||          }t          |          dk    r_|d         }t                       t          t	          d| d| d|d          d	t
          j                             t          ||           dS t                       t          t	          d| d| d
t
          j                             t                       g }|D ]}|                     d          rd|d          dnd}	|                     d          rd|d          nd}
d}|                     dg           }|rt          d |D                       rt          ||          rd}n|sd}nd}|
                    |d          |	 |
 |            t          ||          }t          d||          }t          ||         |           dS )zBReconfigure a tool category - provider selection + API key update.rj   rY  rT   r  r   r  r  r  r  z - Choose a provider ---rU   r  r  rV   r  rW   c              3   @   K   | ]}t          |d                    V  dS r"  r#  r  s     r:   r   z8_configure_tool_category_for_reconfig.<locals>.<genexpr>  r  rE   r  r  z  Select provider:N)r   r,  rO  r  r   r   r  _reconfigure_providerr-  r  r   r  r>  )rB   r3  r   rj   rT   rk   r4  r  r   rU   rV   r  rW   r  r  s                  r:   r  r    s   7762Dv;D"3//I
9~~Q<eCTCCDCCHV,<CCCV[QQRRRh/////eBTBBDBBBFKPPQQQ 	L 	LA*+%%..@&7&&&&bE()e<$!E($$$"CJuuZ,,H 1s"M"MH"M"M"MMM 1&q&11 1!,JJ! 1!#JJ!0J##qy$J%$J$Jj$J$JKKKK3IvFF%&:<LkZZi5v>>>>>rE   c           	      B   |                      dg           }|                      d          }|                      d          r't          |          }|j        st          d           dS |                      d          r7| d         |                    di           d<   t          d	| d                     d
| v rd| d
         }|dk    r)d|                    di           d<   t          d           n-|r+||                    di           d<   t          d|            |                      d          r7| d         |                    di           d<   t          d| d                     |s}|                      d          rt          | d                    t          d| d          d           |rt          d           |                      d          }|rt          ||           dS |D ]}t          |d                   }|r$t          d|d          d|dd          d           |                     dd          }	|	rt          d |	            |                     d!d          }
t          d"|                     d#|d                    d$|
 %          }|rL|                                r8t          |d         |                                           t          d&           t          d'           |                      d          }|rt          ||           dS dS )(z)Reconfigure a provider - update API keys.rW   rZ   rY   r  NrX   r"   r4  z  TTS provider set to: r   r   r   r}  r  r  ro   r   r|  r  r   r  rT   r  r  r}   r^   : configured (   ...)r_   rY  r  r   r  r    (Enter to keep current)r      Updated    Kept current)r   r   ry  r   r  r   r   r   r  r
   r  r   r   )r4  r   rW   r  r(  r  r|  r&  r  r_   r  r   s               r:   r  r  	  s   ||J++Hll#9::O||()) 1&99) 	bcccF||N## M3;N3K%$$Z0K.1IKKLLLX%%()==AHFi,,-=>89999 	EACFi,,-=>CrCCDDD ||M"" K2:=2I%$$Y/I0GIIJJJ 
<<%% 	4H\2333IHV,IIIJJJ 	^\]]],,122 	7%gv666 , , U,, 	KISZIIx|IIIJJJggeR   	20300111ggi,,VswwxU<<VVVepapqqq 	,U[[]] 	,3u:u{{}}555=))))*++++ ll-..G 3!'6222223 3rE   c           	      v    t                                g           }|sdS t           fdt                      D                        }t	                       t	          t          d| dt          j                             |D ]\  }}t          |          }|rt          d| d|dd          d           |rt          d|            t          d	| d
d          }|rF|                                r2t          ||                                           t          d           t          d           dS )z(Reconfigure simple env var requirements.Nc              3   0   K   | ]\  }}}|k    |V  d S r   r?   r  s       r:   r   z3_reconfigure_simple_requirements.<locals>.<genexpr>M  r  rE   r  r  r  r  r  r  r  r  Tr  r  r  )r.  r   r  r;   r  r   r   r  r
   r   r  r   r   r   )rB   r5  ro  r&  r_   r  r   s   `      r:   r  r  G  sl   +//;;L \\\\&J&L&L\\\^deeH	GGG	% X   &+
.
.///  , ,S %% 	DBSBB!BBBCCC 	0...///<s<<<tLLL 	,U[[]] 	,3...=))))*++++, ,rE   Ffirst_installc                 *  !"# |t                      }t                      }t                       t          | dd          rt	          t                                }t          t          dt          j        t          j	                             t                       t          ||          }|D ]!}t          |         }|                    |t                                }t	          |          }	t          t          d|d          t          j	                  t          d|	 d| d	t          j                  z              |ret          |          D ]T#t!          #fd
t                      D             #          }
t          t          d|
 t          j                             Ut          t          dt          j                             #t                       dS t          t          dt          j        t          j	                             t          t          dt          j                             t          t          dt          j                             t          t          dt          j                             t                       |r|D ]}t          |         }t%          ||d          }|t&          z
  }t)          |d         |          }||z
  }||z
  }|rdt          |          D ]T"t!          "fdt                      D             "          }
t          t          d|
 t          j                             U|rdt          |          D ]T"t!          "fdt                      D             "          }
t          t          d|
 t          j                             Ut-          ||          !t/                      r^t          !          D ]N#t!          #fdt0          D             #          }
t          t          d|
 dt          j                             O!fdt          |          D             }|rt                       t          t          dt	          |           dt          j                             |D ]T#t!          #fdt                      D             #          }
t          t          d|
 t          j                             Ut          t          dt          j                             t                       |D ]#t5          #|           t7          |||           t9          |           t          t          d |d          d!t          j                             t                       dS g }g }|D ]}t          |         }t%          ||d          }t	          |          }	t	          t                                }|                    d"|d          d|	 d| d#           |                    |           t	          |          d$k    r|                    d%           |                    d&           t=          |                    d'                    }|r|                    d(           |                    d)           t	          |          d$k    rt	          |          nd*}t	          |          t	          |          d$k    rd$nd+z   }|r|d$z   nd*}||rd,nd$z   }	 t?          d.|d+/          }||k    rnp||k    rtA          |           t                       ?||k    rtC          |           t                       c||k    rt                      }|D ]}|t%          ||d          z  }t)          d0|          }||k    rJ|D ]}t%          ||d          }||z
  }||z
  }t          |         }|s|rt          t          d|d          d1t          j                             t          |          D ]T"t!          "fd2t                      D             "          }
t          t          d3|
 t          j                             Ut          |          D ]T"t!          "fd4t                      D             "          }
t          t          d5|
 t          j                             Ut          |          D ]V#tD                              #          stF                              #          r tI          #|          rt5          #|           Wt7          |||           t9          |           t          t          d6t          j                             tK          |          D ]_\  }}t	          t%          ||d                    }t	          t                                }d"t          |         d          d| d| d#||<   `n't          t          d7t          j                             t                       *||         }t          |         }t%          ||d          }t)          |d         |          }||k    r||z
  }||z
  }|rdt          |          D ]T"t!          "fd8t                      D             "          }
t          t          d|
 t          j                             U|rdt          |          D ]T"t!          "fd9t                      D             "          }
t          t          d|
 t          j                             Ut          |          D ]V#tD                              #          stF                              #          r tI          #|          rt5          #|           Wt7          |||           t9          |           t          t          d |d          d:t          j                             n0t          t          d;|d          t          j                             t                       t	          t%          ||d                    }t	          t                                }d"|d          d| d| d#||<   t                       d+d<l&m'}  t          t          d= |              d>t          j                             t          t          d?t          j                             t                       dS )@a	  Entry point for `hermes tools` and `hermes setup tools`.

    Args:
        first_install: When True (set by the setup wizard on fresh installs),
            skip the platform menu, go straight to the CLI checklist, and
            prompt for API keys on all enabled tools that need them.
        config: Optional config dict to use.  When called from the setup
            wizard, the wizard passes its own dict so that platform_toolsets
            are written into it and survive the wizard's final save_config().
    Nr   Fu   ⚕ Tool Summaryr  rK   rZ  /r[  c              3   0   K   | ]\  }}}|k    |V  d S r   r?   r  s       r:   r   z tools_command.<locals>.<genexpr>  5      !i!i1a]^bh]h]h!]h]h]h]h!i!irE   u       ✓ z    (none enabled)u   ⚕ Hermes Tool Configurationz'  Enable or disable tools per platform.z;  Tools that need API keys will be configured when enabled.zM  Guide: https://hermes-agent.nousresearch.com/docs/user-guide/features/toolsr   c              3   0   K   | ]\  }}}|k    |V  d S r   r?   rA   rM   r  rC   r   s       r:   r   z tools_command.<locals>.<genexpr>  5      !e!e1a]^bd]d]d!]d]d]d]d!e!erE   z  + c              3   0   K   | ]\  }}}|k    |V  d S r   r?   r  s       r:   r   z tools_command.<locals>.<genexpr>  r  rE   z  - )r	  c              3   0   K   | ]\  }}}|k    |V  d S r   r?   r  s       r:   r   z tools_command.<locals>.<genexpr>  s.      !X!X1aAQWKK!KKKK!X!XrE   u     ✓ z': using your Nous subscription defaultsc                     g | ]<}t                               |          st                              |          r|v:|=S r?   )r+  r   r.  )rA   rB   auto_configureds     r:   r   z!tools_command.<locals>.<listcomp>  s]       !#''//3K3O3OPV3W3W /11 111rE   z  Configuring z	 tool(s):c              3   0   K   | ]\  }}}|k    |V  d S r   r?   r  s       r:   r   z tools_command.<locals>.<genexpr>  r  rE   u       • z1  You can skip any tool you don't need right now.u     ✓ Saved z tool configurationz
Configure z	 enabled)r  z Configure all platforms (global)z2Reconfigure an existing tool's provider or API keyr   zConfigure MCP server toolsDoner   r  TzSelect an option:r   zAll platformsr  c              3   0   K   | ]\  }}}|k    |V  d S r   r?   r  s       r:   r   z tools_command.<locals>.<genexpr>  5      )m)m1aefjlelel!elelelel)m)mrE   z    + c              3   0   K   | ]\  }}}|k    |V  d S r   r?   r  s       r:   r   z tools_command.<locals>.<genexpr>
  r%  rE   z    - u+     ✓ Saved configuration for all platformsz  No changesc              3   0   K   | ]\  }}}|k    |V  d S r   r?   r  s       r:   r   z tools_command.<locals>.<genexpr>-  r  rE   c              3   0   K   | ]\  }}}|k    |V  d S r   r?   r  s       r:   r   z tools_command.<locals>.<genexpr>1  r  rE   z configurationz  No changes to r   z  Tool configuration saved to z/config.yamlz:  Changes take effect on next 'hermes' or gateway restart.)(r   r   r  getattrrO  r;   r   r   r  BOLDr   rH   r   rF   DIMr  r  GREENr   _DEFAULT_OFF_TOOLSETSrs  REDr   r   r5   r  rw  r  r	   r   r   r>  r   _configure_mcp_tools_interactiver+  r.  r  rm  r   r   )$argsr  r   enabled_platformsrg  r   r   pinfor   countrK   current_enabledchecklist_preselectednew_enabledaddedremovedto_configureplatform_choicesplatform_keysr  _has_mcp_global_idx_reconfig_idx_mcp_idx	_done_idxrf  all_currentpkprevpinfo_innerci	new_countr   r   r   rB   s$                                    @@@r:   tools_commandrG  a  s    ~.00	GGG tY&& 8::;;e&V[AABBB+F4EFF% 
	? 
	?DdOEkk$..GLLE%-U7^--v{;;eDZ%DZDZRWDZDZDZ\b\f>g>gghhh ?$Woo C CF !i!i!i!i3W3Y3Y!i!i!ikqrrE% 25 2 2FLAABBBBC e0&*==>>>>	%/fk
J
JKKK	%96:
F
FGGG	%Mvz
Z
Z[[[	%_agak
l
lmmm	GGG  9% 6	 6	DdOE1&$\abbbO %46K$K! 4E'NDYZZK/1E%3G ? -- ? ?B !e!e!e!e3W3Y3Y!e!e!egijjE%u==>>>> = // = =B !e!e!e!e3W3Y3Y!e!e!egijjE%u
;;<<<<9!,  O *++ h$_55 h hF !X!X!X!X3H!X!X!XZ`aaE% W W W WY_Yeffgggg   %+K%8%8  L  	7eIS->->III6=YYZZZ* A AF !i!i!i!i3W3Y3Y!i!i!ikqrrE% 25 2 2FJ??@@@@eOQWQ[\\]]]* 7 7F&vv6666 {;;;%JuW~JJJFLYYZZZGGGG M! # #$%fdPUVVVG8::;; XU7^ X X X X X X XYYYT""""
=A BCCCPQQQ FJJ}--..H > <===F### ),M(:(:Q(>(>#m$$$BK&&s=/A/AA/E/E!!1MM&.6!!BHh!5A6Ia]02BANNN ) -f%%%GGG (??,V444GGG +%%K# b b262[`aaaa3O[QQKk))' B BB.vrW\]]]D'$.E"[0G"+B-K G Ge$@W)=$@$@$@&*MMNNN"(-- I IB$()m)m)m)m;_;a;a)m)m)moq$r$rE!%(8(8(8&,"G"GHHHH"(// G GB$()m)m)m)m;_;a;a)m)m)moq$r$rE!%(8(8(8&*"E"EFFFF"(-- C C+//77 C;S;W;WX^;_;_ CB66RR C 266 B B B([AAAAF###eI6<XXYYY'66 p pFB #$7`e$f$f$f g gI D F FGGE+o	"g8N+o+oS\+o+o_d+o+o+o$R((p
 eNFJ77888GGGS!$ .fdX]^^^ 0gPP/))/1E%3G ? -- ? ?B !e!e!e!e3W3Y3Y!e!e!egijjE%u==>>>> = // = =B !e!e!e!e3W3Y3Y!e!e!egijjE%u
;;<<<< !-- ; ;#''// ;3K3O3OPV3W3W ;:66JJ ;*66::: {;;;%EuW~EEEv|TTUUUU%;5>;;VZHHIII +FDV[\\\]]	8::;; \U7^ \ \	 \ \E \ \ \Ca]F 
GGG444444	%T1D1D1F1FTTTV\V`
a
abbb	%Lfj
Y
YZZZ	GGGGGrE   c           
      	   ddl m} |                     d          pi }|st          d           dS d |                                D             }|st          d           dS t                       t          t          dt          j                             t          t          d	t          |           d
d
                    |           t          j                             	 ddlm}  |            n*# t          $ r}t          d|            Y d}~dS d}~ww xY ws t!          d           t          d           dS fd|D             }|r|D ]}t!          d| d           t#          d                                 D                       }t          t          d| dt                     dt          j                             t                       d}	                                D ]k\  }
}|st          d|
 d           |                    |
i           }|                    d          pi }|                    d          pg }|                    d          pg }g }|D ]Z\  }}t          |          dk    r|dd         dz   n|}|r|                    | d| d            E|                    |           [t+                      }d! |D             t-                    D ]R\  }}|r||v r|                    |           !|r||vr|                    |           =|                    |           S |d"|
 dt          |           d#|||$          |k    rt          d|
 d%           fd&t1          t                              D             }|                    |
i           }|                    di           }|r||d<   |                    dd           n,|                    dd           |                    dd           t                    }t          |          |z
  }t7          d|
 d'| d(| d)           d*}	m|	rFt9          |            t                       t          t          d+t          j                             dS t          t          d,t          j                             dS )-zProbe MCP servers for available tools and let user toggle them on/off.

    Connects to each configured MCP server, discovers tools, then shows
    a per-server curses checklist.  Writes changes back as ``tools.exclude``
    entries in config.yaml.
    r   rW  r   zNo MCP servers configured.Nc                 H    g | ]\  }}|                     d d          dv| S )r   T)Fr   r   r   r   rb  )rA   rM   r  s      r:   r   z4_configure_mcp_tools_interactive.<locals>.<listcomp>`  s@       a55D!!)KKK 	
KKKrE   zAll MCP servers are disabled.z'  Discovering tools from MCP servers...z  Connecting to z server(s): , )probe_mcp_server_toolszFailed to probe MCP servers: z-Could not discover tools from any MCP server.zKCheck that server commands/URLs are correct and dependencies are installed.c                     g | ]}|v|	S r?   r?   )rA   nserver_toolss     r:   r   z4_configure_mcp_tools_interactive.<locals>.<listcomp>y  s#    @@@A!<*?*?a*?*?*?rE   z  Could not connect to ''c              3   4   K   | ]}t          |          V  d S r   r  )rA   toolss     r:   r   z3_configure_mcp_tools_interactive.<locals>.<genexpr>~  s(      DDUc%jjDDDDDDrE   z  Found z tool(s) across z
 server(s)Fr  z: no tools foundrQ  includeexcludeF   z...rZ  r[  c                     g | ]
}|d          S rk  r?   rA   ts     r:   r   z4_configure_mcp_tools_interactive.<locals>.<listcomp>  s    ***qad***rE   zMCP Server: z tools))r<  z: no changesc                 (    g | ]}|v|         S r?   r?   )rA   r]  r_  
tool_namess     r:   r   z4_configure_mcp_tools_interactive.<locals>.<listcomp>  s#    XXXQWz!}rE   : z
 enabled, z	 disabledTu"     ✓ MCP tool configuration savedz  No changes to MCP tools)r=  rX  r   r   r  r  r   r   r  rO  joinr+  tools.mcp_toolrK  r8   r  r   rd  r  r,  r   rF   rm  r  ranger  popr   r	   )r   rX  r   enabled_namesrK  excfailedrT   total_toolsany_changesserver_namerQ  srv_cfg	tools_cfginclude_listexclude_listrn  	tool_namedescription
desc_shortrr  r]  new_excludeenabled_countdisabled_countr_  rN  rY  s                            @@@r:   r/  r/  Q  s    655555**]++1rK 0111 !''))  M  3444	GGG	%96=
I
IJJJ	%]3}#5#5]]499]C[C[]]_e_i
j
jkkk999999--//   :S::;;;  FGGGabbb A@@@@@@F ? 	? 	?D=d===>>>>DDl.A.A.C.CDDDDDK	%U;UUL8I8IUUUW]Wc
d
deee	GGGK*0022 C CU 	:[:::;;;//+r22KK((.B	 }}Y//52 }}Y//52 &+ 	) 	)"I{585E5E5J5JSbS)E11P[J )<<z<<<====i(((( "%**E***
%j11 	$ 	$LAy 
$,, $$Q''' $L00 $$Q'''   ####!!>;>>3u::>>>'	
 
 
 \!!6[666777 YXXXXeC
OO.D.DXXX ((b99&&w33	 	+#.Ii MM)T**** MM)T***MM)T***FUm3RRRRRRRR	
 	
 	
  >Fe8&,GGHHHHHe/<<=====s   (C9 9
D DD r  actionc                     t          | |d          }|dk    r|t          |          z
  }n|t          |          z  }t          | ||           dS )z/Add or remove built-in toolsets for a platform.Fr   disableN)r   rF   r  )r   r   r  ro  r   updateds         r:   _apply_toolset_changers    s`    !&(PUVVVGC...C...733333rE   targetsc                   	 t                      }|                     d          pi }|D ]}|                    dd          \  }	||vr|                    |           5||                             di           }t          |                    d          pg           }|dk    r	|vr|                    	           n	fd|D             }||d<   |S )zAdd or remove specific MCP tools from a server's exclude list.

    Returns the set of server names that were not found in config.
    r   r  r  rQ  rS  rq  c                      g | ]
}|k    |S r?   r?   )rA   rW  ri  s     r:   r   z%_apply_mcp_change.<locals>.<listcomp>  s    <<<QQ)^^q^^^rE   )rF   r   splitr  r  r4   r   )
r   rt  ro  failed_serversr   targetrd  rf  rS  ri  s
            @r:   _apply_mcp_changerz    s    
  #uuN**]++1rK ' '!'c1!5!5Yk)){+++,77DD	y}}Y//5266Y''y)))<<<<'<<<G&	)rE   r   r	  r   c                    t                      }d t          D             t          d| d           |D ]s\  }}}|vr|| v rt          dt          j                  nt          dt          j                  }t          d| d| dt          |t          j                              tfd|D             }|rt                       t          d| d           |D ]m\  }}|| v rt          dt          j                  nt          dt          j                  }t          d| d| dt          |t          j                              n|rt                       t          d	           |                                D ]\  }	}
|
	                    d
          pi }|	                    d          pg }|	                    d          pg }|r)t          |	 dd                    |           d           u|rAt          |	 dt          d                    |          t          j                   d           t          |	 dt          dt          j                              dS dS )zBPrint a summary of enabled/disabled toolsets and MCP tool filters.c                     h | ]\  }}}|	S r?   r?   r@   s      r:   rD   z$_print_tools_list.<locals>.<setcomp>  s    EEE|vq!FEEErE   zBuilt-in toolsets (z):u   ✓ enabledu   ✗ disabledr  c                 (    g | ]\  }}}|v
||fS r?   r?   )rA   rM   r  rC   builtin_keyss       r:   r   z%_print_tools_list.<locals>.<listcomp>  s-    OOOAq,9N9Nq!f9N9N9NrE   zPlugin toolsets (zMCP servers:rQ  rS  rR  z  [include only: rJ  r  z  [excluded: zall tools enabledN)r;   r5   r  r   r   r,  r.  r+  r  r   r   r[  r  )r	  r   r   rl  rB   rK   rC   statusplugin_entriessrv_namere  rf  rS  rR  r~  s                 @r:   _print_tools_listr    s   466IEE/DEEEL	
,
,
,
,---% C Cq%%8>BR8R8R%v|444^VZ88 	A6AAVAAuUFJ'?'?AABBBB POOOIOOON G.(...///+ 	G 	GMFE<BFV<V<VeM6<888 << EvEEEE5
+C+CEEFFFF Un!,!2!2!4!4 		U 		UHgG,,2ImmI..4"GmmI..4"G UxOO$))G:L:LOOOPPPP UxaaeDIIg<N<NPVP]6^6^aaabbbbxSS51Dfj+Q+QSSTTTTU U		U 		UrE   c                 n   | j         }t          | dd          }t                      }|t          vr/t	          d| dd                    t                                dS |dk    r8t          t          ||d	          |                    d
          pi |           dS | j	        }d |D             }d |D             }d t          D             t                      z  fd|D             r&D ]}t	          d| d           fd|D             }|rt          ||||           t                      |r)t          |||          D ]}t	          d| d           t          |           fd|D             }	|	r3|dk    rdnd}
t!          |
 dd                    |	                      dS dS )zEnable, disable, or list tools for a platform.

    Built-in toolsets use plain names (e.g. ``web``, ``memory``).
    MCP tools use ``server:tool`` notation (e.g. ``github:create_issue``).
    r   r   zUnknown platform 'z
'. Valid: rJ  Nr4   Fr   r   c                     g | ]}d |v|	S r  r?   rV  s     r:   r   z0tools_disable_enable_command.<locals>.<listcomp>1  s    :::QS\\q\\\rE   c                     g | ]}d |v |	S r  r?   rV  s     r:   r   z0tools_disable_enable_command.<locals>.<listcomp>2  s    2221rE   c                     h | ]\  }}}|	S r?   r?   r@   s      r:   rD   z/tools_disable_enable_command.<locals>.<setcomp>4  s    GGGAfGGGrE   c                     g | ]}|v|	S r?   r?   rA   rW  valid_toolsetss     r:   r   z0tools_disable_enable_command.<locals>.<listcomp>5  s#    NNNaa~6M6M6M6M6MrE   zUnknown toolset 'rO  c                     g | ]}|v |	S r?   r?   r  s     r:   r   z0tools_disable_enable_command.<locals>.<listcomp>9  s#    MMMn9L9L19L9L9LrE   zMCP server 'z' not found in configc                 ^    g | ])}|vd |vs|                     d           d         v'|*S )r  r   )rw  )rA   rW  rx  unknown_toolsetss     r:   r   z0tools_disable_enable_command.<locals>.<listcomp>F  sP       $$$#Q,,!''#,,q/Q_:_:_ 	
:_:_:_rE   rq  DisabledEnabledrZ  )tools_actionr)  r   rH   r  r[  r  r   r   namesr5   rG   rs  rF   rz  r	   r   )r0  ro  r   r   rt  toolset_targetsmcp_targetsrT   srv
successfulverbrx  r  r  s              @@@r:   tools_disable_enable_commandr    se    FtZ//H]]Fy  T(TTdii	>R>RTTUUU-fh\abbb **]339r8	E 	E 	EG::':::O22g222KGG1FGGGJbJdJddNNNNN?NNN N$ 	6 	6D4T4445555MMMMoMMM IfhHHH"uuN D*6;GG! 	D 	DCBBBBCCCC      J  ;#y00zzi$99$))J"7"799:::::; ;rE   r   )Trk  )NFN)r   )]__doc__jsonrM  loggingr   pathlibr   typingr   r   r   r   r  r   r	   r
   r   hermes_cli.colorsr   r   hermes_cli.nous_subscriptionr   r   tools.tool_backend_helpersr   	getLogger__name__rG  __file__parentresolver   hermes_cli.cli_outputr   r  r   r   r   r   r   r   r   r  r5   r-  r;   rF   rG   hermes_cli.platformsrH   _PLATFORMS_REGISTRYr  r+  r.  r   r   r   r   r   r   r   r   r  r6  r4   r   r>  r?  __annotations__rT  rs  rw  r,  r  ru  r  r  r  r  r  r  r  rv  r  r  r  r  rG  r/  rs  rz  r  r  r?   rE   r:   <module>r     sb  	 	 	      



       , , , , , , , , , , , ,            , + + + + + + +        B A A A A A		8	$	$tH~~$+3355
                2 766    #     B A A A A A ,&,..  	 ! ,'G (&*(-&>@P%Q	 	 -28 &  %,4@PY  A  A !)  ";)]Kbcc !&  %,0<P  ZG  H  H !-  02-9JSpqq !*  ,"E,8HQyzz !) k>
B BH '/{ ,'F*&*(-&9;N%O	 	 **A*/;NWnoo  B$)]K[\\  #6).:LUjkk  !$M',8HQnoo  0.A*/;vww _8
> >@ # ,'Q&*(3&/[$)	 	 !Y%Gfgg %* 
 4 % @'H$1&*(1&;%<-
 
 (2=$+-  &?1=R[tuu4@XYY %2-
 
 &<1=R[tuu %2-	 	 $</;NWnoo %0-	 	 "(B)5IVmGI I %.'
 
g>
B BH  )-(4\]]&2FStuu 	
  " +-,8H  RC  D  D+Okll , 

	 [} }D JJIJ  EJC EJ EJ EJ EJTS	      d xS	7J VZ[^`cdg`h[hVi           * )-	b b bbb "&	b
 	Xb b b bJ' ' 'CPSH ' ' ' 'T#> #>c #>4 #>4 #> #> #> #>PY YS Y4 Y# Yc Y Y Y Y /3 8DcN+ 2 2 2'tCH~ ' ' ' 'T,-c ,-CH ,-S ,- ,- ,- ,-b/s /D / / / /
D 
$ 
4: 
 
 
 
1 1T 1d 1 1 1 1*A=S A=t A=T A= A= A= A=H$      D	T 	4 	C 	 	 	 	2% % % 
!(   D $ 3    ;0C ;0 ;0$ ;0 ;0 ;0 ;0|a7$ a7 a7 a7 a7 a7H<*3 <* <* <* <*~d    D"?# "?D "?$ "? "? "? "?J;3D ;3$ ;3 ;3 ;3 ;3|,S , , , ,4j jD j$ j j j j`}>T }> }> }> }>F4$ 4# 4d3i 4Y\ 4 4 4 4d T#Y  C    2#U #U #U$ #U# #U #U #U #UL/; /; /; /; /;rE   