Enhance tool availability checks and user feedback in CLI

- Updated the CLI to include a new method for displaying warnings about disabled tools due to missing API keys.
- Integrated tool availability checks into the setup wizard and doctor commands, providing users with clear information on which tools are available and what is required for full functionality.
- Improved user prompts and feedback regarding API key configuration, emphasizing the importance of setting up keys for certain tools.
- Added detailed summaries of tool availability during setup and diagnostics, enhancing the overall user experience.
This commit is contained in:
teknium1
2026-02-02 19:28:27 -08:00
parent e87bee9ccd
commit bbb5776763
4 changed files with 307 additions and 25 deletions

View File

@@ -28,7 +28,8 @@ Usage:
import json
import asyncio
from typing import Dict, Any, List, Optional
import os
from typing import Dict, Any, List, Optional, Tuple
from tools.web_tools import web_search_tool, web_extract_tool, web_crawl_tool, check_firecrawl_api_key
from tools.terminal_tool import terminal_tool, check_terminal_requirements, TERMINAL_TOOL_DESCRIPTION, cleanup_vm
@@ -71,6 +72,131 @@ from toolsets import (
get_toolset_info, print_toolset_tree
)
# =============================================================================
# Tool Availability Checking
# =============================================================================
# Maps toolsets to their required API keys/environment variables
TOOLSET_REQUIREMENTS = {
"web": {
"name": "Web Search & Extract",
"env_vars": ["FIRECRAWL_API_KEY"],
"check_fn": check_firecrawl_api_key,
"setup_url": "https://firecrawl.dev/",
"tools": ["web_search", "web_extract"],
},
"vision": {
"name": "Vision (Image Analysis)",
"env_vars": ["OPENROUTER_API_KEY"],
"check_fn": check_vision_requirements,
"setup_url": "https://openrouter.ai/keys",
"tools": ["vision_analyze"],
},
"moa": {
"name": "Mixture of Agents",
"env_vars": ["OPENROUTER_API_KEY"],
"check_fn": check_moa_requirements,
"setup_url": "https://openrouter.ai/keys",
"tools": ["mixture_of_agents"],
},
"image_gen": {
"name": "Image Generation",
"env_vars": ["FAL_KEY"],
"check_fn": check_image_generation_requirements,
"setup_url": "https://fal.ai/",
"tools": ["image_generate"],
},
"browser": {
"name": "Browser Automation",
"env_vars": ["BROWSERBASE_API_KEY", "BROWSERBASE_PROJECT_ID"],
"check_fn": check_browser_requirements,
"setup_url": "https://browserbase.com/",
"tools": ["browser_navigate", "browser_snapshot", "browser_click", "browser_type"],
},
"terminal": {
"name": "Terminal/Command Execution",
"env_vars": [], # No API key required, just system dependencies
"check_fn": check_terminal_requirements,
"setup_url": None,
"tools": ["terminal"],
},
"skills": {
"name": "Skills Knowledge Base",
"env_vars": [], # Just needs skills directory
"check_fn": check_skills_requirements,
"setup_url": None,
"tools": ["skills_categories", "skills_list", "skill_view"],
},
}
def check_tool_availability(quiet: bool = False) -> Tuple[List[str], List[Dict[str, Any]]]:
"""
Check which tool categories are available based on API keys and requirements.
Returns:
Tuple containing:
- List of available toolset names
- List of dicts with info about unavailable toolsets and what's missing
"""
available = []
unavailable = []
for toolset_id, info in TOOLSET_REQUIREMENTS.items():
if info["check_fn"]():
available.append(toolset_id)
else:
# Figure out what's missing
missing_vars = [var for var in info["env_vars"] if not os.getenv(var)]
unavailable.append({
"id": toolset_id,
"name": info["name"],
"missing_vars": missing_vars,
"setup_url": info["setup_url"],
"tools": info["tools"],
})
return available, unavailable
def print_tool_availability_warnings(unavailable: List[Dict[str, Any]], prefix: str = ""):
"""Print warnings about unavailable tools."""
if not unavailable:
return
# Filter to only those missing API keys (not system dependencies)
api_key_missing = [u for u in unavailable if u["missing_vars"]]
if api_key_missing:
print(f"{prefix}⚠️ Some tools are disabled due to missing API keys:")
for item in api_key_missing:
vars_str = ", ".join(item["missing_vars"])
print(f"{prefix}{item['name']}: missing {vars_str}")
if item["setup_url"]:
print(f"{prefix} Get key at: {item['setup_url']}")
print(f"{prefix} Run 'hermes setup' to configure API keys")
print()
def get_tool_availability_summary() -> Dict[str, Any]:
"""
Get a summary of tool availability for display in status/doctor commands.
Returns:
Dict with 'available' and 'unavailable' lists of tool info
"""
available, unavailable = check_tool_availability()
return {
"available": [
{"id": tid, "name": TOOLSET_REQUIREMENTS[tid]["name"], "tools": TOOLSET_REQUIREMENTS[tid]["tools"]}
for tid in available
],
"unavailable": unavailable,
}
def get_web_tool_definitions() -> List[Dict[str, Any]]:
"""
Get tool definitions for web tools in OpenAI's expected format.