feat: Update hanzo to v0.2.12 with hanzo-net v0.1.6

- Update dependency to hanzo-net>=0.1.6 for QR code and mobile support
- Fix async event loop handling in net command
- Support for mobile devices joining network via QR code
This commit is contained in:
2025-08-08 16:23:55 -05:00
parent 8f5c4b4cd0
commit 3cc297bd74
5 changed files with 124 additions and 44 deletions
+49
View File
@@ -1,5 +1,54 @@
# Changelog
## [0.2.10] - 2024-08-07
### Dependencies
- Updated to hanzo-net v0.1.2
### Improvements in hanzo-net v0.1.2
- Fixed async event loop issues ("coroutine 'main' was never awaited")
- Removed "tinychat" branding - now shows "Hanzo Chat"
- Proper handling when called from existing async context
- Fixed "Cannot run the event loop while another loop is running" error
## [0.2.9] - 2024-08-07
### Fixed
- Fixed `hanzo net` command to properly pass arguments to hanzo-net
- Resolved argparse conflict when importing net module
- Improved handling of command-line arguments for both installed and source versions
## [0.2.8] - 2024-08-07
### Changed
- Main command to run Hanzo Network is now `hanzo net` (was `hanzo node`)
- `hanzo node` remains as an alias for backward compatibility
### Notes
- Use `hanzo net` to start the distributed AI compute node
- Use `hanzo network` for agent network management commands
## [0.2.7] - 2024-08-06
### Major Update
- hanzo-net is now published to PyPI! Install with: `pip install hanzo-net`
- No longer requires local installation from GitHub
- Full remote support for distributed AI compute nodes
### Improvements in hanzo-net v0.1.0 (now on PyPI)
- Changed "Exo Cluster" to "Hanzo Network" branding
- Removed "tinychat" label from Web Chat URL
- New HANZO ASCII art instead of exo branding
- Fixed model import path (resolves "Model type llama not supported" error)
- Fully responsive CLI interface that adapts to terminal width
- Dynamic centering of all UI elements
- Adaptive text formatting for narrow terminals
### hanzo CLI Updates
- Improved dependency checking for hanzo/net
- Better error messages when hanzo/net is not found
- Automatic detection of hanzo/net venv
## [0.2.6] - 2024-08-06
### Added
+2 -1
View File
@@ -1,6 +1,6 @@
[project]
name = "hanzo"
version = "0.2.6"
version = "0.2.12"
description = "Hanzo AI - Complete AI Infrastructure Platform with CLI, Router, MCP, and Agent Runtime"
authors = [
{name = "Hanzo AI", email = "[email protected]"},
@@ -13,6 +13,7 @@ dependencies = [
"httpx>=0.23.0",
"pydantic>=2.0.0",
"pyyaml>=6.0",
"hanzo-net>=0.1.6",
]
readme = "README.md"
requires-python = ">= 3.8"
+1 -1
View File
@@ -1,6 +1,6 @@
"""Hanzo - Complete AI Infrastructure Platform with CLI, Router, MCP, and Agent Runtime."""
__version__ = "0.2.6"
__version__ = "0.2.12"
__all__ = ["main", "cli"]
from .cli import main, cli
+63 -35
View File
@@ -12,7 +12,7 @@ from .interactive.repl import HanzoREPL
from .utils.output import console
# Version
__version__ = "0.2.6"
__version__ = "0.2.10"
@click.group(invoke_without_command=True)
@@ -88,6 +88,18 @@ def serve(ctx, name: str, port: int):
asyncio.run(cluster.start_cluster(ctx, name, port))
@cli.command()
@click.option("--name", "-n", help="Node name (auto-generated if not provided)")
@click.option("--port", "-p", default=52415, help="Node port (default: 52415 for hanzo/net)")
@click.option("--network", default="local", help="Network to join (mainnet/testnet/local)")
@click.option("--models", "-m", multiple=True, help="Models to serve (e.g., llama-3.2-3b)")
@click.option("--max-jobs", type=int, default=10, help="Max concurrent jobs")
@click.pass_context
def net(ctx, name: str, port: int, network: str, models: tuple, max_jobs: int):
"""Start the Hanzo Network distributed AI compute node."""
asyncio.run(start_compute_node(ctx, name, port, network, models, max_jobs))
@cli.command()
@click.option("--name", "-n", help="Node name (auto-generated if not provided)")
@click.option("--port", "-p", default=52415, help="Node port (default: 52415 for hanzo/net)")
@@ -96,7 +108,7 @@ def serve(ctx, name: str, port: int):
@click.option("--max-jobs", type=int, default=10, help="Max concurrent jobs")
@click.pass_context
def node(ctx, name: str, port: int, network: str, models: tuple, max_jobs: int):
"""Start as a compute node for the Hanzo network using hanzo/net."""
"""Alias for 'hanzo net' - Start as a compute node for the Hanzo network."""
asyncio.run(start_compute_node(ctx, name, port, network, models, max_jobs))
@@ -116,18 +128,12 @@ async def start_compute_node(ctx, name: str = None, port: int = 52415,
is_available, net_path, python_exe = check_net_installation()
if not is_available:
console.print("[red]Error:[/red] hanzo/net is not properly configured")
if net_path:
console.print(f"Found hanzo/net at {net_path} but dependencies are missing")
missing = get_missing_dependencies(python_exe)
if missing:
console.print(f"Missing packages: {', '.join(missing)}")
console.print("\nTo fix, run:")
console.print(f" cd {net_path} && pip install -e .")
else:
console.print("\nTo install hanzo/net:")
console.print(" git clone https://github.com/hanzoai/net.git ~/work/hanzo/net")
console.print(" cd ~/work/hanzo/net && pip install -e .")
console.print("[red]Error:[/red] hanzo-net is not installed")
console.print("\nTo install hanzo-net from PyPI:")
console.print(" pip install hanzo-net")
console.print("\nOr for development, clone from GitHub:")
console.print(" git clone https://github.com/hanzoai/net.git ~/work/hanzo/net")
console.print(" cd ~/work/hanzo/net && pip install -e .")
return
try:
@@ -140,26 +146,37 @@ async def start_compute_node(ctx, name: str = None, port: int = 52415,
# net is installed as a package
console.print("[green]✓[/green] Using installed hanzo/net")
# Import and run net
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.executable)), "lib", "python3.*/site-packages"))
from net.main import run as net_run
# Set up environment for net
if models:
os.environ["NET_MODELS"] = ",".join(models)
if name:
os.environ["NET_NODE_NAME"] = name
console.print(f"\n[green]✓[/green] Node initialized")
console.print(f" Port: {port}")
console.print(f" Models: {', '.join(models) if models else 'auto-detect'}")
console.print("\n[bold green]Hanzo Net is running![/bold green]")
console.print("WebUI: http://localhost:52415")
console.print("API: http://localhost:52415/v1/chat/completions")
console.print("\nPress Ctrl+C to stop\n")
# Run net
await net_run()
# Set up sys.argv for net's argparse
original_argv = sys.argv.copy()
try:
# Build argv for net
sys.argv = ["hanzo-net"] # Program name
# Add options
if port != 52415:
sys.argv.extend(["--chatgpt-api-port", str(port)])
if name:
sys.argv.extend(["--node-id", name])
if network != "local":
sys.argv.extend(["--discovery-module", network])
if models:
sys.argv.extend(["--default-model", models[0]])
# Import and run net
from net.main import run as net_run
console.print(f"\n[green]✓[/green] Node initialized")
console.print(f" Port: {port}")
console.print(f" Models: {', '.join(models) if models else 'auto-detect'}")
console.print("\n[bold green]Hanzo Net is running![/bold green]")
console.print("WebUI: http://localhost:52415")
console.print("API: http://localhost:52415/v1/chat/completions")
console.print("\nPress Ctrl+C to stop\n")
# Run net
await net_run()
finally:
sys.argv = original_argv
else:
# Run from source directory using the detected python_exe
console.print(f"[green]✓[/green] Using hanzo/net from {net_path}")
@@ -189,9 +206,20 @@ async def start_compute_node(ctx, name: str = None, port: int = 52415,
console.print("API: http://localhost:52415/v1/chat/completions")
console.print("\nPress Ctrl+C to stop\n")
# Build command line args
cmd_args = [python_exe, "-m", "net.main"]
if port != 52415:
cmd_args.extend(["--chatgpt-api-port", str(port)])
if name:
cmd_args.extend(["--node-id", name])
if network != "local":
cmd_args.extend(["--discovery-module", network])
if models:
cmd_args.extend(["--default-model", models[0]])
# Run net command with detected python
process = subprocess.run(
[python_exe, "-c", "from net.main import run; run()"],
cmd_args,
env=env,
check=False
)
+9 -7
View File
@@ -13,18 +13,20 @@ def check_net_installation() -> Tuple[bool, Optional[str], Optional[str]]:
Returns:
Tuple of (is_available, net_path, python_exe)
"""
# Check for hanzo/net in standard location
# First try to import as PyPI package (hanzo-net)
try:
import net
return True, None, sys.executable
except ImportError:
pass
# For development: check for hanzo/net in standard location
net_path = Path.home() / "work" / "hanzo" / "net"
if not net_path.exists():
net_path = Path("/Users/z/work/hanzo/net")
if not net_path.exists():
# Try to import as package
try:
import net
return True, None, sys.executable
except ImportError:
return False, None, None
return False, None, None
# Check for venv
venv_python = net_path / ".venv" / "bin" / "python"