feat: add providers CLI command for managing AI providers
New commands: - smarttools providers list - List all providers with status - smarttools providers check - Check which providers are available - smarttools providers add <name> <command> - Add/update provider - smarttools providers remove <name> - Remove provider - smarttools providers test <name> - Test a provider Features: - Shows [+] for available, [-] for missing providers - Mock provider always shows as available (built-in) - Helpful installation hints when no providers found - Can add custom providers (Ollama, local scripts, etc.) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
f65d250973
commit
6abca22019
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from . import __version__
|
||||
from .tool import list_tools, load_tool, save_tool, delete_tool, Tool, ToolArgument, PromptStep, CodeStep
|
||||
from .ui import run_ui
|
||||
from .providers import load_providers, add_provider, delete_provider, Provider, call_provider
|
||||
|
||||
|
||||
def cmd_list(args):
|
||||
|
|
@ -336,6 +338,107 @@ echo "input" | {args.name}
|
|||
return 0
|
||||
|
||||
|
||||
def cmd_providers(args):
|
||||
"""Manage AI providers."""
|
||||
import shutil
|
||||
|
||||
if args.providers_cmd == "list":
|
||||
providers = load_providers()
|
||||
print(f"Configured providers ({len(providers)}):\n")
|
||||
for p in providers:
|
||||
# Mock provider is always available
|
||||
if p.name.lower() == "mock":
|
||||
print(f" [+] {p.name}")
|
||||
print(f" Command: (built-in)")
|
||||
print(f" Status: OK (always available)")
|
||||
if p.description:
|
||||
print(f" Info: {p.description}")
|
||||
print()
|
||||
continue
|
||||
|
||||
# Check if command exists
|
||||
cmd_parts = p.command.split()[0]
|
||||
cmd_expanded = cmd_parts.replace("$HOME", str(Path.home())).replace("~", str(Path.home()))
|
||||
exists = shutil.which(cmd_expanded) is not None or Path(cmd_expanded).exists()
|
||||
status = "OK" if exists else "NOT FOUND"
|
||||
status_icon = "+" if exists else "-"
|
||||
|
||||
print(f" [{status_icon}] {p.name}")
|
||||
print(f" Command: {p.command}")
|
||||
print(f" Status: {status}")
|
||||
if p.description:
|
||||
print(f" Info: {p.description}")
|
||||
print()
|
||||
return 0
|
||||
|
||||
elif args.providers_cmd == "add":
|
||||
name = args.name
|
||||
command = args.command
|
||||
description = args.description or ""
|
||||
|
||||
provider = Provider(name, command, description)
|
||||
add_provider(provider)
|
||||
print(f"Provider '{name}' added/updated.")
|
||||
return 0
|
||||
|
||||
elif args.providers_cmd == "remove":
|
||||
name = args.name
|
||||
if delete_provider(name):
|
||||
print(f"Provider '{name}' removed.")
|
||||
return 0
|
||||
else:
|
||||
print(f"Provider '{name}' not found.")
|
||||
return 1
|
||||
|
||||
elif args.providers_cmd == "test":
|
||||
name = args.name
|
||||
print(f"Testing provider '{name}'...")
|
||||
result = call_provider(name, "Say 'hello' and nothing else.", timeout=30)
|
||||
if result.success:
|
||||
print(f"SUCCESS: {result.text[:200]}...")
|
||||
else:
|
||||
print(f"FAILED: {result.error}")
|
||||
return 0 if result.success else 1
|
||||
|
||||
elif args.providers_cmd == "check":
|
||||
providers = load_providers()
|
||||
print("Checking all providers...\n")
|
||||
available = []
|
||||
missing = []
|
||||
|
||||
for p in providers:
|
||||
# Mock provider is always available (handled specially)
|
||||
if p.name.lower() == "mock":
|
||||
available.append(p.name)
|
||||
print(f" [+] {p.name}: OK (built-in)")
|
||||
continue
|
||||
|
||||
cmd_parts = p.command.split()[0]
|
||||
cmd_expanded = cmd_parts.replace("$HOME", str(Path.home())).replace("~", str(Path.home()))
|
||||
exists = shutil.which(cmd_expanded) is not None or Path(cmd_expanded).exists()
|
||||
|
||||
if exists:
|
||||
available.append(p.name)
|
||||
print(f" [+] {p.name}: OK")
|
||||
else:
|
||||
missing.append(p.name)
|
||||
print(f" [-] {p.name}: NOT FOUND ({cmd_parts})")
|
||||
|
||||
print(f"\nSummary: {len(available)} available, {len(missing)} missing")
|
||||
if len(available) == 1 and available[0] == "mock":
|
||||
print(f"\nNo real AI providers found. Install one of these:")
|
||||
print(f" - claude: npm install -g @anthropic-ai/claude-cli")
|
||||
print(f" - codex: pip install openai-codex")
|
||||
print(f" - gemini: pip install google-generative-ai")
|
||||
print(f"\nMeanwhile, use mock provider for testing:")
|
||||
print(f" echo 'test' | summarize --provider mock")
|
||||
elif missing:
|
||||
print(f"\nAvailable providers: {', '.join(available)}")
|
||||
return 0
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def main():
|
||||
"""Main CLI entry point."""
|
||||
parser = argparse.ArgumentParser(
|
||||
|
|
@ -405,6 +508,38 @@ def main():
|
|||
p_docs.add_argument("-e", "--edit", action="store_true", help="Edit/create README in $EDITOR")
|
||||
p_docs.set_defaults(func=cmd_docs)
|
||||
|
||||
# 'providers' command
|
||||
p_providers = subparsers.add_parser("providers", help="Manage AI providers")
|
||||
providers_sub = p_providers.add_subparsers(dest="providers_cmd", help="Provider commands")
|
||||
|
||||
# providers list
|
||||
p_prov_list = providers_sub.add_parser("list", help="List all providers and their status")
|
||||
p_prov_list.set_defaults(func=cmd_providers)
|
||||
|
||||
# providers check
|
||||
p_prov_check = providers_sub.add_parser("check", help="Check which providers are available")
|
||||
p_prov_check.set_defaults(func=cmd_providers)
|
||||
|
||||
# providers add
|
||||
p_prov_add = providers_sub.add_parser("add", help="Add or update a provider")
|
||||
p_prov_add.add_argument("name", help="Provider name")
|
||||
p_prov_add.add_argument("command", help="Command to run (e.g., 'claude -p')")
|
||||
p_prov_add.add_argument("-d", "--description", help="Provider description")
|
||||
p_prov_add.set_defaults(func=cmd_providers)
|
||||
|
||||
# providers remove
|
||||
p_prov_remove = providers_sub.add_parser("remove", help="Remove a provider")
|
||||
p_prov_remove.add_argument("name", help="Provider name")
|
||||
p_prov_remove.set_defaults(func=cmd_providers)
|
||||
|
||||
# providers test
|
||||
p_prov_test = providers_sub.add_parser("test", help="Test a provider")
|
||||
p_prov_test.add_argument("name", help="Provider name")
|
||||
p_prov_test.set_defaults(func=cmd_providers)
|
||||
|
||||
# Default for providers with no subcommand
|
||||
p_providers.set_defaults(func=lambda args: cmd_providers(args) if args.providers_cmd else (setattr(args, 'providers_cmd', 'list') or cmd_providers(args)))
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# If no command, launch UI
|
||||
|
|
|
|||
Loading…
Reference in New Issue