diff --git a/README.md b/README.md index 38eaad6f1..6ce48995b 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,12 @@ pip install . --use-feature=in-tree-build pytest tests ``` +## Local dev + +```sh +uv tool install --from "sunholo[cli]" sunholo --with ".[all]" +``` + ## Demos Using https://github.com/charmbracelet/vhs diff --git a/docs/docs/cli.md b/docs/docs/cli.md index e6e39c5a0..29d2c1d73 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -43,6 +43,9 @@ sunholo ### Upgrades and installing features ```bash +#uninstall +uv tool uninstall sunholo +#upgrade uv tool upgrade sunholo # install tool with Anthropic MCP uv tool install --from "sunholo[cli]" sunholo --with "sunholo[anthropic]" diff --git a/setup.py b/setup.py index c079d854d..e13a7f993 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = '0.116.1' +version = '0.116.2' setup( name='sunholo', diff --git a/sunholo/cli/cli.py b/sunholo/cli/cli.py index f43a369c2..30246b003 100644 --- a/sunholo/cli/cli.py +++ b/sunholo/cli/cli.py @@ -16,7 +16,6 @@ from ..senses.stream_voice import setup_tts_subparser from ..mcp.cli import setup_mcp_subparser - from ..utils import ConfigManager from ..utils.version import sunholo_version @@ -24,7 +23,7 @@ from .sun_rich import console import sys -from rich.panel import Panel + def load_default_gcp_config(): try: @@ -43,6 +42,7 @@ def __init__(self, option_strings, dest, nargs=0, **kwargs): super().__init__(option_strings, dest, nargs=nargs, **kwargs) def __call__(self, parser, namespace, values, option_string=None): + from rich.panel import Panel console.print( Panel("Welcome to Sunholo Command Line Interface, your assistant to deploy GenAI Virtual Agent Computers (VACs) to Multivac or your own Cloud.", title="Sunholo GenAIOps Assistant CLI", @@ -64,7 +64,7 @@ def main(args=None): """ default_project, default_region = load_default_gcp_config() - parser = argparse.ArgumentParser(description="sunholo CLI tool for deploying GenAI VACs 3", add_help=False) + parser = argparse.ArgumentParser(description=f"sunholo CLI tool for deploying GenAI VACs - [{sunholo_version()}]", add_help=False) parser.add_argument('-h', '--help', action=CustomHelpAction, help='Show this help message and exit') parser.add_argument('--debug', action='store_true', help='Enable debug output') parser.add_argument('--project', default=default_project, help='GCP project to list Cloud Run services from.') diff --git a/sunholo/mcp/cli.py b/sunholo/mcp/cli.py index 02988b66b..2fbde8920 100644 --- a/sunholo/mcp/cli.py +++ b/sunholo/mcp/cli.py @@ -3,6 +3,7 @@ from typing import Any, Sequence from functools import lru_cache import subprocess +from ..utils.version import sunholo_version try: from mcp.server import Server @@ -24,12 +25,10 @@ from pydantic import AnyUrl # Configure logging -import logging -logging.basicConfig(level=logging.DEBUG) -logger = logging.getLogger("sunholo-mcp") +from ..custom_logging import setup_logging +logger = setup_logging("sunholo-mcp") - -class SunholoMCPServer2: +class SunholoMCPServer: def __init__(self): logger.info("Initializing Sunholo MCP Server") @@ -58,8 +57,8 @@ async def list_resources() -> list[Resource]: """List available Sunholo resources""" return [ Resource( - uri="sunholo://vacs/list2", - name="Available Sunholo VACs 2", + uri="sunholo://vacs/list", + name="Available Sunholo VACs", mimeType="application/json", description="List of available Virtual Agent Computers" ) @@ -70,7 +69,7 @@ async def read_resource(uri: AnyUrl) -> str: """Read Sunholo resources based on URI""" logger.info(f"{uri} available") console.print(f"{uri} available") - if str(uri) == "sunholo://vacs/list2": + if str(uri) == "sunholo://vacs/list": try: # Execute sunholo vac list command result = subprocess.run( @@ -78,7 +77,6 @@ async def read_resource(uri: AnyUrl) -> str: capture_output=True, text=True ) - console.print(f"{result=}") return result.stdout except subprocess.CalledProcessError as e: raise RuntimeError(f"Failed to list VACs: {str(e)}") @@ -96,7 +94,7 @@ async def list_tools() -> list[Tool]: return [ Tool( name="chat_with_vac", - description="Chat with a specific Sunholo VAC2", + description="Chat with a specific Sunholo VAC", inputSchema={ "type": "object", "properties": { @@ -114,7 +112,7 @@ async def list_tools() -> list[Tool]: ), Tool( name="list_configs", - description="List Sunholo configurations2", + description="List Sunholo configurations", inputSchema={ "type": "object", "properties": { @@ -135,7 +133,7 @@ async def list_tools() -> list[Tool]: ), Tool( name="embed_content", - description="Embed content in a VAC's vector store2", + description="Embed content in a VAC's vector store", inputSchema={ "type": "object", "properties": { @@ -269,11 +267,16 @@ def cli_mcp(args): """CLI handler for the MCP server command""" try: + if not os.getenv("VAC_CONFIG_FOLDER"): + raise ValueError("sunholo configuration folder must be present in config/ or via VAC_CONFIG_FOLDER") + # Create and run the MCP server - server = SunholoMCPServer2() - - logger.info("Starting Sunholo MCP server3...") - console.print("Starting Sunholo MCP server3...") + server = SunholoMCPServer() + msg = {"message": "Starting Sunholo MCP server..."} + + logger.info(msg) + console.print(msg) + asyncio.run(server.run()) except Exception as e: @@ -292,6 +295,6 @@ def setup_mcp_subparser(subparsers): ``` """ mcp_parser = subparsers.add_parser('mcp', - help='Start an Anthropic MCP server that wraps `sunholo` functionality3') + help='Start an Anthropic MCP server that wraps `sunholo` functionality') mcp_parser.set_defaults(func=cli_mcp)