
    PL
j                    |   U d Z ddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
mZmZmZmZ ddlmZ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mZ dd	lmZm Z   ej!        e"          Z# e	e$          j%        j%        &                                Z'dd
l(m)Z*m+Z,m-Z.m/Z0m1Z2 g dZ3h dZ4de5fdZ6dhdhdZ7ee8ee8         f         e9d<   de8de8de5fdZ:d Z;de<fdZ=ddl>m?Z@ d  e@jA                    D             Z?d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/d0g d1d2d3d4d*d5d6d7d8d.gd9d(d:d;d<d=d>d?d.gd@d(dAdBdCg dDdDdEdFdBdGg dHdHdEgdIdJdKdLdMdddNdOg ddPdQdRgdSdTdUdVdOdRdWdXgdYgdZd[d\ddd]g dd^d_gd`dadbd*dcd_ddded.gd`dfgdIdgdhg dIdidjdkdldmddng d2dodpd*dqdrdpdsd.gdtgdZdudvdwddxg dyddzd{gd|d}	d~d%dg dd|dddddddddgdddgdIdddddddXddddgdgdIddddg ddgdIddddddg ddogdd	ZBdgdgdZCddddee8         deDde5fdZEdde5de5fdZFdde8de5de5fdZGde8fdZHdee8         fdZIddeJdeee8                  dee8ee8         f         fdZKd de5de5fdZLdddeJde8de5dee8         fdZMdeJde8dee8         fdZNdde8deJde5fdZOdde8dePdeDdeDfdĄZQdaReee8eDf                  e9d<   dee8eDf         fdƄZSdde8dee8         de8dee8         fdʄZTde8deJfd˄ZUdePeJ         fd̄ZVdePeJ         fd̈́ZWdePeJ         fd΄ZXdePeJ         fdτZYdeJdeJdePeJ         fdфZZdd҄ iZ[eJe9d<   de8de5fdԄZ\de8deJde5fdՄZ]de8deJdeJfdքZ^deJdeJde5fd؄Z_dePdeJdeDfdڄZ`dۄ Zad`dbd^eadܜiZbde8deJdeJde8fdZcde8deJddfdZdde8fdZede8deJddfdZfde8deJddfdZgde8fdZhde8deJddfdZide8deJddfdZjdeJdeJfdZkde8fdZldeJfdZmde8deJde5fdZnde8deJdeJfdZodeJdeJfdZpde8fdZqdde5deJfdZrdeJfdZsdeJde8dee8         de8fdZtdeJdee8         de8dee8         fdZudde<deJde8fdZvd Zwd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)cfg_getload_configsave_configget_env_valuesave_env_value)Colorscolor)apply_nous_managed_defaultsget_nous_subscription_features)fal_key_is_configuredmanaged_nous_tools_enabled)base_url_hostnameis_truthy_value)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)videou   🎬 Video Analysisz,video_analyze (requires video-capable model))	image_genu   🎨 Image Generationimage_generate)	video_genu   🎬 Video Generationz/video_generate (text-to-video + image-to-video))x_searchu   🐦 X (Twitter) Searchz,x_search (requires xAI OAuth or XAI_API_KEY))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)homeassistantu   🏠 Home Assistantzsmart home device control)spotifyu   🎵 Spotifyz$playback, search, playlists, library)discordu   💬 Discord (read/participate)z-fetch messages, search members, create thread)discord_adminu   🛡️  Discord Server Adminz&list channels/roles, pin, assign roles)yuanbaou   🤖 Yuanbaozgroup info, member queries, DM)computer_useu   🖱️  Computer Use (macOS)z)background desktop control via cua-driver>   r'   r"   r7   r6   r&   r%   r8   r5   returnc                  n   	 ddl m}   |              dS # t          $ r Y nw xY w	 ddlm} t           |d          pd                                          rdS n# t          $ r Y nw xY wt          t          t          j	        
                    d          pd                                                    S )u  Cheap, side-effect-free check for usable xAI credentials.

    Used to auto-enable the ``x_search`` toolset when the user has either
    completed xAI Grok OAuth (SuperGrok subscription) or set
    ``XAI_API_KEY``. Does NOT hit the network — only inspects the local
    auth store and environment. The tool's runtime ``check_fn`` still
    gates schema registration if creds later expire or get revoked.
    r   )_read_xai_oauth_tokensTr   XAI_API_KEY )hermes_cli.authr=   	Exceptiontools.xai_httpr   strstripboolosenvironget)r=   _xai_get_env_values     ;/home/kuhnn/.hermes/hermes-agent/hermes_cli/tools_config.py_xai_credentials_presentrL   d   s    ::::::   t   FFFFFF!!-006B77==?? 	4	   BJNN=117R88>>@@AAAs    
!!2A 
A'&A'r7   )r7   r8   _TOOLSET_PLATFORM_RESTRICTIONSts_keyplatformc                 F    t                               |           }|du p||v S )zReturn True if ``ts_key`` is configurable on ``platform``.

    Toolsets without a restriction entry are allowed everywhere (the default).
    N)rM   rI   )rN   rO   alloweds      rK   _toolset_allowed_for_platformrR      s+    
 -0088Gd?1h'11    c                     t          t                    } d | D             }	 ddlm}m}  |              |            D ]=}|d         |v r|                    |d                    |                     |           >n# t          $ r Y nw xY w| S )u  Return 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. A plugin whose toolset key
    already appears in ``CONFIGURABLE_TOOLSETS`` is skipped — bundled
    plugins (e.g. ``plugins/spotify``) share their toolset key with the
    built-in entry, and we want the built-in label/description to win.
    Without the dedupe, ``hermes tools`` → "reconfigure existing" would
    list the same toolset twice.
    c                     h | ]\  }}}|	S  rV   .0rN   _s      rK   	<setcomp>z7_get_effective_configurable_toolsets.<locals>.<setcomp>   s    ...|vq!F...rS   r   discover_pluginsget_plugin_toolsets)listCONFIGURABLE_TOOLSETShermes_cli.pluginsr\   r]   addappendrB   )resultseenr\   r]   entrys        rK   $_get_effective_configurable_toolsetsrf      s     '((F..v...D	LLLLLLLL((** 	! 	!EQx4HHU1XMM%    		!
    Ms   AA= =
B
	B
c                      	 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   r[   c                     h | ]\  }}}|	S rV   rV   rW   s      rK   rZ   z+_get_plugin_toolset_keys.<locals>.<setcomp>   s    AAA<61aAAArS   )r`   r\   r]   rB   setr[   s     rK   _get_plugin_toolset_keysrj      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_toolsetrm   )rX   kinfos      rK   
<dictcomp>rr      s;       4 0DEE  rS   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)rw   rx   ry   rz   r{   z
OpenAI TTSpaidzHigh quality voiceszOpenAI API keyz$https://platform.openai.com/api-keys)keyr   urlzxAI TTSu2   Grok voices — uses xAI Grok OAuth or XAI_API_KEYxaixai_grok)rw   ry   rz   r{   
post_setup
ElevenLabszMost natural voicesELEVENLABS_API_KEYzElevenLabs API keyz+https://elevenlabs.io/app/settings/api-keys
elevenlabszGoogle Gemini TTSpreviewz,30 prebuilt voices, controllable via promptsGEMINI_API_KEYzGemini API keyz&https://aistudio.google.com/app/apikeygemini	KittenTTSu   local · freez.Lightweight local ONNX TTS (~25MB), no API key	kittentts)rw   rx   ry   rz   r{   r   Piperz0Local neural TTS, 44 languages (voices ~20-90MB)piper)rw   icon	providers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)rw   rx   ry   web_backendrz   r|   r}   r~   zFirecrawl Self-Hostedu   free · self-hostedz(Run your own Firecrawl instance (Docker)z9Your Firecrawl instance URL (e.g., http://localhost:3002))r   r   )rw   rx   ry   r   rz   )rw   setup_title
setup_noter   r   Image Generationu   🎨z8Managed FAL image generation billed to your subscriptionr#   FAL_KEYfal)rw   rx   ry   rz   r|   r}   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)rw   rx   ry   rz   r   Video Generationu   🎬zX (Twitter) SearchzSelect xAI Credential Sourceu  Hermes routes X searches through xAI's built-in x_search Responses tool. Both credential sources hit the same https://api.x.ai/v1/responses endpoint — pick whichever you already have. SuperGrok OAuth is preferred when both are set (uses your subscription quota instead of API spend).u   🐦z'xAI Grok OAuth (SuperGrok Subscription)u6   Browser login at accounts.x.ai — no API key required)rw   rx   ry   rz   r   zxAI API keyz&Direct xAI API billing via XAI_API_KEYr?   zhttps://console.x.ai/)rw   rx   ry   rz   Browser Automationu   🌐z%Nous Subscription (Browser Use cloud)z/Managed Browser Use billed to your subscriptionzbrowser-user   BROWSER_USE_API_KEYagent_browser)	rw   rx   ry   rz   browser_providerr|   r}   r~   r   zLocal Browserz$Headless Chromium, no API key neededlocal)rw   rx   ry   rz   r   r   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   )rw   ry   rz   Spotifyu   🎵zSpotify Web APIu%   PKCE OAuth — opens the setup wizardr6   )rw   ry   rz   r   zComputer Use (macOS)u   🖱️darwinzcua-driver (background)u    ★ recommended · free · localun   macOS background computer-use via SkyLight SPIs — does NOT steal your cursor or focus. Works with any model.
cua_driver)rw   r   platform_gater   )	r)   r   r#   r%   r&   r   r5   r6   r:   )OPENROUTER_API_KEYzhttps://openrouter.ai/keys)r    r'   ,  )timeoutcapture_outputargsr   r   c          	      $   t          t          j                  j        j        }i t          j        dt          |          i}t          j        d          }|rI	 t          j
        |ddg| |d||          }|j        dk    r|S n# t          j        t          f$ r Y nw xY wt          j        ddg}	 t          j
        |d	gz   ddd
          }|j        dk    rt          d          n# t          j        t          f$ rr 	 t          j
        t          j        ddddgdddd           nE# t          j        t          j        f$ r'}	t          j        |ddd|	           cY d}	~	cY S d}	~	ww xY wY nw xY wt          j
        |dg| z   |d|          S )u  Install Python packages from a post-setup hook.

    Strategy (in order):
    1. ``uv pip install`` if uv is on PATH — fast, doesn't need pip in the venv.
    2. ``python -m pip install`` — works on stdlib venvs.
    3. ``python -m ensurepip --upgrade`` then retry pip — covers ``uv venv``
       which creates a venv WITHOUT pip.

    Why this exists: the Windows installer creates the venv via ``uv venv``,
    which doesn't seed pip. Post-setup hooks that shelled out to
    ``[sys.executable, '-m', 'pip', 'install', ...]`` failed with
    ``No module named pip`` on every fresh install. uv-first sidesteps that.

    Returns the ``subprocess.CompletedProcess`` from whichever tier succeeded
    (or the last failure for the caller to inspect).
    VIRTUAL_ENVuvpipinstallT)r   textr   envr   z-m	--version   r   r   r   zpip not in venv	ensurepipz	--upgradez--default-pipx   )r   r   r   check   r@   z(pip not available and ensurepip failed: )
returncodestdoutstderrN)r   sys
executableparentrG   rH   rD   shutilwhich
subprocessrunr   TimeoutExpiredFileNotFoundErrorCalledProcessErrorCompletedProcess)
r   r   r   	venv_rootuv_envuv_binrc   pip_cmdprobees
             rK   _pip_installr     s<   , S^$$+2I:
:M3y>>::F\$F 	^	1D1-D'  F
  A%% & )+<= 	 	 	D	 ~tU+G{m#dB
 
 
 q  #$5666 !%'89   
	N{KQ#$4     -z/HI 	 	 	.AbE!EE          		  >9$t$$%D'   sT   *B BB26C) )E1 (D)(E1)E+E&E+E1&E++E10E1Fupgradec                 <   ddl }ddl}ddl}|                                dk    r| rdS t	          d           dS  |j        d          }|sB| s@ |j        d          s t	          d           t          d	           dS t          d
          S |r| s	  |j        ddgddd          j	        
                                }t          d|pd            n# t          $ r t          d           Y nw xY wt          d           t          d           t          d           dS  |j        d          st	          d           t          |          S |rA	  |j        ddgddd          j	        
                                }n# t          $ r d}Y nw xY wd}t          dd          }|rs|rq	  |j        ddgddd          j	        
                                }|r||k    rt          d| d|            n|rt          d|            n# t          $ r Y nw xY w|S )u  Install or refresh the cua-driver binary used by Computer Use.

    The upstream installer always pulls the latest release tag, so re-running
    it is the canonical way to upgrade. We expose two modes:

    * ``upgrade=False`` — original post-setup behaviour: skip if already
      installed, install otherwise. Used by the toolset enable flow where
      we don't want to surprise the user with a network fetch.
    * ``upgrade=True`` — always re-run the installer (or call ``cua-driver
      update`` if the binary supports it). Used by ``hermes update`` and
      by ``hermes computer-use install --upgrade``.

    Returns True iff cua-driver is installed (or successfully refreshed)
    when the function returns. macOS-only — silently returns False on
    other platforms.
    r   NDarwinFz6    Computer Use (cua-driver) is macOS-only; skipping.
cua-drivercurlu(       curl not found — install manually:zG      https://github.com/trycua/cua/blob/main/libs/cua-driver/README.md
Installing)rn   r   T   r   z"    cua-driver already installed: zunknown versionz!    cua-driver already installed.z,    Grant macOS permissions if not done yet::      System Settings > Privacy & Security > Accessibility=      System Settings > Privacy & Security > Screen Recordingu1       curl not found — cannot refresh cua-driver.r@   
Refreshing)rn   verbosez    cua-driver upgraded: u    → z    cua-driver up to date: )rO   r   r   system_print_warningr   _print_info_run_cua_driver_installerr   r   rE   _print_successrB   rF   )	r   _platr   r   binaryversionbeforeokafters	            rK   install_cua_driverr   )  s   " MMM||~~!! 	 5OPPPuV\,''F  =' =v|F## 	EFFFabbb5(|<<<<  g 	@$jn{+#$   UUWW  ^@\K\^^____ 	@ 	@ 	@>?????	@BCCCPQQQSTTTt 6< JKKKF|| 
	#Z^{+#$   UUWW F  	 	 	FFF	 	"u	E	E	EB	 f 
	"JN{+#$   UUWW   C&O6OOOOPPPP CA%AABBB 	 	 	D	Is8   AC C10C1-F FF,AH 
HHr   rn   r   c                    ddl }ddl}d}|rt          d|  d           nt          d|  d           	  |j        |dd	          }|j        dk    r_ |j        d
          rO|rKt          d           t          d           t          d           t          d           t          d           dS t          d|                                  d           t          d|            dS # |j	        $ r) t          d|                                  d           Y dS t          $ r2}t          d|                                  d|            Y d}~dS d}~ww xY w)zRun the upstream cua-driver install.sh. Returns True on success.

    The script is idempotent: it always downloads the latest release, so
    re-running it on an already-installed system performs an upgrade.
    r   Nzq/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/trycua/cua/main/libs/cua-driver/scripts/install.sh)"    z. cua-driver (macOS background computer-use)...z cua-driver...Tr   )shellr   r   z    cua-driver installed.u.       IMPORTANT — grant macOS permissions now:r   r   z2    Both must allow the terminal / Hermes process.z    cua-driver z# did not complete. Re-run manually:      Fz timed out. Re-run manually.z	 failed: )r   r   r   r   r   r   r   r   lowerr   rB   )rn   r   r   r   install_cmdrc   r   s          rK   r   r     s    MMM	0 
  2P5PPPQQQQ050001114EEE!!lfl<&@&@! R:;;;LMMMXYYY[\\\PQQQ4[[[[\\\*[**+++u$   TTTTUUUuu   DDDDDEEEuuuuus$   A;C+ 27C+ +/E	E&'EEpost_setup_keyc           	         ddl }| dv rwt          dz  dz  } |j        d          } |j        d          }|                                s|rt	          d           ddl} |j        |d	d
gddt          t                              }|j        dk    rt          d           nddl
m} t          d |             d           |j        r1t	          d|j                                        dd                     n%|                                st          d           dS | dk    rdS 	 ddlm}m}	 n*# t$          $ r}
t          d|
            Y d}
~
dS d}
~
ww xY w |            rt          d           dS  |	            r/t          d           t	          d           t	          d           dS |st          d           dS t	          d           ddl}t          dz  dz  dz  }t&          j        dk    r+|                    d          }|                                r|}|                                rt          |          d	d gn|d!dd	d g}	  |j        |ddt          t                    d"#          }|j        dk    rt          d$           ddlm} d|_        n{t          d%           |j        p|j        pd&                                                                d'd         }|D ]}t	          d|dd                     t	          d(           dS dS # |j        $ r" t          d)           t	          d(           Y dS t$          $ r,}
t          d*|
            t	          d(           Y d}
~
dS d}
~
ww xY w| d+k    r[t          dz  d,z  d-z  } |j        d          }|                                s|rt	          d.           t	          d/           ddl}	  |j        |d	d0d1d2d3gt          t                    4          }|j        dk    rt          d5           nt          d6           n8# t$          $ r+}
t          d7|
            t	          d8           Y d}
~
nd}
~
ww xY w|                                r/t	          d9           t	          d:           t	          d;           dS  |j        d          s t          d<           t	          d=           dS dS | d>k    rt7          d?@           dS | dAk    r	 t9          dA           t          dB           dS # t:          $ r Y nw xY wt	          dC           dD}	 t=          dE|dFdGgdHI          }|j        dk    r.t          dJ           t	          dK           t	          dL           nWt          dM           t	          d|j        pd&                                ddH                     t	          dN| dO           dS dS # |j        $ r& t          dP           t	          dN| dO           Y dS w xY w| dQk    r"	 t9          dQ           t          dR           n# t:          $ r t	          dS           	 t=          g dTdHI          }|j        dk    rt          dU           nTt          dV           t	          d|j        pd&                                ddH                     t	          dW           Y dS n0# |j        $ r# t          dX           t	          dW           Y Y dS w xY wY nw xY wt	          dY           t	          dZ           t	          d[           dS | d\k    r	 t9          d\           t          d]           n# t:          $ r t	          d^           	 t=          g d_dHI          }|j        dk    rt          d`           nTt          da           t	          d|j        pd&                                ddH                     t	          db           Y dS n0# |j        $ r# t          dc           t	          db           Y Y dS w xY wY nw xY wt	          dd           t	          de           dS | dfk    rddglm } 	 ddhl!m"} n9# t$          $ r,}
t          di|
            t	          dj           Y d}
~
dS d}
~
ww xY wt	          dk           	  | |dddd?dl                     t          dm           dS # tF          $ r,}
t          dn|
            t	          do           Y d}
~
dS d}
~
wt$          $ r,}
t          dp|
            t	          dj           Y d}
~
dS d}
~
ww xY w| dqk    ri	 ddrl!m$} tK           |            &                    ds                    }n# t$          $ r d?}Y nw xY wtO          dt          }|rt          du           dS |rt          dv           dS t	          dw           	 ddxl(m)}m*}m+} ddyl,m-} n9# t$          $ r,}
t          dz|
            t	          d{           Y d}
~
dS d}
~
ww xY w |d|g d}d~          }|dk    r, |            rt          d           dS t          d           dS |dk    r= |dd          }|r |dt|           t          d           dS t          d           dS t	          d           dS dS )zBRun post-setup hooks for tools that need extra installation steps.r   N>   browserbaser   node_moduleszagent-browsernpmnpxz8    Installing Node.js dependencies for browser tools...r   z--silentT)r   r   cwdz"    Node.js dependencies installeddisplay_hermes_homez*    npm install failed - run manually: cd z/hermes-agent && npm installr      zV    Node.js not found - browser tools require: npm install (in hermes-agent directory)r   )_chromium_installed_running_in_dockerz%    Could not check Chromium status: z&    Chromium browser already installedz5    Chromium is missing but you're running in Docker.z6    Pull the latest image to get the bundled Chromium:z:      docker pull ghcr.io/nousresearch/hermes-agent:latestzT    npx not found - install Chromium manually: npx agent-browser install --with-depsz5    Installing Chromium (~170MB one-time download)...z.binwin32z.cmdz--with-depsz-yiX  )r   r   r   r   z    Chromium installedz    Chromium install failed:r@   z7    Run manually: npx agent-browser install --with-depsz'    Chromium install timed out (>10min)z    Chromium install failed: r   z@askjozcamofox-browserz)    Installing Camofox browser package...uW       First run downloads the Camoufox engine (~300MB) — this can take several minutes.z@askjo/camofox-browser@^1.5.2z	--no-fundz
--no-auditz--progress=false)r   z    Camofox installeduK       npm install failed — run manually: npm install @askjo/camofox-browserz    Camofox install failed: z4    Run manually: npm install @askjo/camofox-browserz    Start the Camofox server:z       npx @askjo/camofox-browserzV    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   F)r   r   z"    kittentts is already installedz6    Installing kittentts (~25-80MB model, CPU-only)...z^https://github.com/KittenML/KittenTTS/releases/download/0.8.1/kittentts-0.8.1-py3-none-any.whl-U	soundfile--quietr   )r   z    kittentts installedz>    Voices: Jasper, Bella, Luna, Bruno, Rosie, Hugo, Kiki, LeozO    Models: KittenML/kitten-tts-nano-0.8-int8 (25MB), micro (41MB), mini (80MB)z    kittentts install failed:z%    Run manually: uv pip install -U 'z' soundfilez'    kittentts install timed out (>5min)r   z"    piper-tts is already installedzI    Installing piper-tts (~14MB wheel, voices downloaded on first use)...)r   z	piper-ttsr  z    piper-tts installedz    piper-tts install failed:z-    Run manually: uv pip install -U piper-ttsz'    piper-tts install timed out (>5min)zE    Default voice: en_US-lessac-medium (downloaded on first TTS call)zU    Full voice list: https://github.com/OHF-Voice/piper1-gpl/blob/main/docs/VOICES.mdzE    Switch voices by setting tts.piper.voice in ~/.hermes/config.yamlddgsz    ddgs is already installedz2    Installing ddgs (DuckDuckGo search package)...)r   r  r  z    ddgs installedz    ddgs install failed:z(    Run manually: uv pip install -U ddgsz"    ddgs install timed out (>5min)zE    No API key required. DuckDuckGo enforces server-side rate limits.z?    Pair with an extract provider if you also need web_extract.r6   )SimpleNamespace)login_spotify_commandz!    Could not load Spotify auth: z%    Run manually: hermes auth spotifyz    Starting Spotify login...)	client_idredirect_uriscope
no_browserr   z    Spotify authenticatedz$    Spotify login did not complete: z"    Run later: hermes auth spotifyz    Spotify login failed: r   )get_xai_oauth_auth_status	logged_inr?   zI    xAI will use your xAI Grok OAuth (SuperGrok Subscription) credentialsz*    xAI will use your existing XAI_API_KEYz&    xAI needs credentials. Choose one:)_run_xai_oauth_login_from_setupprompt_choicer   )r   z"    Could not load setup helpers: z?    Run later: hermes auth add xai-oauth   (or set XAI_API_KEY)z(    How do you want xAI to authenticate?)uF   Sign in with xAI Grok OAuth (SuperGrok Subscription) — browser loginz#Paste an xAI API key (console.x.ai)u8   Skip — configure later via `hermes auth add xai-oauth`)choicesr   u6       Logged in — xAI will use these OAuth credentialszO    xAI Grok OAuth login did not complete. Run later: hermes auth add xai-oauthr   z    xAI API keypasswordz    XAI_API_KEY savedz=    No API key provided. Run later: hermes auth add xai-oauthz>    xAI will remain inactive until credentials are configured.).r   PROJECT_ROOTr   existsr   r   r   rD   r   r   hermes_constantsr   r   r   rE   tools.browser_toolr   r   rB   r   rO   with_suffixbrowser_tool_cached_chromium_installedr   
splitlinesr   r   
__import__ImportErrorr   typesr  rA   r  
SystemExitr
  rF   rI   r   hermes_cli.setupr  r  r   hermes_cli.configr   )r   r   r   npm_binnpx_binr   rc   r   r   r   exclocal_ablocal_ab_winr   _bttaillinecamofox_dir_npm_bin	wheel_urlr  r  r
  oauth_logged_inexisting_api_keyr  r  _setup_promptr   idxapi_keys                                  rK   _run_post_setupr/    s   MMM999#n4F&,u%%&,u%%""$$ 	 	RSSS
 $Z^)Z0#$C4E4E  F  A%%CDDDD@@@@@@L_L_LaLa  A  A  A= H F)<)<)>)>tt)D F FGGG$$&& 	stttF
 _,,F		          	 	 	H3HHIIIFFFFF	    	CDDDF 
	G   H   L   F 	f   FKLLL  .069OK<7""#//77L""$$ ('   LS]]I}554)]K 	
	S#Z^#$C4E4Es  F  A%%7888 10000015..=>>><<"CCEEPPRRSUSVSVW  7 7D 5dsd 5 56666UVVVVV /. ( 	S 	S 	SDEEEQRRRRRR 	S 	S 	S@3@@AAAQRRRRRRRRR	S 
9	$	$"^3h>ARR6<&&!!## 	 	CDDDqrrr'y*I ,0BDL))  
 $))"#:;;;;"=      CcCCDDDJ       
  	e7888:;;;pqqqqqe$$ 	eOPPPcddddd	e 	e 
<	'	'5))))))	;	&	&	{###?@@@F 	 	 	D	LMMM5 		X!4K"KUXYYYF A%%8999\]]]mnnnn>???Jfm&9r%@%@%B%B4C4%HJJKKKZIZZZ[[[[[	 on
 ( 	X 	X 	XDEEEV	VVVWWWWWW	X 
7	"	"	w?@@@@ 	 	 	cddd%&D&D&DcRRR$))"#<===="#BCCC N&-*=2)D)D)F)Ftt)L N NOOO OPPPFF > ,   HIIIKLLL >=	 	[\\\klll[\\\\\	6	!	!	v:;;;; 	 	 	LMMM%&?&?&?MMM$))"#78888"#=>>> N&-*=2)D)D)F)Ftt)L N NOOO JKKKFF 9 ,   CDDDFGGG 98	 	[\\\UVVVVV	9	$	$ 	*)))))	======= 	 	 	DsDDEEE?@@@FFFFF	 	3444	A!!//T $# # #    677777 	> 	> 	> G#GGHHH<========= 	A 	A 	A===>>>?@@@@@@@@@	A 
:	%	%	$AAAAAA"#<#<#>#>#B#B;#O#OPPOO 	$ 	$ 	$#OOO	$(77 	[   F 	GHHHF<===
	         
 9888888 	 	 	EEEFFFYZZZFFFFF	
 m6  
 
 
 
 !88..00 L     ;     AXX#m$5EEEG }g666677777S     XYYYYYC 
&	%sI  ,D5 5
E?EECL (M>		M>!M99M>!AP6 6
Q+ !Q&&Q+T# #
T0/T0B#W, ,,XX'Y \ A?[#"\#(\\\\\]/ /`?	A?``?(`94`?8`99`?>`?/a6 6
b, !b''b,?(c) )
e3!de'!ee0f ff&g7 7
h-!h((h-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_TOKENr7   SLACK_BOT_TOKENslackWHATSAPP_ENABLEDwhatsapp	QQ_APP_IDqqbot)r   rb   )enableds    rK   _get_enabled_platformsr<    s    gG)** #z"""()) "y!!!&''  w'(( #z"""[!!  wNrS   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       rK   _platform_toolset_summaryrC    sC     *,,	#%G : :+FD99NrS   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)
isinstancerF   intrD   rE   r   )valuer   lowereds      rK   _parse_enabled_flagrQ    s    }% % z% ++--%%''00041115NrS   include_default_mcp_serversrS  c                8  &'( ddl m}m} |                     d          pi }|                              }|t	          |t
                    s-t                                        }|r	|d         }nd }|g}d |D             }d t          D             &t                      (d	 t          	                                D             't          &fd
|D                       }	|	r0&fd|D             }
t                      }|D ].}|&v s|(v r||vr|                     ||                     /|rt                      }t          D ][\  }}}t          |          st           ||                    }|r*|                    |          r|                    |           \t          t                     }|v rt"          vr|                               d|v r)t'          j        d          r|                    d           ||z  }|
|z  }
nZt                      }|D ] }|                     ||                     !t                      }
t          D ][\  }}}t          |          st           ||                    }|r*|                    |          r|
                    |           \t          d          ot+                      }|r|
                    d           t          t                     }|v rt"          vr|                               d|v r)t'          j        d          r|                    d           |rd|v r|                    d           |
|z  }
t                                        }|r|d         nd }t           ||                    }t                      }&D ] }|                     ||                     !t                      }|
D ] }|                     ||                     !&(z  'z  }|d |D             z  }|t          t                     hz
  z  }|                                D ]\  }}||v r
|                    d          r t           ||                    }|r|                    |          sP|                    |          rf|                    |          s*|
                    |           |                    |           (r{|                     di           }t          |                    g                     }(D ]?}||v r|
                    |           |t           v r&||vr|
                    |           @&'(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|
                    |"           |                     d          pi }#|#                    d          pg }$|$rd |$D             }%|
|%z  }
|
S )zBResolve which individual toolset names are enabled for a platform.r   )resolve_toolsetTOOLSETSplatform_toolsetsNro   hermes-c                 ,    g | ]}t          |          S rV   rD   rX   tss     rK   
<listcomp>z'_get_platform_tools.<locals>.<listcomp>3  s    555SWW555rS   c                     h | ]\  }}}|	S rV   rV   rW   s      rK   rZ   z&_get_platform_tools.<locals>.<setcomp>5      JJJLFAqJJJrS   c                     h | ]
}|d          S ro   rV   rX   ps     rK   rZ   z&_get_platform_tools.<locals>.<setcomp>7      NNNaQ01NNNrS   c              3       K   | ]}|v V  	d S NrV   )rX   r\  configurable_keyss     rK   	<genexpr>z&_get_platform_tools.<locals>.<genexpr>>  s)      NN"b$55NNNNNNrS   c                 <    h | ]}|v t          |          |S rV   rR   )rX   r\  rg  rO   s     rK   rZ   z&_get_platform_tools.<locals>.<setcomp>A  s?     
 
 
&&&+HX+V+V& &&&rS   r5   r   r&   c                 <    h | ]}|                     d           |S )rX  )
startswith)rX   rp   s     rK   rZ   z&_get_platform_tools.<locals>.<setcomp>  s)    <<<1ALL$;$;<Q<<<rS   includesknown_plugin_toolsetsc                 ,    h | ]}|vr
|vr|v|S rV   rV   )rX   r\  rg  platform_default_keysplugin_ts_keyss     rK   rZ   z&_get_platform_tools.<locals>.<setcomp>  sH       &&&n$$+++	 	 ,++rS   mcp_serversc                     h | ]N\  }}t          |t                    t          |                    d d          d          ?t	          |          OS )r;  Tr   )rM  dictrQ  rI   rD   )rX   rw   
server_cfgs      rK   rZ   z&_get_platform_tools.<locals>.<setcomp>  sg       D*j$''  
y$ ? ?NNN	D		  rS   no_mcpagentdisabled_toolsetsc                 ,    h | ]}t          |          S rV   rZ  r[  s     rK   rZ   z&_get_platform_tools.<locals>.<setcomp>  s    <<<BB<<<rS   )toolsetsrU  rV  rI   rM  r^   rk   r_   rj   valuesanyri   updaterR   issubsetra   _DEFAULT_OFF_TOOLSETSrM   removerG   getenvrL   items))r=  rO   rS  rU  rV  rW  toolset_names	plat_info
default_tshas_explicit_configenabled_toolsetscomposite_toolsts_nameexpandedrN   rY   ts_toolsdefault_offall_tool_namesx_search_auto_enabled
_plat_info_default_tsplatform_tool_universeconfigurable_tool_universeckclaimedskipts_def	known_mapknown_for_platformptsexplicit_passthroughrr  enabled_mcp_serversexplicit_mcp_servers	agent_cfgry  disabled_setrg  rp  rq  s)    `                                    @@@rK   r@  r@    s>    32222222

#677=2%))(33MJ}d$C$CMM(++	 	."#45JJ .8--J# 65}555MJJ4IJJJ-//NNN9;K;K;M;MNNN NNNNNNNNN [(
 
 
 
 
&
 
 
 %%$ 	= 	=G+++w./H/Hh&&""??7#;#;<<<< 	)uuH 5 ) )14VXFF v6677 ) 1 1/ B B )LL(((344K;&&8;Y+Y+Y""8,,,+--")L2I2I-""?333#H( $ 	< 	<G!!//'":":;;;;551 	- 	-LFAq0BB ??62233H -H--n== - $$V,,, **h?? +(** 	 ! 	-  ,,,/00 {""x7U'U'Ux((( k))bi.E.E)/// ! 	+Z;%>%>z***K' x((J3=W*.//CWXCWCWK !=!=>>!$ ? ?"))//"*=*=>>>>eeG" 0 0v..////~-0EED<<<<<<DC%&&(33D"..** % %T>>::j!! 	v..// 	x001GHH 	788 	  )) 	%  (((NN8$$$  *JJ6;;	 x!<!<==! 		* 		*Cm## $$S))))---... $$S)))
        **]++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 

7##)rI!&9::@b )<<*;<<<L(rS   enabled_toolset_keysc                 J   |                      di            fd|D             }d t          D             t                      }|z  d t                                          D             t          | dg           }t          |t                    sg }d |D             }fd|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.
    rW  c                 4    h | ]}t          |          |S rV   rj  )rX   r\  rO   s     rK   rZ   z'_save_platform_tools.<locals>.<setcomp>  s9       (X66
  rS   c                     h | ]\  }}}|	S rV   rV   rW   s      rK   rZ   z'_save_platform_tools.<locals>.<setcomp>  r_  rS   c                     h | ]
}|d          S ra  rV   rb  s     rK   rZ   z'_save_platform_tools.<locals>.<setcomp>  rd  rS   rt  c                 ,    g | ]}t          |          S rV   rZ  r[  s     rK   r]  z(_save_platform_tools.<locals>.<listcomp>"  s    ===RR===rS   c                 $    h | ]}|v|v
|S rV   rV   )rX   re   rg  rp  s     rK   rZ   z'_save_platform_tools.<locals>.<setcomp>&  s:       )))e;P.P.P 	.P.P.PrS   rw  rn  N)
setdefaultr_   rj   rk   r|  r   rM  r^   discardsortedr
   )r=  rO   r  plugin_keysexisting_toolsetspreserved_entriesrg  rp  s    `    @@rK   _save_platform_toolsr    s    )2...
   )   KJ4IJJJ*,,K$
 ON9;K;K;M;MNNN  (;XrRRR'.. ==+<===    ,   h''' -33GJ[3[,\,\F)  H126664:;4G4G&'1rS   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#   Trz   c              3   @   K   | ]}t          |d                    V  dS r   Nr>   )rX   r   s     rK   rh  z$_toolset_has_keys.<locals>.<genexpr>W  s.      ==q=5**======rS   c              3   :   K   | ]\  }}t          |          V  d S rf  r>   )rX   varrY   s      rK   rh  z$_toolset_has_keys.<locals>.<genexpr>_  s.      ==fc1}S!!======rS   )r	   agent.auxiliary_clientr  rB   r   featuresrI   	availablemanaged_by_nousTOOL_CATEGORIES_visible_providersallTOOLSET_ENV_REQUIREMENTS)rN   r=  r  	_providerclient_modelr  featurecatproviderrz   requirementss               rK   _toolset_has_keysr  <  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 
>>questionr  c                 ,    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  )r  r  r   r  s       rK   _prompt_choicer  d  s/    555555HgPWXXXXrS   _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)typer  )r  tiktokenget_encodingrB   loggerdebugmodel_toolstools.registryr  get_all_tool_names
get_schema_jsondumpslenencode)r  encr  r  countsrw   schemar   s           rK   _estimate_tool_tokensr  p  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r1  platform_labelr;  c                    ddl m} ddlm t	                      t                      }fd|D             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_checklist)rU  c                 B    g | ]\  }}}t          |          |||fS rV   rj  rX   rp   ldrO   s       rK   r]  z-_prompt_toolset_checklist.<locals>.<listcomp>  E       q!Q(H55	
Aq	  rS   r@   z  [no API key]  ()c                 *    h | ]\  }\  }}}|v |S rV   rV   )rX   irN   rY   r;  s       rK   rZ   z,_prompt_toolset_checklist.<locals>.<setcomp>  s8       a&!QW 	
rS   Nc                     g | ]\  }}}|	S rV   rV   rW   s      rK   r]  z-_prompt_toolset_checklist.<locals>.<listcomp>  s    888lfa6888rS   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rI   )rX   rw   tool_tokenss     rK   rh  z?_prompt_toolset_checklist.<locals>.status_fn.<locals>.<genexpr>  s1      GGTa00GGGGGGrS   i  zEst. tool context: ~z.1fzk tokensz tokens)ri   r~  sum)r  	all_toolsr-  totalrU  r  ts_keyss       rK   	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8rS   z
Tools for )r  r  c                 ,    h | ]}|         d          S r   rV   )rX   r  	effectives     rK   rZ   z,_prompt_toolset_checklist.<locals>.<setcomp>  s!    ,,,IaLO,,,rS   )r  r  r{  rU  r  rf   r  r  rI   r  rb   	enumerateri   rD   )r  r;  rO   r  effective_alllabelsrN   ts_labelts_descsuffixpre_selectedr  r  r  rU  r  r  s    ``          @@@@rK   _prompt_toolset_checklistr    s   555555(((((( ())K8::M   #0  I
 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,,,,rS   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  rI   _configure_tool_category_configure_simple_requirements)rN   r=  r  s      rK   _configure_toolsetr    sM     

f
%
%C
 / f55555 	'v.....rS   c                  N   	 ddl m}  ddlm}  |              |             }n# t          $ r g cY S w xY wg }|D ]}t          |dd          dk    r	 |                                }n# t          $ r Y :w xY wt          |t                    sT|	                    d|j
                  |	                    dd          |	                    d	d          |	                    d
g           |j        d}|	                    d          r|d         |d<   |                    |           |S )uV  Build picker-row dicts from plugin-registered image gen providers.

    Each returned dict looks like a regular ``TOOL_CATEGORIES`` provider
    row but carries an ``image_gen_plugin_name`` marker so downstream
    code (config writing, model picker) knows to route through the
    plugin registry instead of the in-tree FAL backend.

    FAL is skipped — it's already exposed by the hardcoded
    ``TOOL_CATEGORIES["image_gen"]`` entries. When FAL gets ported to
    a plugin in a follow-up PR, the hardcoded entries go away and this
    function surfaces it alongside OpenAI automatically.
    r   list_providers_ensure_plugins_discoveredrw   Nr   rx   r@   ry   rz   )rw   rx   ry   rz   image_gen_plugin_namer   )agent.image_gen_registryr
  r`   r  rB   getattrget_setup_schemarM  ru  rI   display_namerw   rb   r
  r  r   rowsr  r  rows          rK   _plugin_image_gen_providersr    s   ;;;;;;AAAAAA""$$$"N$$		   			 D  8VT**e33	..00FF 	 	 	H	&$'' 	JJvx'<==ZZ,,::eR((

:r22%-]
 
 ::l## 	5 &| 4CCKs    # 22A''
A43A4c                  "   	 ddl m}  ddlm}  |              |             }n# t          $ r g cY S w xY wg }|D ]}	 |                                }n# t          $ r Y $w xY wt          |t                    s>|                    d|j	                  |                    dd          |                    dd          |                    dg           |j
        d	}|                    d
          r|d
         |d
<   |                    |           |S )u`  Build picker-row dicts from plugin-registered video gen providers.

    Mirrors ``_plugin_image_gen_providers`` exactly — every video backend
    is a plugin, so this function is the *only* source of provider rows
    for the Video Generation category. The hardcoded ``TOOL_CATEGORIES``
    entry for ``video_gen`` keeps an empty providers list.
    r   r	  r  rw   rx   r@   ry   rz   )rw   rx   ry   rz   video_gen_plugin_namer   )agent.video_gen_registryr
  r`   r  rB   r  rM  ru  rI   r  rw   rb   r  s          rK   _plugin_video_gen_providersr    sg   ;;;;;;AAAAAA""$$$"N$$		   			 D  	..00FF 	 	 	H	&$'' 	JJvx'<==ZZ,,::eR((

:r22%-]
 
 ::l## 	5 &| 4CCKs    # 22A
AAc                  B   	 ddl m}  ddlm}  |              |             }n# t          $ r g cY S w xY wg }|D ]}t          |dd          }|s	 |                                }n# t          $ r Y 8w xY wt          |t                    sR|	                    d|j
                  |	                    dd          |	                    dd          |	                    d	g           ||d
}|	                    d          r|d         |d<   |                    |           |S )a\  Build picker-row dicts from plugin-registered web search providers.

    Each returned dict is a regular ``TOOL_CATEGORIES`` provider row. It
    populates both ``web_backend`` (legacy field consumed by setup +
    selection helpers) and ``web_search_plugin_name`` (informational
    marker) so the picker behaves identically whether a provider is
    hardcoded or plugin-registered.

    After PR #25182, all seven web providers (brave-free, ddgs, searxng,
    exa, parallel, tavily, firecrawl) are plugins; this helper is the sole
    source of provider rows for the Web Search & Extract category.
    r   r	  r  rw   Nrx   r@   ry   rz   )rw   rx   ry   rz   r   web_search_plugin_namer   )agent.web_search_registryr
  r`   r  rB   r  r  rM  ru  rI   r  rb   )_list_web_providersr  r   r  r  rw   r  r  s           rK   _plugin_web_search_providersr  =  s   SSSSSSAAAAAA""$$$''))		   			 D  x.. 		..00FF 	 	 	H	&$'' 	JJvx'<==ZZ,,::eR((

:r22&*
 
 ::l## 	5 &| 4CCK    # 22A%%
A21A2c                  B   	 ddl m}  ddlm}  |              |             }n# t          $ r g cY S w xY wg }|D ]}t          |dd          }|s	 |                                }n# t          $ r Y 8w xY wt          |t                    sR|	                    d|j
                  |	                    dd          |	                    dd          |	                    d	g           ||d
}|	                    d          r|d         |d<   |                    |           |S )a1  Build picker-row dicts from plugin-registered cloud browser providers.

    Each returned dict mirrors the legacy ``TOOL_CATEGORIES["browser"]``
    schema (``name`` / ``badge`` / ``tag`` / ``env_vars`` /
    ``browser_provider`` / ``post_setup``) so the picker behaves identically
    whether a provider was hardcoded or plugin-registered.

    Populates ``browser_provider`` (the legacy config key written to
    ``browser.cloud_provider``) and a ``browser_plugin_name`` marker so
    setup / write paths can route through the registry when they want to.
    r   r	  r  rw   Nrx   r@   ry   rz   )rw   rx   ry   rz   r   browser_plugin_namer   )agent.browser_registryr
  r`   r  rB   r  r  rM  ru  rI   r  rb   )_list_browser_providersr  r   r  r  rw   r  r  s           rK   _plugin_browser_providersr$  u  s   TTTTTTAAAAAA""$$$++--		   			 D  x.. 		..00FF 	 	 	H	&$'' 	JJvx'<==ZZ,,::eR((

:r22 $#'
 
 ::l## 	5 &| 4CCKr  r  c                    t          |          }g }|                     dg           D ]X}|                    d          rt                      s&|                    d          r|j        sC|                    |           Y|                     d          dk    r!|                    t                                 |                     d          dk    r!|                    t                                 |                     d          dk    r!|                    t                                 |                     d          dk    r!|                    t                                 |S )	zBReturn provider entries visible for the current auth/config state.r   r}   r|   rw   r   r   r   r   )
r   rI   r   nous_auth_presentrb   extendr  r  r  r$  )r  r=  r  visibler  s        rK   r  r    sW   -f55HGGGK,, ! !<<.// 	8R8T8T 	<<,-- 	h6P 	x     wwv,,,244555 wwv,,,244555 wwv000355666 wwv...022333NrS   c                  D    t          t          j        d                    S )Nr   )rF   r   r   rV   rS   rK   <lambda>r*    s    $v|L99:: rS   _POST_SETUP_INSTALLEDc                     t                               |           }|dS 	 t           |                      S # t          $ r Y dS w xY w)zAReturn True when the post_setup install side-effect is satisfied.NT)r+  rI   rF   rB   )r   	predicates     rK   _post_setup_already_installedr.    s]    %)).99I tIIKK      tts   7 
AAc                    t                               |           }|st          | |           S t          ||          D ]+}|                    d          }|rt	          |          s d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    rot                      rd
S 	 ddlm	} ddl
m}	  |	              |            D ]*}	 |                                r d
S # t          $ r Y 'w xY wn# t          $ r Y nw xY wdS | dk    r_	 ddlm	} ddl
m}	  |	              |            D ]*}	 |                                r d
S # t          $ r Y 'w xY wn# t          $ r Y nw xY wdS t          | |           S )zBReturn True when enabling this toolset should open provider setup.r   Tr)   r  r   backendr   cloud_providerr#   Fr   r	  r  r%   )r  rI   r  r  r.  rM  ru  r   r  r
  r`   r  is_availablerB   r  )
rN   r=  r  r  r   tts_cfgweb_cfgbrowser_cfgr
  r  s
             rK   #_toolset_needs_configuration_promptr6    s   


f
%
%C 5$VV4444 'sF33  \\,//
 	;JGG 	44**UB''gt,,,I
'0II**UB''gt,,,H	0HHjjB//k4000W4DK4WW !"" 	5	??????EEEEEE&&(((*N,,  ,,.. %$uu%    H	  	 	 	D	t	??????EEEEEE&&(((*N,,  ,,.. %$uu%    H	  	 	 	D	t 0000sx   #"E/ EE/ E/ 
E+(E/ *E++E/ /
E<;E<"G +G?G G 
GG GG 
G! G!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.r   r@   rw   requires_python  z requires Python r   .r   z+ (current: r  z3  Upgrade Python and reinstall to enable this tool.N  ---   () ---ry   r   r   zChoose a providerz - z ---rx    []    — rz   c              3   @   K   | ]}t          |d                    V  dS r  r>   rX   vs     rK   rh  z+_configure_tool_category.<locals>.<genexpr>V  .      "M"Mq=5#:#:"M"M"M"M"M"MrS   	 [active] [configured]u(   Skip — keep defaults / configure later:z
  Skipped )rI   r  r   version_infoprint_print_errormajorminorr   r  r   r   CYAN_configure_providerr  _is_provider_activerb   _detect_active_provider_indexr  )rN   r  r=  r   rw   r   reqr  titleprovider_choicesrc  rx   ry   
configuredrz   default_idxprovider_idxs                    rK   r  r  +  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<<<<<rS   r  c                 t   |                      d          }|rD|                     di           }t          |t                    o|                     d          |k    S |                      d          }|rD|                     di           }t          |t                    o|                     d          |k    S |                      d          }|rZt          |          }|j                             |          }|dS |dk    r|                     di           }t          |t                    rV|                     d          }	|	d	vrdS |                     d
          &t          |                     d
          d          sdS |j        S |                      d          r"|j        ot          |dd          | d         k    S d| v r$t          |dd          }
|j        o| d         |
k    S |                      d          r$t          |dd          }
|j        o|
| d         k    S |j        S |                      d          rt          |dd          | d         k    S d| v rt          |dd          }
| d         |
k    S |                      d          rt          |dd          }
|
| d         k    S |                      d          rw|                     di           }t          |t                    sdS |                     d          }	| d         dk    o(|	d	v o$t          |                     d
          d           S dS )z>Check if a provider entry matches the currently active config.r  r#   r  r  r%   r}   NF>   Nr@   r   use_gatewayrt  r{   r)   r   r   r1  r   r   r0  r   r   )rI   rM  ru  r   r  r   r  r   )r  r=  plugin_name	image_cfgvideo_plugin_name	video_cfgmanaged_featurer  r  configured_providercurrents              rK   rP  rP  o  s   ,,677K XJJ{B//	)T**Wy}}Z/H/HK/WW %<== ^JJ{B//	)T**]y}}Z/H/HL]/]]ll#9::O '1&99#''88?5k))

;33I)T** !&/mmJ&?&?#&.??? 5==//;OT]TaTaboTpTpz  EA  EA  EA; 5**<<'' 	' SFE:66(>:RR ))fi1ABBG*Vx8J/Kw/VV<<&& 	RfeY77G*Qw(=:Q/QQ&&||N## Nvuj11Xn5MMMX%%&)-=>>*+w66||M"" 2&%33(=111||&'' 	
JJ{B//	)T** 	5'mmJ77'(E1 Q#'88Q#IMM-$@$@%PPPP	

 5rS   r   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.rz   c              3   @   K   | ]}t          |d                    V  dS r  r>   rC  s     rK   rh  z0_detect_active_provider_index.<locals>.<genexpr>  s.      FFM!E(33FFFFFFrS   r   )r  rP  rI   r  )r   r=  r  rc  rz   s        rK   rQ  rQ    s    )$$  1q&)) 	HHH55R(( 	FFXFFFFF 	HHH1rS   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_toolre  rf  rd  s     rK   _fal_model_catalogrh    s%    EEEEEEEE}$$rS   )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.<modelr9  speedr@   	strengthspricer  )rl  rm  rn  s      rK   _format_imagegen_model_rowru    s      	#fWo 	#* 	# 	#88GR  	##)'?	#7	# 	#88K$$	#'-k':	#?	# 	# 88GR  	# 	#rS   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.
    Nrk  rj  rq  c                      g | ]
}|k    |S rV   rV   rX   mcurrent_models     rK   r]  z-_configure_imagegen_model.<locals>.<listcomp>  #     L L Lqm9K9K9K9K9KrS   c              3   4   K   | ]}t          |          V  d S rf  r  rX   rz  s     rK   rh  z,_configure_imagegen_model.<locals>.<genexpr>  (      //SVV//////rS   c              3   j   K   | ]-}t          |                             d d                    V  .dS rr  r@   Nr  rI   rX   rz  catalogs     rK   rh  z,_configure_imagegen_model.<locals>.<genexpr>  =      JJ1c'!*.."5566JJJJJJrS      rt  c              3   j   K   | ]-}t          |                             d d                    V  .dS rs  r@   Nr  r  s     rK   rh  z,_configure_imagegen_model.<locals>.<genexpr>  =      RR1#gajnn["==>>RRRRRRrS   r   rq  rr  rs  r9  Modelrp  Speedrr  	Strengthsrs    Price     ← currently in use	  Choose ri   model:  Model set to: )IMAGEGEN_BACKENDSrI   r  rM  ru  r^   keysmaxrJ  r   r   rN  ru  rb   r  r   )rv  r=  r0  default_modelcfg_keycur_cfg	model_idsorderedrn  headerr  midr  r-  r  r  r{  s                  @@rK   _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../////rS   rZ  c                    	 ddl m} ddlm}  |              ||           }n# t          $ r i dfcY S w xY w|i dfS 	 |                                pg }|                                }n# t          $ r i dfcY S w xY wd |D             }||fS )ua  Return ``(catalog_dict, default_model_id)`` for a plugin provider.

    ``catalog_dict`` is shaped like the legacy ``FAL_MODELS`` table —
    ``{model_id: {"display", "speed", "strengths", "price", ...}}`` —
    so the existing picker code paths work without change. Returns
    ``({}, None)`` if the provider isn't registered or has no models.
    r   get_providerr  Nc                 R    i | ]$}t          |t                    d |v |d          |%S idrM  ru  r  s     rK   rr   z-_plugin_image_gen_catalog.<locals>.<dictcomp>3  2    OOOaZ4-@-@OTQYYqwYYYrS   )r  r  r`   r  rB   list_modelsr  rZ  r  r  r  modelsr   r  s          rK   _plugin_image_gen_catalogr    s    999999AAAAAA""$$$<,,   4x4x%%''-2((**   4xOO6OOOGG   !$ 55*A* *A;:A;c           	         t          |           \  }sdS |                    di           }t          |t                    si }||d<   |                    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<   t          d|            dS )zPrompt the user to pick a model for a plugin-registered backend.

    Writes selection to ``image_gen.model``. Mirrors
    :func:`_configure_imagegen_model` but sources its catalog from the
    plugin registry instead of :data:`IMAGEGEN_BACKENDS`.
    Nr#   rq  c                      g | ]
}|k    |S rV   rV   ry  s     rK   r]  z8_configure_imagegen_model_for_plugin.<locals>.<listcomp>K  r|  rS   c              3   4   K   | ]}t          |          V  d S rf  r~  r  s     rK   rh  z7_configure_imagegen_model_for_plugin.<locals>.<genexpr>N  r  rS   c              3   j   K   | ]-}t          |                             d d                    V  .dS r  r  r  s     rK   rh  z7_configure_imagegen_model_for_plugin.<locals>.<genexpr>O  r  rS   r  rt  c              3   j   K   | ]-}t          |                             d d                    V  .dS r  r  r  s     rK   rh  z7_configure_imagegen_model_for_plugin.<locals>.<genexpr>P  r  rS   r   r  r9  r  rp  r  rr  r  rs  r  r  r  r  r  )r  r  rM  ru  rI   r^   r  r  rJ  r   r   rN  ru  rb   r  r   )rZ  r=  r  r  r  r  rn  r  r  r  r  r-  r  r  r{  s                @@rK   $_configure_imagegen_model_for_pluginr  7  sq    7{CCG] R00Ggt$$ &%{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
(K(((  C S\FGG.f../////rS   c                     |                     di           }t          |t                    si }||d<   | |d<   d|d<   t          d|             t	          | |           dS )z<Persist a plugin-backed image generation provider selection.r#   r  FrY  z  image_gen.provider set to: N)r  rM  ru  r   r  )rZ  r=  img_cfgs      rK   !_select_plugin_image_gen_providerr  n  y    R00Ggt$$ &%{%GJ"GM@;@@AAA(f=====rS   c                    	 ddl m} ddlm}  |              ||           }n# t          $ r i dfcY S w xY w|i dfS 	 |                                pg }|                                }n# t          $ r i dfcY S w xY wd |D             }||fS )zReturn ``(catalog_dict, default_model_id)`` for a video gen plugin.

    Mirrors :func:`_plugin_image_gen_catalog`. Returns ``({}, None)`` when
    the plugin isn't registered or has no models.
    r   r  r  Nc                 R    i | ]$}t          |t                    d |v |d          |%S r  r  r  s     rK   rr   z-_plugin_video_gen_catalog.<locals>.<dictcomp>  r  rS   )r  r  r`   r  rB   r  r  r  s          rK   _plugin_video_gen_catalogr  }  s    999999AAAAAA""$$$<,,   4x4x%%''-2((**   4xOO6OOOGGr  c                 6   t          |           \  }sdS |                    di           }t          |t                    si }||d<   |                    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 ]}	|	         }
d|	d|d          d|
                    dd          d|d          d|
                    dd          d|d          d|
                    dd           }|	k    r|dz  }|                    |           t          d|  d|d
          }||         }||d<   t          d|            dS )zPrompt for a video gen model from a plugin's catalog.

    Mirrors :func:`_configure_imagegen_model_for_plugin`. Writes the
    selection to ``video_gen.model``.
    Nr%   rq  c                      g | ]
}|k    |S rV   rV   ry  s     rK   r]  z8_configure_videogen_model_for_plugin.<locals>.<listcomp>  r|  rS   c              3   4   K   | ]}t          |          V  d S rf  r~  r  s     rK   rh  z7_configure_videogen_model_for_plugin.<locals>.<genexpr>  r  rS   c              3   j   K   | ]-}t          |                             d d                    V  .dS r  r  r  s     rK   rh  z7_configure_videogen_model_for_plugin.<locals>.<genexpr>  r  rS   r  rt  c              3   j   K   | ]-}t          |                             d d                    V  .dS r  r  r  s     rK   rh  z7_configure_videogen_model_for_plugin.<locals>.<genexpr>  r  rS   r   r  r9  r  rp  r  rr  r  rs  r  r@   rt  r  r  r  r  )r  r  rM  ru  rI   r^   r  r  rJ  r   r   rN  rb   r  r   )rZ  r=  r  r  r  r  rn  r  r  r  rm  r  r-  r  r  r{  s                 @@rK   $_configure_videogen_model_for_pluginr    s    7{CCG] R00Ggt$$ &%{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 
 
s|' 'vg '+ ' 'xx$$''-g';' 'xxR(('+1++>'C' ' xx$$' ' 	 -++CC
(K(((  C S\FGG.f../////rS   c                     |                     di           }t          |t                    si }||d<   | |d<   d|d<   t          d|             t	          | |           dS )z<Persist a plugin-backed video generation provider selection.r%   r  FrY  z  video_gen.provider set to: N)r  rM  ru  r   r  )rZ  r=  vid_cfgs      rK   !_select_plugin_video_gen_providerr    r  rS   c           	      
   |                      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          }|rt          ||           dS |                      d          }|rWt          ||           |                    d i           }t          |t                    r|                     d          d!vrd"|d<   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                    |rt          d| d          d.           |                      d          }|rt          ||           dS |                      d          }|rt          ||           dS |                      d          }|r[t          ||           |                    d i           }t          |t                    r"|                     d          d!vrd"|d<   dS dS dS dS dS )/zAConfigure a single provider - prompt for API keys and set config.rz   r}   r|   E  Nous Subscription is only available after logging into Nous Portal.Nr{   r)   r  rY  r   r   r   r1    Browser set to local mode!  Browser cloud provider set to: r   r   r0    Web backend set to: >   r)   r   r   Tr   Fr   r9  rw    - no configuration needed!B  Requests for this tool will be billed to your Nous subscription.r  r  r   r#   >   Nr@   r   r   r   z: already configuredr   r@     Get yours at: r   r   r   r  	    Saved    Skippedz configured!)rI   r   r&  r   r  rF   r   r  r  rM  ru  r/  r   r  r  r  r   _promptr   )r  r=  rz   r^  r  r3  bpr5  r4  cat_keyr  sectionrZ  video_pluginr0  r  all_configuredr  existingr   default_valrO  s                         rK   rO  rO    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 	^\]]] ll#:;; 	-k6BBBF  ||$;<< 	-lFCCCF,,122 	,%gv666 ''R88G'4(( ,W[[-D-DL]-]-]&+
# 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./// ,:HV,:::;;;ll#:;; 	-k6BBBF||$;<< 	-lFCCCF,,122 	,%gv666''R88G'4(( ,W[[-D-DL]-]-]&+
###!, ,	, 	,, ,-]-]rS   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}t          |          dk    }|rdnd}t          |d
          }|r|                                rt          d|                                           t                      }|                    di                               di           }	||	d<   t          |           |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 keyrv   	auxiliarybase_urlAUXILIARY_VISION_MODELzgpt-4o-minic                 :    g | ]\  }}t          |          ||fS rV   r>   )rX   r  r   s      rK   r]  z2_configure_simple_requirements.<locals>.<listcomp>	  s-    QQQhc3mC>P>PQSzQQQrS   c              3   0   K   | ]\  }}}|k    |V  d S rf  rV   rX   rp   r  rY   rN   s       rK   rh  z1_configure_simple_requirements.<locals>.<genexpr>	  5      \\71aPQU[P[P[QP[P[P[P[\\rS   r9  z requires configuration:  Get key at: r   )r  rJ  r   r   YELLOWr  r   r  rE   r   r   r   r   r	   r  r
   r  rI   nextrf   )rN   r  r-  rO  r  is_native_openai	key_labelr.  _cfg_auxr  missingr  r  r   s   `              rK   r  r  _	  s>   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oToH0::>NN0@S,,mIi$777G .7==?? ./AAA"}}{B77BB8RPP#+Z D!!!# L"#;]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...;''''=))))* *rS   c                    g }t                      D ]u\  }}}t                              |          }t                              |          }|s|r7t	          ||           st          ||           r|                    ||f           v|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 rV   rV   )rX   rY   rn   s      rK   r]  z%_reconfigure_tool.<locals>.<listcomp>	  s    222Eu222rS   Cancelz+  Which tool would you like to reconfigure?r   )rf   r  rI   r  r   _toolset_enabled_for_reconfigurerb   r   r  r  %_configure_tool_category_for_reconfig _reconfigure_simple_requirementsr
   )	r=  configurablerN   r  rY   r  reqsr  r-  s	            rK   _reconfigure_toolr  	  sv    LCEE 8 8!!!&))'++F33 	8$ 	8 00 84TU[]c4d4d 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rS   c                     t           D ]>}t          | |          s	 t          ||d          }n# t          $ r Y 3w xY w| |v r dS ?dS )zReturn True if a configurable toolset is enabled anywhere.

    Reconfigure must include enabled-but-unconfigured categories so users can
    finish provider/API-key setup without disabling and re-enabling the toolset.
    FrR  T)rk   rR   r@  rB   )rN   r=  rO   r;  s       rK   r  r  	  s       ,VX>> 		),1  GG
  	 	 	H	W44 5s   /
<<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.r   r@   rw   r   r   r;  r<  r=  r>  z - Choose a provider ---rx   r?  r@  ry   rA  rz   c              3   @   K   | ]}t          |d                    V  dS r  r>   rC  s     rK   rh  z8_configure_tool_category_for_reconfig.<locals>.<genexpr>	  rE  rS   rF  rG  z  Select provider:N)rI   r  r  rJ  r   r   rN  _reconfigure_providerr  rP  rb   rQ  r  )rN   r  r=  r   rw   r   r  rT  rc  rx   ry   rU  rz   rV  rW  s                  rK   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>>>>>rS   c           	      
   |                      dg           }|                      d          }|                      d          r't          |          }|j        st          d           dS |                      d          rK|                    di           }| d         |d<   t          |          |d	<   t          d
| 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r8|                    |i           }	t          |	t                    si }	|	||<   d|	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          }|rt          ||           dS |                      d           }|rKt          ||           |d!k    r5|                    d"i           }t          |t                    r
d!|d<   d|d	<   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          d0           |                      d          rt          | d                    |                      d          }|rt          ||           dS |                      d          }|rt          ||           dS |                      d           }|rMt          ||           |d!k    r9|                    d"i           }t          |t                    rd!|d<   d|d	<   dS dS dS dS )1z)Reconfigure a provider - update API keys.rz   r}   r|   r  Nr{   r)   r  rY  z  TTS provider set to: r   r   r   r1  r  r  r   r   r0  r  >   r)   r   r   Tr   Fr   r9  rw   r  r  r  r  r   r   r#   r   : configured (   ...)r   r@   r  r   r   r    (Enter to keep current)r      Updated    Kept current)rI   r   r&  r   r  rF   r   rM  ru  r  r  r/  r   r  r  r  r   r  rE   r   )r  r=  rz   r^  r  r3  r  r5  r4  r  r  r  rZ  r  r0  r  r  r  r   r  rO  s                        rK   r  r  	  s    ||J++Hll#9::O||()) 1&99) 	bcccF||N## M##E2..&~6
!%o!6!6K.1IKKLLL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##OR88'4(( 	.G&-F?#!% +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 	^\]]]ll#:;; 	-k6BBBF||$;<< 	-lFCCCF,,122 	3%gv666% ++K<<gt,, 3*/GJ'-2GM* , , 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=))))*++++||L!! 0./// ,,677K )+v>>> << 788L ),???ll-..G /!'6222e''R88G'4(( /&+
#).&&&/ // /rS   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 rf  rV   r  s       rK   rh  z3_reconfigure_simple_requirements.<locals>.<genexpr>t
  r  rS   r9  rH  r  r  r  r  r   r  Tr  r  r  )r  rI   r  rf   rJ  r   r   rN  r   r   r  rE   r   r   )rN   r  r  r  r   r  rO  s   `      rK   r  r  n
  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...=))))*++++, ,rS   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().
    NrA  Fu   ⚕ Tool Summaryr9  rn   r  /r  c              3   0   K   | ]\  }}}|k    |V  d S rf  rV   r  s       rK   rh  z tools_command.<locals>.<genexpr>
  5      !i!i1a]^bh]h]h!]h]h]h]h!i!irS   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/toolsrR  c              3   0   K   | ]\  }}}|k    |V  d S rf  rV   rX   rp   r  rY   r\  s       rK   rh  z tools_command.<locals>.<genexpr>
  5      !e!e1a]^bd]d]d!]d]d]d]d!e!erS   z  + c              3   0   K   | ]\  }}}|k    |V  d S rf  rV   r  s       rK   rh  z tools_command.<locals>.<genexpr>
  r  rS   z  - )r  c              3   0   K   | ]\  }}}|k    |V  d S rf  rV   r  s       rK   rh  z tools_command.<locals>.<genexpr>
  s.      !X!X1aAQWKK!KKKK!X!XrS   u     ✓ z': using your Nous subscription defaultsc                     g | ]<}t                               |          st                              |          r|v:|=S rV   )r  rI   r  )rX   rN   auto_configureds     rK   r]  z!tools_command.<locals>.<listcomp>
  s]       !#''//3K3O3OPV3W3W /11 111rS   z  Configuring z	 tool(s):c              3   0   K   | ]\  }}}|k    |V  d S rf  rV   r  s       rK   rh  z tools_command.<locals>.<genexpr>
  r   rS   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 keyrr  zConfigure MCP server toolsDoner   r  TzSelect an option:rt  zAll platformsrH  c              3   0   K   | ]\  }}}|k    |V  d S rf  rV   r  s       rK   rh  z tools_command.<locals>.<genexpr>.  5      )m)m1aefjlelel!elelelel)m)mrS   z    + c              3   0   K   | ]\  }}}|k    |V  d S rf  rV   r  s       rK   rh  z tools_command.<locals>.<genexpr>1  r  rS   z    - u+     ✓ Saved configuration for all platformsz  No changesc              3   0   K   | ]\  }}}|k    |V  d S rf  rV   r  s       rK   rh  z tools_command.<locals>.<genexpr>T  r  rS   c              3   0   K   | ]\  }}}|k    |V  d S rf  rV   r  s       rK   rh  z tools_command.<locals>.<genexpr>X  r  rS   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<  rJ  r  r  rf   r   r   rN  BOLDrC  rk   rI   ri   DIMr  r  GREENr@  r  r  REDr   r   r_   r  r  r  r
   rb   rF   r  r   _configure_mcp_tools_interactiver  r  r6  r  r  r   )$r   r  r=  enabled_platformsr  rA  rB  pinfor;  countrn   current_enabledchecklist_preselectednew_enabledaddedremovedto_configureplatform_choicesplatform_keysr`  _has_mcp_global_idx_reconfig_idx_mcp_idx	_done_idxr-  all_currentpkprevpinfo_innerci	new_countr   r  r\  rN   s$                                    @@@rK   tools_commandr+  
  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[_``K/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	GGGGGrS   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   r  rr  zNo MCP servers configured.Nc                 H    g | ]\  }}|                     d d          dv| S )r;  T>   FrI  rJ  rK  rL  r  )rX   rp   rD  s      rK   r]  z4_configure_mcp_tools_interactive.<locals>.<listcomp>  s@       a55D!!)KKK 	
KKKrS   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 rV   rV   )rX   nserver_toolss     rK   r]  z4_configure_mcp_tools_interactive.<locals>.<listcomp>  s#    @@@A!<*?*?a*?*?*?rS   z  Could not connect to ''c              3   4   K   | ]}t          |          V  d S rf  r~  )rX   toolss     rK   rh  z3_configure_mcp_tools_interactive.<locals>.<genexpr>  s(      DDUc%jjDDDDDDrS   z  Found z tool(s) across z
 server(s)Fr9  z: no tools foundr5  includeexcludeF   z...r  r  c                     g | ]
}|d          S r  rV   rX   ts     rK   r]  z4_configure_mcp_tools_interactive.<locals>.<listcomp>  s    ***qad***rS   zMCP Server: z tools))r  z: no changesc                 (    g | ]}|v|         S rV   rV   )rX   r  r  
tool_namess     rK   r]  z4_configure_mcp_tools_interactive.<locals>.<listcomp>  s#    XXXQWz!}rS   : z
 enabled, z	 disabledTu"     ✓ MCP tool configuration savedz  No changes to MCP tools)r  r  rI   r   r  rJ  r   r   r  r  joinr  tools.mcp_toolr/  rB   rK  r   r  r|  r  rb   ri   r  ra   ranger  popr   r
   )r=  r  rr  enabled_namesr/  r!  failedrw   total_toolsany_changesserver_namer5  srv_cfg	tools_cfginclude_listexclude_listr  	tool_namedescription
desc_shortr  r  new_excludeenabled_countdisabled_countr  r2  r=  s                            @@@rK   r  r  x  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.FrR  disableN)r@  ri   r  )r=  rO   r  rR  r;  updateds         rK   _apply_toolset_changerV    s`    !&(PUVVVGC...C...733333rS   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.
    rr  rH  r   r5  r7  rT  c                      g | ]
}|k    |S rV   rV   )rX   r;  rL  s     rK   r]  z%_apply_mcp_change.<locals>.<listcomp>  s    <<<QQ)^^q^^^rS   )ri   rI   splitra   r  r^   rb   )
r=  rW  rR  failed_serversrr  targetrG  rI  r7  rL  s
            @rK   _apply_mcp_changer]    s    
  #uuN**]++1rK ' '!'c1!5!5Yk)){+++,77DD	y}}Y//5266Y''y)))<<<<'<<<G&	)rS   r  rr  c                    t                      }fd|D             }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                 B    g | ]\  }}}t          |          |||fS rV   rj  r  s       rK   r]  z%_print_tools_list.<locals>.<listcomp>!  r  rS   c                     h | ]\  }}}|	S rV   rV   rW   s      rK   rZ   z$_print_tools_list.<locals>.<setcomp>%  s    EEE|vq!FEEErS   zBuilt-in toolsets (z):u   ✓ enabledu   ✗ disabledr9  c                 (    g | ]\  }}}|v
||fS rV   rV   )rX   rp   r  rY   builtin_keyss       rK   r]  z%_print_tools_list.<locals>.<listcomp>0  s-    OOOAq,9N9Nq!f9N9N9NrS   zPlugin toolsets (zMCP servers:r5  r7  r6  z  [include only: r.  r@  z  [excluded: zall tools enabledN)rf   r_   rJ  r   r   r  r  r  r  rI   r   r?  r  )r  rr  rO   r  r  rN   rn   rY   statusplugin_entriessrv_namerH  rI  r7  r6  rb  s     `            @rK   _print_tools_listrf    s   8::M   #0  I F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rS   c                 z   | 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             }fd|D             rtD ]c}t          t                              |          pt                                }t	          d| d dd                    |           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``).
    rO   r1  zUnknown platform 'z
'. Valid: r.  Nr^   FrR  rr  c                     g | ]}d |v|	S rH  rV   r:  s     rK   r]  z0tools_disable_enable_command.<locals>.<listcomp>\  s    :::QS\\q\\\rS   c                     g | ]}d |v |	S ri  rV   r:  s     rK   r]  z0tools_disable_enable_command.<locals>.<listcomp>]  s    2221rS   c                     h | ]\  }}}|	S rV   rV   rW   s      rK   rZ   z/tools_disable_enable_command.<locals>.<setcomp>_  s    GGGAfGGGrS   c                     g | ]}|v|	S rV   rV   rX   r;  valid_toolsetss     rK   r]  z0tools_disable_enable_command.<locals>.<listcomp>`  s#    NNNaa~6M6M6M6M6MrS   zUnknown toolset 'r3  c                     g | ]}|v |	S rV   rV   rm  s     rK   r]  z0tools_disable_enable_command.<locals>.<listcomp>d  s#    MMMn9L9L19L9L9LrS   c                 4    g | ]}t          |          |S rV   rj  )rX   r;  rO   s     rK   r]  z0tools_disable_enable_command.<locals>.<listcomp>g  s9       ,Q99	  rS   z	Toolset 'z ' is not available on platform 'z	' (only: r  c                     g | ]}|v|	S rV   rV   )rX   r;  restricted_targetss     rK   r]  z0tools_disable_enable_command.<locals>.<listcomp>r  s$    UUUBT9T9T19T9T9TrS   zMCP server 'z' not found in configc                 ^    g | ])}|vd |vs|                     d           d         v'|*S )rH  r   )rZ  )rX   r;  r[  unknown_toolsetss     rK   r]  z0tools_disable_enable_command.<locals>.<listcomp>  sP       $$$#Q,,!''#,,q/Q_:_:_ 	
:_:_:_rS   rT  DisabledEnabledr>  )tools_actionr  r	   rk   rK  r?  rf  r@  rI   namesr_   rj   r  rM   ri   rV  r]  r
   r   )r   rR  r=  rW  toolset_targetsmcp_targetsrw   rQ   srv
successfulverbr[  rO   rr  rt  rn  s              @@@@@rK   tools_disable_enable_commandr~  H  s=    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   "    V& 	 	D;??EENOOG0D 0 0( 0 0))G,,0 0 0    VUUUoUUU 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:::::; ;rS   )F)r   Trf  )Tr  )r1  )NFN)x__doc__jsonr  loggingrG   r   r   r   pathlibr   typingr   r   r   r   r  r   r	   r
   r   r   hermes_cli.colorsr   r   hermes_cli.nous_subscriptionr   r   tools.tool_backend_helpersr   r   utilsr   r   	getLogger__name__r  __file__r   resolver  hermes_cli.cli_outputr   rK  r   r   r   r   r   r   r   r  r_   r  rF   rL   rM   rD   __annotations__rR   rf   ri   rj   hermes_cli.platformsrk   _PLATFORMS_REGISTRYr  r  r  rN  r   r   r   r/  r<  ru  rC  rQ  r@  r  r  r^   r  r  r  r  r  r  r  r  r$  r  r+  r.  r6  r  rP  rQ  rh  r  ru  r  r  r  r  r  r  r  rO  r  r  r  r  r  r  r+  r  rV  r]  rf  r~  rV   rS   rK   <module>r     s  	 	 	      				      



       , , , , , , , , , , , ,              , + + + + + + +        Y X X X X X X X 4 4 4 4 4 4 4 4		8	$	$tH~~$+3355
                V zyy B$ B B B BB {[7 7 S#c(] 3   2# 2 2 2 2 2 2  4#     B A A A A A ,&,..  	 ! ,'G (&*(-&>@P%Q	 	 -28 &  %,4@PY  A  A !)  "K %(  %,0<P  ZG  H  H !-  ,"E,8HQyzz !)  $(G +)   (I '% G
K KZ '/{ ,'F*&*(-&9;N%O	 	 0.A*/;vww 
# #J # ,'Q&*(3&/[$)	 	 !Y%Gfgg %* 
 4 #
   %5C  B'O(  &?  -"/6 	 
   D % @'H$1&*(1&;%<-
 
 (2=$+-  "(B)5IVmGI I %.'
 
)
. .`  )-(4\]]&2FStuu 	
   *>'	 
  '! 2;L
 + 
	 {R Rn JJIJ   	A A A
s)A A 	A A A AHT T T T T T Tn$ $S $$ $RV $ $ $ $NZC Z Z Z ZH
S	      d xS	7J VZ[^`cdg`h[hVi           * )-	e e eee "&	e
 	Xe e e eP5 5 5CPSH 5 5 5 5p#> #>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1- 1-c 1-CH 1-PS 1-`cdg`h 1- 1- 1- 1-l/s /D / / / /+T$Z + + + +\#T$Z # # # #`-d4j - - - -p,4: , , , ,^%D %$ %4: % % % %l :: t   $
# 
$ 
 
 
 
=1 =1T =1d =1 =1 =1 =1@A=S A=t A=T A= A= A= A=H:$ : : : : : :z	T 	4 	C 	 	 	 	2% % % 
!(   D $ 3    ;0C ;0 ;0$ ;0 ;0 ;0 ;0|3    640c 404 40D 40 40 40 40n	>3 	> 	> 	> 	> 	> 	>3    290c 904 90D 90 90 90 90x	>3 	> 	> 	> 	> 	> 	>~,$ ~, ~, ~, ~, ~,B<*3 <* <* <* <*~d    DS $ 4    ,"?# "?D "?$ "? "? "? "?Jp/D p/$ p/ p/ p/ p/f,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T=; =; =; =; =;rS   