mirror of
https://github.com/hanzoai/python-sdk.git
synced 2026-10-23 20:23:00 +00:00
feat(hanzo-mcp): repo joins the default surface, on llm limits and typed plan refusals
This commit is contained in:
@@ -68,6 +68,7 @@ _PREFIX_TO_CATEGORY: dict[str, ToolCategory] = {
|
||||
"find": ToolCategory.search,
|
||||
"search": ToolCategory.search,
|
||||
"git": ToolCategory.vcs,
|
||||
"repo": ToolCategory.vcs,
|
||||
"think": ToolCategory.reasoning,
|
||||
"critic": ToolCategory.reasoning,
|
||||
"memory": ToolCategory.memory,
|
||||
|
||||
@@ -34,7 +34,7 @@ PACKAGE_TOOL_PREFIXES: dict[str, list[str]] = {
|
||||
"core": ["id"], # Identity axis (hash, uri, ref, verify)
|
||||
"code": ["code"], # Symbols + Structure axis (parse, transform, summarize)
|
||||
"shell": ["exec"], # Execution axis
|
||||
"vcs": ["git"], # History + Diffs axis
|
||||
"vcs": ["git", "repo"], # History + Diffs axis; repo is the Hanzo git side
|
||||
"test": ["test"], # Validation axis (check, build, test)
|
||||
"net": ["fetch"], # Network axis (search, fetch, download, crawl)
|
||||
"plan": ["plan"], # Orchestration axis (intent, route, compose)
|
||||
|
||||
@@ -107,6 +107,7 @@ ESSENTIAL_TOOLS = [
|
||||
"exec", # Execution (run, background, ps, kill, logs)
|
||||
"code", # Symbols + Semantics (parse, search, transform, summarize)
|
||||
"git", # Diffs + History
|
||||
"repo", # Repositories on Hanzo git linked to GitHub (list, sync now)
|
||||
"fetch", # Network (get, post, download)
|
||||
"plan", # Orchestration / intent
|
||||
# Knowledge persistence
|
||||
@@ -117,8 +118,8 @@ ESSENTIAL_TOOLS = [
|
||||
# Agent spawning
|
||||
"agent",
|
||||
# Models through Hanzo: completions Enso routes, the catalog with prices,
|
||||
# feedback (llm); typed questions to Kai (kai_decide). Both are HTTP calls
|
||||
# to api.hanzo.ai, with nothing heavy to install.
|
||||
# the plan's limits, feedback (llm); typed questions to Kai (kai_decide).
|
||||
# Both are HTTP calls to api.hanzo.ai, with nothing heavy to install.
|
||||
"llm",
|
||||
"kai_decide",
|
||||
# Hanzo cloud — one tool projecting every service from the OpenAPI registry.
|
||||
@@ -143,7 +144,7 @@ HEAVY_TOOLS = [
|
||||
# now points at the HIP-0300 axis tool that absorbs the legacy split.
|
||||
UNIX_TOOLS = ["exec"]
|
||||
BUILD_TOOLS = ["exec"]
|
||||
VERSION_CONTROL = ["git"]
|
||||
VERSION_CONTROL = ["git", "repo"]
|
||||
AI_TOOLS = ["agent", "consensus", "critic", "think", "llm"]
|
||||
SEARCH_TOOLS = ["code", "fs"]
|
||||
DATABASE_TOOLS = ["sql_query", "sql_search", "graph_add", "graph_query"]
|
||||
|
||||
@@ -77,7 +77,7 @@ class ToolListTool(BaseTool):
|
||||
("vector", "Semantic search (search/index/stats/clear)"),
|
||||
],
|
||||
"ai": [
|
||||
("llm", "Models through Hanzo: query (Enso routes), models (with prices), feedback"),
|
||||
("llm", "Models through Hanzo: query (Enso routes), models (search, class, price), limits, feedback"),
|
||||
("kai_decide", "Typed questions to Kai, Hanzo's decision model"),
|
||||
("agent", "AI agents (run/start/call/stop/list with A2A support)"),
|
||||
("swarm", "Parallel agent execution across multiple files"),
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "hanzo-mcp"
|
||||
version = "0.15.19"
|
||||
version = "0.15.20"
|
||||
description = "The Zen of Hanzo MCP: One server to rule them all. The ultimate MCP that orchestrates all others."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
@@ -18,8 +18,9 @@ classifiers = [
|
||||
keywords = ["mcp", "claude", "hanzo", "code", "agent"]
|
||||
dependencies = [
|
||||
# Hanzo AI core SDK (canonical types, config, session, MCP client)
|
||||
# 2.2.1 is the first release shipping hanzoai.protocols (permissions.py imports it)
|
||||
"hanzoai>=2.2.1",
|
||||
# 2.2.1 is the first release shipping hanzoai.protocols (permissions.py imports it);
|
||||
# 8.5.624 the first carrying hanzoai.usage, which the llm tools read refusals with
|
||||
"hanzoai>=8.5.624",
|
||||
# Core MCP dependencies
|
||||
"mcp>=1.25.0,<2",
|
||||
"fastmcp>=2.14.4",
|
||||
@@ -30,7 +31,7 @@ dependencies = [
|
||||
"hanzo-async>=0.1.3",
|
||||
"uvloop>=0.22.1; sys_platform != 'win32'",
|
||||
# Hanzo tool infrastructure (all tools)
|
||||
"hanzo-tools>=0.3.8", # 0.3.8 carries extra request headers (Enso's bounds) and DEFAULT_ACTION
|
||||
"hanzo-tools>=0.3.9", # 0.3.9: a cloud refusal carries its body and headers, send() returns headers
|
||||
"hanzo-tools-fs>=0.3.4", # 0.3.4 returns image files as native MCP ImageContent
|
||||
"hanzo-tools-shell>=0.6.5", # 0.6.5 pairs with hanzo-tools>=0.3.0 (ToolError)
|
||||
"hanzo-tools-core>=0.3.1", # 0.3.1 is the EMPTY shim — no longer shadows canonical hanzo-tools.core
|
||||
@@ -43,9 +44,9 @@ dependencies = [
|
||||
# 0.2.1 fixes ConfigTool passing permission_manager positionally into BaseTool.__init__
|
||||
"hanzo-tools-config>=0.2.1",
|
||||
"hanzo-tools-refactor>=0.1.0",
|
||||
"hanzo-tools-llm>=0.2.1", # 0.2.1 is llm over api.hanzo.ai (Enso) and kai_decide
|
||||
"hanzo-tools-llm>=0.2.2", # 0.2.2: llm limits, searched models, served/paid-by, typed plan refusals
|
||||
"hanzo-tools-code>=0.1.0",
|
||||
"hanzo-tools-vcs>=0.1.0",
|
||||
"hanzo-tools-vcs>=0.1.3", # 0.1.3 adds repo: repositories on Hanzo git (list, sync now)
|
||||
"hanzo-tools-net>=0.1.0",
|
||||
"hanzo-tools-agent>=0.3.1",
|
||||
"hanzo-tools-api>=0.3.2", # 0.3.2 is the unified `hanzo` tool projected from cloud's OpenAPI registry
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
"""The cloud-backed tools ride the default surface of every mode.
|
||||
|
||||
A mode disables every registered tool it does not list, so a tool missing from
|
||||
ESSENTIAL_TOOLS is installed and invisible. llm (completions, the catalog, the
|
||||
plan's limits), kai_decide and repo (repositories on Hanzo git) are HTTP calls to
|
||||
api.hanzo.ai, so every mode carries them.
|
||||
"""
|
||||
|
||||
from hanzo_mcp.tools.common.entrypoint_loader import PACKAGE_TOOL_PREFIXES
|
||||
from hanzo_mcp.tools.common.mode import ModeRegistry
|
||||
from hanzo_mcp.tools.common.mode_loader import ModeLoader
|
||||
from hanzo_mcp.tools.common.personality import ESSENTIAL_TOOLS
|
||||
|
||||
CLOUD_TOOLS = ("llm", "kai_decide", "repo")
|
||||
|
||||
|
||||
def test_the_cloud_tools_are_essential():
|
||||
assert set(CLOUD_TOOLS) <= set(ESSENTIAL_TOOLS)
|
||||
assert PACKAGE_TOOL_PREFIXES["llm"] == ["llm", "kai_decide"]
|
||||
assert PACKAGE_TOOL_PREFIXES["vcs"] == ["git", "repo"]
|
||||
|
||||
|
||||
def test_every_mode_enables_them():
|
||||
ModeLoader.initialize_modes()
|
||||
modes = ModeRegistry.list()
|
||||
assert modes
|
||||
for mode in modes:
|
||||
enabled = ModeLoader.get_enabled_tools_from_mode(force_mode=mode.name)
|
||||
assert all(enabled.get(t) for t in CLOUD_TOOLS), (
|
||||
mode.name,
|
||||
{t: enabled.get(t) for t in CLOUD_TOOLS},
|
||||
)
|
||||
Reference in New Issue
Block a user