Skip to content

Latest commit

 

History

History
187 lines (144 loc) · 5.7 KB

File metadata and controls

187 lines (144 loc) · 5.7 KB

LLM.md - Hanzo Python SDK

Quick Start

uv sync --all-packages
uv run python -c "from hanzoai import __version__; print(__version__)"

Packages

Core (Workspace Members)

Package Import Description
hanzoai import hanzoai Official Hanzo API client
hanzo-mcp import hanzo_mcp MCP server with 39 tools
hanzo-memory import hanzo_memory Memory service with SQLite/vector
hanzo-repl import hanzo_repl Interactive REPL
hanzo-agent import hanzo_agent Agent framework

Tool Packages (Entry Points)

All tools discovered via [project.entry-points."hanzo.tools"]:

  • hanzo-tools-shell - zsh, ps, open, npx, uvx
  • hanzo-tools-browser - Playwright automation
  • hanzo-tools-fs - read, write, edit, tree, find, search, ast
  • hanzo-tools-memory - Unified memory tool
  • hanzo-tools-reasoning - think, critic
  • hanzo-tools-agent - CLI agent runner, iching, review
  • hanzo-tools-api - Generic REST API via OpenAPI
  • hanzo-tools-lsp - Language server protocol
  • hanzo-tools-refactor - AST-based refactoring
  • hanzo-tools-llm - LLM calls, consensus

Architecture

hanzo-mcp (thin wrapper)
  └── discovers tools via entry points from hanzo-tools-* packages

hanzo-tools-*
  └── each exports TOOLS list via entry point

Entry Point Pattern:

[project.entry-points."hanzo.tools"]
shell = "hanzo_tools.shell:TOOLS"

Key Patterns

Tool Registration

class MyTool(BaseTool):
    name = "my_tool"

    @property
    def description(self) -> str:
        return "Tool description"

    async def call(self, ctx, **params) -> str:
        pass

Async (Non-blocking)

# Use asyncio subprocess
proc = await asyncio.create_subprocess_exec(*cmd, stdout=PIPE, stderr=PIPE)
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=30)

# Use aiofiles for file I/O
async with aiofiles.open(path) as f:
    content = await f.read()

Auto-backgrounding

Commands auto-background after 45s. Use ps tool to monitor.

Memory System

SQLite-based with optional vector search (sqlite-vec).

~/.hanzo/
├── memory/           # Global markdown files
└── db/
    └── global.db     # SQLite with FTS5

/project/.hanzo/
├── memory/           # Project memories
└── db/
    └── memory.db     # Project database

Backends: local (default), sqlite, lancedb (optional), kuzudb (optional)

Browser Tool (hanzo-tools-browser)

Two-process architecture (since 0.5.0): hanzo-tools-browser hosts the ZAP server directly inside the MCP process. Browser extensions discover it on the lowest free port from [9999, 9998, 9997, 9996, 9995] (POSIX flock ensures multi-MCP coexistence under one ext).

from hanzo_tools.browser import (
    BrowserTool,            # the MCP tool
    ZapServer,              # raw server (for advanced use)
    get_or_start_server,    # bootstrap + return singleton
    get_server,             # return current singleton or None
)

Key files:

  • hanzo_tools/browser/zap_server.py — wire format, server, leases, cluster registry (~/.hanzo/extension/config.json:mcp_instances).
  • hanzo_tools/browser/browser_tool.py_extension_command tries ZAP first, falls back to legacy HTTP bridge on :9224. New actions list_mcp_instances, claim_browser, release_browser.
  • hanzo_tools/browser/cdp_bridge_server.py — legacy node-bridge replacement (kept for non-ZAP callers).

Env vars:

  • BROWSER_TRANSPORT=zap|http|auto — pin transport (default auto).
  • HANZO_ZAP_DISABLED=1 — don't auto-start the ZAP server.
  • HANZO_ZAP_PORTS=9999,9998 — override the candidate port list.
  • HANZO_AGENT_LABEL=... — attach to the cluster registry entry.
  • HANZO_CDP_BRIDGE_ENABLED=1 — opt back into the legacy HTTP bridge.

Tests live in pkg/hanzo-tools-browser/tests/test_zap_server.py (30 cases: wire format, lifecycle, RPC, leases, multi-MCP). Latency bench in test_zap_bench.py. The full suite runs with:

cd pkg/hanzo-tools-browser
uv venv .venv --python 3.12
.venv/bin/python -m pip install -e .
.venv/bin/python -m pytest tests/ -v

API Tool

Generic REST API tool with OpenAPI specs.

api(action="list")                                    # List providers
api(action="config", provider="github", api_key="x") # Configure
api(action="call", provider="github", operation="listRepos")

Auto-detects: GITHUB_TOKEN, CLOUDFLARE_API_TOKEN, OPENAI_API_KEY, etc.

Hanzo API Providers

All Hanzo services have unified OpenAPI specs at /Users/z/work/hanzo/openapi/:

Provider Service Base URL Spec
hanzo Unified API api.hanzo.ai hanzo.yaml
hanzo-iam Identity/Auth iam.hanzo.ai iam/openapi.yaml
hanzo-gateway LLM Gateway gateway.hanzo.ai gateway/openapi.yaml
hanzo-commerce E-commerce api.hanzo.ai/v1 commerce/openapi.yaml
hanzo-vector Vector DB vector.hanzo.ai vector/openapi.yaml
hanzo-cloud AI Platform cloud.hanzo.ai cloud/openapi.yaml
hanzo-nexus RAG/Knowledge nexus.hanzo.ai nexus/openapi.yaml
# Example: Call IAM API
api(action="spec", provider="hanzo-iam")
api(action="ops", provider="hanzo-iam", search="user")
api(action="call", provider="hanzo-iam", operation="getUser", params='{"id": "admin/user1"}')

Testing

uv run pytest tests/ -v
uv run python -c "from hanzoai import __version__; print(__version__)"

Common Issues

Import error: Run uv sync --all-packages

Missing tool: Check entry point in package's pyproject.toml

Backend not available: Install optional deps (lancedb, kuzu, sqlite-vec)