hanzo 0.3.26__py3-none-any.whl → 0.3.27__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of hanzo might be problematic. Click here for more details.
- hanzo/__init__.py +1 -1
- hanzo/tools/detector.py +127 -31
- {hanzo-0.3.26.dist-info → hanzo-0.3.27.dist-info}/METADATA +1 -1
- {hanzo-0.3.26.dist-info → hanzo-0.3.27.dist-info}/RECORD +6 -6
- {hanzo-0.3.26.dist-info → hanzo-0.3.27.dist-info}/WHEEL +0 -0
- {hanzo-0.3.26.dist-info → hanzo-0.3.27.dist-info}/entry_points.txt +0 -0
hanzo/__init__.py
CHANGED
hanzo/tools/detector.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import os
|
|
4
4
|
import shutil
|
|
5
5
|
import subprocess
|
|
6
|
+
import httpx
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from typing import Dict, List, Optional, Tuple
|
|
8
9
|
from dataclasses import dataclass
|
|
@@ -33,12 +34,33 @@ class ToolDetector:
|
|
|
33
34
|
|
|
34
35
|
# Define available tools with priority order
|
|
35
36
|
TOOLS = [
|
|
37
|
+
# Hanzo Local Node - highest priority for privacy and local control
|
|
38
|
+
AITool(
|
|
39
|
+
name="hanzod",
|
|
40
|
+
command="hanzo node",
|
|
41
|
+
display_name="Hanzo Node (Local Private AI)",
|
|
42
|
+
provider="hanzo-local",
|
|
43
|
+
priority=0, # Highest priority - local and private
|
|
44
|
+
check_command=None, # Check via API endpoint
|
|
45
|
+
api_endpoint="http://localhost:8000/health",
|
|
46
|
+
env_var=None
|
|
47
|
+
),
|
|
48
|
+
AITool(
|
|
49
|
+
name="hanzo-router",
|
|
50
|
+
command="hanzo router",
|
|
51
|
+
display_name="Hanzo Router (LLM Proxy)",
|
|
52
|
+
provider="hanzo-router",
|
|
53
|
+
priority=1,
|
|
54
|
+
check_command=None,
|
|
55
|
+
api_endpoint="http://localhost:4000/health",
|
|
56
|
+
env_var=None
|
|
57
|
+
),
|
|
36
58
|
AITool(
|
|
37
59
|
name="claude-code",
|
|
38
60
|
command="claude",
|
|
39
61
|
display_name="Claude Code",
|
|
40
62
|
provider="anthropic",
|
|
41
|
-
priority=
|
|
63
|
+
priority=2,
|
|
42
64
|
check_command="claude --version",
|
|
43
65
|
env_var="ANTHROPIC_API_KEY"
|
|
44
66
|
),
|
|
@@ -47,7 +69,7 @@ class ToolDetector:
|
|
|
47
69
|
command="hanzo dev",
|
|
48
70
|
display_name="Hanzo Dev (Native)",
|
|
49
71
|
provider="hanzo",
|
|
50
|
-
priority=
|
|
72
|
+
priority=3,
|
|
51
73
|
check_command="hanzo --version",
|
|
52
74
|
env_var="HANZO_API_KEY"
|
|
53
75
|
),
|
|
@@ -56,7 +78,7 @@ class ToolDetector:
|
|
|
56
78
|
command="openai",
|
|
57
79
|
display_name="OpenAI Codex",
|
|
58
80
|
provider="openai",
|
|
59
|
-
priority=
|
|
81
|
+
priority=4,
|
|
60
82
|
check_command="openai --version",
|
|
61
83
|
env_var="OPENAI_API_KEY"
|
|
62
84
|
),
|
|
@@ -65,7 +87,7 @@ class ToolDetector:
|
|
|
65
87
|
command="gemini",
|
|
66
88
|
display_name="Gemini CLI",
|
|
67
89
|
provider="google",
|
|
68
|
-
priority=
|
|
90
|
+
priority=5,
|
|
69
91
|
check_command="gemini --version",
|
|
70
92
|
env_var="GEMINI_API_KEY"
|
|
71
93
|
),
|
|
@@ -74,7 +96,7 @@ class ToolDetector:
|
|
|
74
96
|
command="grok",
|
|
75
97
|
display_name="Grok CLI",
|
|
76
98
|
provider="xai",
|
|
77
|
-
priority=
|
|
99
|
+
priority=6,
|
|
78
100
|
check_command="grok --version",
|
|
79
101
|
env_var="GROK_API_KEY"
|
|
80
102
|
),
|
|
@@ -83,7 +105,7 @@ class ToolDetector:
|
|
|
83
105
|
command="openhands",
|
|
84
106
|
display_name="OpenHands CLI",
|
|
85
107
|
provider="openhands",
|
|
86
|
-
priority=
|
|
108
|
+
priority=7,
|
|
87
109
|
check_command="openhands --version",
|
|
88
110
|
env_var=None
|
|
89
111
|
),
|
|
@@ -92,7 +114,7 @@ class ToolDetector:
|
|
|
92
114
|
command="cursor",
|
|
93
115
|
display_name="Cursor AI",
|
|
94
116
|
provider="cursor",
|
|
95
|
-
priority=
|
|
117
|
+
priority=8,
|
|
96
118
|
check_command="cursor --version",
|
|
97
119
|
env_var=None
|
|
98
120
|
),
|
|
@@ -101,7 +123,7 @@ class ToolDetector:
|
|
|
101
123
|
command="codeium",
|
|
102
124
|
display_name="Codeium",
|
|
103
125
|
provider="codeium",
|
|
104
|
-
priority=
|
|
126
|
+
priority=9,
|
|
105
127
|
check_command="codeium --version",
|
|
106
128
|
env_var="CODEIUM_API_KEY"
|
|
107
129
|
),
|
|
@@ -110,7 +132,7 @@ class ToolDetector:
|
|
|
110
132
|
command="aider",
|
|
111
133
|
display_name="Aider",
|
|
112
134
|
provider="aider",
|
|
113
|
-
priority=
|
|
135
|
+
priority=10,
|
|
114
136
|
check_command="aider --version",
|
|
115
137
|
env_var=None
|
|
116
138
|
),
|
|
@@ -119,7 +141,7 @@ class ToolDetector:
|
|
|
119
141
|
command="continue",
|
|
120
142
|
display_name="Continue Dev",
|
|
121
143
|
provider="continue",
|
|
122
|
-
priority=
|
|
144
|
+
priority=11,
|
|
123
145
|
check_command="continue --version",
|
|
124
146
|
env_var=None
|
|
125
147
|
)
|
|
@@ -143,26 +165,51 @@ class ToolDetector:
|
|
|
143
165
|
|
|
144
166
|
def detect_tool(self, tool: AITool) -> bool:
|
|
145
167
|
"""Detect if a specific tool is available."""
|
|
168
|
+
# Check API endpoint first (for services like hanzod)
|
|
169
|
+
if tool.api_endpoint:
|
|
170
|
+
try:
|
|
171
|
+
response = httpx.get(tool.api_endpoint, timeout=1.0)
|
|
172
|
+
if response.status_code == 200:
|
|
173
|
+
tool.detected = True
|
|
174
|
+
tool.version = "Running"
|
|
175
|
+
|
|
176
|
+
# Special handling for Hanzo services
|
|
177
|
+
if tool.name == "hanzod":
|
|
178
|
+
# Check if models are loaded
|
|
179
|
+
try:
|
|
180
|
+
models_response = httpx.get("http://localhost:8000/models", timeout=1.0)
|
|
181
|
+
if models_response.status_code == 200:
|
|
182
|
+
models = models_response.json()
|
|
183
|
+
if models:
|
|
184
|
+
tool.version = f"Running ({len(models)} models)"
|
|
185
|
+
except:
|
|
186
|
+
pass
|
|
187
|
+
|
|
188
|
+
return True
|
|
189
|
+
except:
|
|
190
|
+
pass
|
|
191
|
+
|
|
146
192
|
# Check if command exists
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
tool.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
193
|
+
if tool.command:
|
|
194
|
+
tool.path = shutil.which(tool.command.split()[0])
|
|
195
|
+
if tool.path:
|
|
196
|
+
tool.detected = True
|
|
197
|
+
|
|
198
|
+
# Try to get version
|
|
199
|
+
if tool.check_command:
|
|
200
|
+
try:
|
|
201
|
+
result = subprocess.run(
|
|
202
|
+
tool.check_command.split(),
|
|
203
|
+
capture_output=True,
|
|
204
|
+
text=True,
|
|
205
|
+
timeout=2
|
|
206
|
+
)
|
|
207
|
+
if result.returncode == 0:
|
|
208
|
+
tool.version = result.stdout.strip().split()[-1]
|
|
209
|
+
except:
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
return True
|
|
166
213
|
|
|
167
214
|
# Check environment variable as fallback
|
|
168
215
|
if tool.env_var and os.getenv(tool.env_var):
|
|
@@ -229,13 +276,25 @@ class ToolDetector:
|
|
|
229
276
|
if self.detected_tools:
|
|
230
277
|
default = self.detected_tools[0]
|
|
231
278
|
self.console.print(f"\n[green]Default tool: {default.display_name}[/green]")
|
|
279
|
+
|
|
280
|
+
# Special message for Hanzo Node
|
|
281
|
+
if default.name == "hanzod":
|
|
282
|
+
self.console.print("[cyan]🔒 Using local private AI - your data stays on your machine[/cyan]")
|
|
283
|
+
self.console.print("[dim]Manage models with: hanzo node models[/dim]")
|
|
232
284
|
else:
|
|
233
285
|
self.console.print("\n[yellow]No AI coding tools detected.[/yellow]")
|
|
234
|
-
self.console.print("[dim]
|
|
286
|
+
self.console.print("[dim]Start Hanzo Node for local AI: hanzo node start[/dim]")
|
|
287
|
+
self.console.print("[dim]Or install Claude Code, OpenAI CLI, etc.[/dim]")
|
|
235
288
|
|
|
236
289
|
def get_tool_command(self, tool: AITool, prompt: str) -> List[str]:
|
|
237
290
|
"""Get the command to execute for a tool with a prompt."""
|
|
238
|
-
if tool.name == "
|
|
291
|
+
if tool.name == "hanzod":
|
|
292
|
+
# Use the local Hanzo node API
|
|
293
|
+
return ["hanzo", "ask", "--local", prompt]
|
|
294
|
+
elif tool.name == "hanzo-router":
|
|
295
|
+
# Use the router proxy
|
|
296
|
+
return ["hanzo", "ask", "--router", prompt]
|
|
297
|
+
elif tool.name == "claude-code":
|
|
239
298
|
return ["claude", prompt]
|
|
240
299
|
elif tool.name == "hanzo-dev":
|
|
241
300
|
return ["hanzo", "dev", "--prompt", prompt]
|
|
@@ -257,6 +316,43 @@ class ToolDetector:
|
|
|
257
316
|
def execute_with_tool(self, tool: AITool, prompt: str) -> Tuple[bool, str]:
|
|
258
317
|
"""Execute a prompt with a specific tool."""
|
|
259
318
|
try:
|
|
319
|
+
# Special handling for Hanzo services
|
|
320
|
+
if tool.name == "hanzod":
|
|
321
|
+
# Use the local API directly
|
|
322
|
+
try:
|
|
323
|
+
response = httpx.post(
|
|
324
|
+
"http://localhost:8000/chat/completions",
|
|
325
|
+
json={
|
|
326
|
+
"messages": [{"role": "user", "content": prompt}],
|
|
327
|
+
"stream": False
|
|
328
|
+
},
|
|
329
|
+
timeout=30.0
|
|
330
|
+
)
|
|
331
|
+
if response.status_code == 200:
|
|
332
|
+
result = response.json()
|
|
333
|
+
return True, result.get("choices", [{}])[0].get("message", {}).get("content", "")
|
|
334
|
+
except Exception as e:
|
|
335
|
+
return False, f"Hanzo Node error: {e}"
|
|
336
|
+
|
|
337
|
+
elif tool.name == "hanzo-router":
|
|
338
|
+
# Use the router API
|
|
339
|
+
try:
|
|
340
|
+
response = httpx.post(
|
|
341
|
+
"http://localhost:4000/chat/completions",
|
|
342
|
+
json={
|
|
343
|
+
"messages": [{"role": "user", "content": prompt}],
|
|
344
|
+
"model": "gpt-3.5-turbo", # Router will route to best available
|
|
345
|
+
"stream": False
|
|
346
|
+
},
|
|
347
|
+
timeout=30.0
|
|
348
|
+
)
|
|
349
|
+
if response.status_code == 200:
|
|
350
|
+
result = response.json()
|
|
351
|
+
return True, result.get("choices", [{}])[0].get("message", {}).get("content", "")
|
|
352
|
+
except Exception as e:
|
|
353
|
+
return False, f"Router error: {e}"
|
|
354
|
+
|
|
355
|
+
# Default command execution
|
|
260
356
|
command = self.get_tool_command(tool, prompt)
|
|
261
357
|
result = subprocess.run(
|
|
262
358
|
command,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hanzo
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.27
|
|
4
4
|
Summary: Hanzo AI - Complete AI Infrastructure Platform with CLI, Router, MCP, and Agent Runtime
|
|
5
5
|
Project-URL: Homepage, https://hanzo.ai
|
|
6
6
|
Project-URL: Repository, https://github.com/hanzoai/python-sdk
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
hanzo/__init__.py,sha256=
|
|
1
|
+
hanzo/__init__.py,sha256=QPRAp9EYB1L4Mii0Qoe3JYADXxMEJdaSyUg8f4vg7mI,185
|
|
2
2
|
hanzo/__main__.py,sha256=F3Vz0Ty3bdAj_8oxyETMIqxlmNRnJOAFB1XPxbyfouI,105
|
|
3
3
|
hanzo/base_agent.py,sha256=ojPaSgFETYl7iARWnNpg8eyAt7sg8eKhn9xZThyvxRA,15324
|
|
4
4
|
hanzo/batch_orchestrator.py,sha256=vn6n5i9gTfZ4DtowFDd5iWgYKjgNTioIomkffKbipSM,35827
|
|
@@ -32,7 +32,7 @@ hanzo/interactive/model_selector.py,sha256=4HcXvr8AI8Y5IttMH7Dhb8M0vqzP5y3S5kQrQ
|
|
|
32
32
|
hanzo/interactive/repl.py,sha256=PXpRw1Cfqdqy1pQsKLqz9AwKJBFZ_Y758MpDlJIb9ao,6938
|
|
33
33
|
hanzo/router/__init__.py,sha256=_cRG9nHC_wwq17iVYZSUNBYiJDdByfLDVEuIQn5-ePM,978
|
|
34
34
|
hanzo/tools/__init__.py,sha256=SsgmDvw5rO--NF4vKL9tV3O4WCNEl9aAIuqyTGSZ4RQ,122
|
|
35
|
-
hanzo/tools/detector.py,sha256=
|
|
35
|
+
hanzo/tools/detector.py,sha256=qwVc1fIDt2lDuqFqjhTVCnToRka91n125mpOpsPCfTU,14054
|
|
36
36
|
hanzo/ui/__init__.py,sha256=Ea22ereOm5Y0DDfyonA6qsO9Qkzofzd1CUE-VGW2lqw,241
|
|
37
37
|
hanzo/ui/inline_startup.py,sha256=7Y5dwqzt-L1J0F9peyqJ8XZgjHSua2nkItDTrLlBnhU,4265
|
|
38
38
|
hanzo/ui/startup.py,sha256=s7gP1QleQEIoCS1K0XBY7d6aufnwhicRLZDL7ej8ZZY,12235
|
|
@@ -40,7 +40,7 @@ hanzo/utils/__init__.py,sha256=5RRwKI852vp8smr4xCRgeKfn7dLEnHbdXGfVYTZ5jDQ,69
|
|
|
40
40
|
hanzo/utils/config.py,sha256=FD_LoBpcoF5dgJ7WL4o6LDp2pdOy8kS-dJ6iRO2GcGM,4728
|
|
41
41
|
hanzo/utils/net_check.py,sha256=YFbJ65SzfDYHkHLZe3n51VhId1VI3zhyx8p6BM-l6jE,3017
|
|
42
42
|
hanzo/utils/output.py,sha256=W0j3psF07vJiX4s02gbN4zYWfbKNsb8TSIoagBSf5vA,2704
|
|
43
|
-
hanzo-0.3.
|
|
44
|
-
hanzo-0.3.
|
|
45
|
-
hanzo-0.3.
|
|
46
|
-
hanzo-0.3.
|
|
43
|
+
hanzo-0.3.27.dist-info/METADATA,sha256=lpeix1C33n9JcKV7DAHF1Iu76YlLADANcA2uhE6LVY8,6061
|
|
44
|
+
hanzo-0.3.27.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
45
|
+
hanzo-0.3.27.dist-info/entry_points.txt,sha256=pQLPMdqOXU_2BfTcMDhkqTCDNk_H6ApvYuSaWcuQOOw,171
|
|
46
|
+
hanzo-0.3.27.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|