hanzo 0.3.6__py3-none-any.whl → 0.3.8__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/__main__.py +1 -1
- hanzo/cli.py +86 -52
- hanzo/commands/__init__.py +12 -1
- hanzo/commands/agent.py +18 -21
- hanzo/commands/auth.py +63 -59
- hanzo/commands/chat.py +54 -35
- hanzo/commands/cluster.py +109 -78
- hanzo/commands/config.py +39 -38
- hanzo/commands/mcp.py +63 -42
- hanzo/commands/miner.py +71 -58
- hanzo/commands/network.py +64 -55
- hanzo/commands/repl.py +37 -30
- hanzo/commands/tools.py +52 -67
- hanzo/interactive/__init__.py +1 -1
- hanzo/interactive/dashboard.py +34 -44
- hanzo/interactive/repl.py +35 -32
- hanzo/mcp_server.py +7 -2
- hanzo/repl.py +13 -3
- hanzo/router/__init__.py +21 -9
- hanzo/utils/__init__.py +1 -1
- hanzo/utils/config.py +37 -35
- hanzo/utils/net_check.py +33 -29
- hanzo/utils/output.py +23 -18
- hanzo-0.3.8.dist-info/METADATA +138 -0
- hanzo-0.3.8.dist-info/RECORD +28 -0
- {hanzo-0.3.6.dist-info → hanzo-0.3.8.dist-info}/WHEEL +1 -2
- hanzo-0.3.8.dist-info/entry_points.txt +6 -0
- hanzo-0.3.6.dist-info/METADATA +0 -76
- hanzo-0.3.6.dist-info/RECORD +0 -29
- hanzo-0.3.6.dist-info/entry_points.txt +0 -2
- hanzo-0.3.6.dist-info/top_level.txt +0 -1
hanzo/commands/network.py
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
"""Network commands for agent networks."""
|
|
2
2
|
|
|
3
|
-
import asyncio
|
|
4
|
-
from typing import List, Optional, Dict, Any
|
|
5
|
-
|
|
6
3
|
import click
|
|
7
4
|
from rich.table import Table
|
|
8
|
-
from rich.progress import Progress,
|
|
5
|
+
from rich.progress import Progress, TextColumn, SpinnerColumn
|
|
9
6
|
|
|
10
|
-
from ..utils.output import console
|
|
7
|
+
from ..utils.output import console
|
|
11
8
|
|
|
12
9
|
|
|
13
10
|
@click.group(name="network")
|
|
@@ -20,11 +17,18 @@ def network_group():
|
|
|
20
17
|
@click.argument("prompt")
|
|
21
18
|
@click.option("--agents", "-a", type=int, default=3, help="Number of agents")
|
|
22
19
|
@click.option("--model", "-m", help="Model to use")
|
|
23
|
-
@click.option(
|
|
20
|
+
@click.option(
|
|
21
|
+
"--mode",
|
|
22
|
+
type=click.Choice(["local", "distributed", "hybrid"]),
|
|
23
|
+
default="hybrid",
|
|
24
|
+
help="Execution mode",
|
|
25
|
+
)
|
|
24
26
|
@click.option("--consensus", is_flag=True, help="Require consensus")
|
|
25
27
|
@click.option("--timeout", "-t", type=int, default=300, help="Timeout in seconds")
|
|
26
28
|
@click.pass_context
|
|
27
|
-
async def dispatch(
|
|
29
|
+
async def dispatch(
|
|
30
|
+
ctx, prompt: str, agents: int, model: str, mode: str, consensus: bool, timeout: int
|
|
31
|
+
):
|
|
28
32
|
"""Dispatch work to agent network."""
|
|
29
33
|
try:
|
|
30
34
|
from hanzo_network import NetworkDispatcher
|
|
@@ -32,16 +36,16 @@ async def dispatch(ctx, prompt: str, agents: int, model: str, mode: str, consens
|
|
|
32
36
|
console.print("[red]Error:[/red] hanzo-network not installed")
|
|
33
37
|
console.print("Install with: pip install hanzo[network]")
|
|
34
38
|
return
|
|
35
|
-
|
|
39
|
+
|
|
36
40
|
dispatcher = NetworkDispatcher(mode=mode)
|
|
37
|
-
|
|
41
|
+
|
|
38
42
|
with Progress(
|
|
39
43
|
SpinnerColumn(),
|
|
40
44
|
TextColumn("[progress.description]{task.description}"),
|
|
41
45
|
console=console,
|
|
42
46
|
) as progress:
|
|
43
47
|
task = progress.add_task("Dispatching to network...", total=None)
|
|
44
|
-
|
|
48
|
+
|
|
45
49
|
try:
|
|
46
50
|
# Create job
|
|
47
51
|
job = await dispatcher.create_job(
|
|
@@ -49,32 +53,32 @@ async def dispatch(ctx, prompt: str, agents: int, model: str, mode: str, consens
|
|
|
49
53
|
num_agents=agents,
|
|
50
54
|
model=model,
|
|
51
55
|
consensus=consensus,
|
|
52
|
-
timeout=timeout
|
|
56
|
+
timeout=timeout,
|
|
53
57
|
)
|
|
54
|
-
|
|
58
|
+
|
|
55
59
|
progress.update(task, description=f"Job {job['id']} - Finding agents...")
|
|
56
|
-
|
|
60
|
+
|
|
57
61
|
# Execute job
|
|
58
62
|
result = await dispatcher.execute_job(job)
|
|
59
|
-
|
|
63
|
+
|
|
60
64
|
progress.update(task, completed=True)
|
|
61
|
-
|
|
65
|
+
|
|
62
66
|
except Exception as e:
|
|
63
67
|
progress.stop()
|
|
64
68
|
console.print(f"[red]Dispatch failed: {e}[/red]")
|
|
65
69
|
return
|
|
66
|
-
|
|
70
|
+
|
|
67
71
|
# Show results
|
|
68
72
|
console.print(f"\n[green]✓[/green] Job completed")
|
|
69
73
|
console.print(f" ID: {result['job_id']}")
|
|
70
74
|
console.print(f" Agents: {result['num_agents']}")
|
|
71
75
|
console.print(f" Duration: {result['duration']}s")
|
|
72
|
-
|
|
76
|
+
|
|
73
77
|
if consensus:
|
|
74
78
|
console.print(f" Consensus: {result.get('consensus_reached', False)}")
|
|
75
|
-
|
|
79
|
+
|
|
76
80
|
console.print("\n[cyan]Results:[/cyan]")
|
|
77
|
-
|
|
81
|
+
|
|
78
82
|
if consensus and result.get("consensus_result"):
|
|
79
83
|
console.print(result["consensus_result"])
|
|
80
84
|
else:
|
|
@@ -84,7 +88,12 @@ async def dispatch(ctx, prompt: str, agents: int, model: str, mode: str, consens
|
|
|
84
88
|
|
|
85
89
|
|
|
86
90
|
@network_group.command()
|
|
87
|
-
@click.option(
|
|
91
|
+
@click.option(
|
|
92
|
+
"--mode",
|
|
93
|
+
type=click.Choice(["local", "distributed", "all"]),
|
|
94
|
+
default="all",
|
|
95
|
+
help="Network mode",
|
|
96
|
+
)
|
|
88
97
|
@click.pass_context
|
|
89
98
|
async def agents(ctx, mode: str):
|
|
90
99
|
"""List available agents in network."""
|
|
@@ -93,24 +102,24 @@ async def agents(ctx, mode: str):
|
|
|
93
102
|
except ImportError:
|
|
94
103
|
console.print("[red]Error:[/red] hanzo-network not installed")
|
|
95
104
|
return
|
|
96
|
-
|
|
105
|
+
|
|
97
106
|
with console.status("Discovering agents..."):
|
|
98
107
|
try:
|
|
99
108
|
agents = await get_network_agents(mode=mode)
|
|
100
109
|
except Exception as e:
|
|
101
110
|
console.print(f"[red]Failed to discover agents: {e}[/red]")
|
|
102
111
|
return
|
|
103
|
-
|
|
112
|
+
|
|
104
113
|
if not agents:
|
|
105
114
|
console.print("[yellow]No agents found[/yellow]")
|
|
106
115
|
if mode == "local":
|
|
107
116
|
console.print("Start local agents with: hanzo agent start")
|
|
108
117
|
return
|
|
109
|
-
|
|
118
|
+
|
|
110
119
|
# Group by type
|
|
111
120
|
local_agents = [a for a in agents if a["type"] == "local"]
|
|
112
121
|
network_agents = [a for a in agents if a["type"] == "network"]
|
|
113
|
-
|
|
122
|
+
|
|
114
123
|
if local_agents:
|
|
115
124
|
table = Table(title="Local Agents")
|
|
116
125
|
table.add_column("ID", style="cyan")
|
|
@@ -118,18 +127,18 @@ async def agents(ctx, mode: str):
|
|
|
118
127
|
table.add_column("Model", style="yellow")
|
|
119
128
|
table.add_column("Status", style="blue")
|
|
120
129
|
table.add_column("Jobs", style="magenta")
|
|
121
|
-
|
|
130
|
+
|
|
122
131
|
for agent in local_agents:
|
|
123
132
|
table.add_row(
|
|
124
133
|
agent["id"][:8],
|
|
125
134
|
agent["name"],
|
|
126
135
|
agent.get("model", "default"),
|
|
127
136
|
agent["status"],
|
|
128
|
-
str(agent.get("jobs_completed", 0))
|
|
137
|
+
str(agent.get("jobs_completed", 0)),
|
|
129
138
|
)
|
|
130
|
-
|
|
139
|
+
|
|
131
140
|
console.print(table)
|
|
132
|
-
|
|
141
|
+
|
|
133
142
|
if network_agents:
|
|
134
143
|
table = Table(title="Network Agents")
|
|
135
144
|
table.add_column("ID", style="cyan")
|
|
@@ -137,16 +146,16 @@ async def agents(ctx, mode: str):
|
|
|
137
146
|
table.add_column("Model", style="yellow")
|
|
138
147
|
table.add_column("Latency", style="blue")
|
|
139
148
|
table.add_column("Cost", style="magenta")
|
|
140
|
-
|
|
149
|
+
|
|
141
150
|
for agent in network_agents:
|
|
142
151
|
table.add_row(
|
|
143
152
|
agent["id"][:8],
|
|
144
153
|
agent.get("location", "unknown"),
|
|
145
154
|
agent.get("model", "various"),
|
|
146
155
|
f"{agent.get('latency', 0)}ms",
|
|
147
|
-
f"${agent.get('cost_per_token', 0):.4f}"
|
|
156
|
+
f"${agent.get('cost_per_token', 0):.4f}",
|
|
148
157
|
)
|
|
149
|
-
|
|
158
|
+
|
|
150
159
|
console.print(table)
|
|
151
160
|
|
|
152
161
|
|
|
@@ -161,34 +170,34 @@ async def jobs(ctx, active: bool, limit: int):
|
|
|
161
170
|
except ImportError:
|
|
162
171
|
console.print("[red]Error:[/red] hanzo-network not installed")
|
|
163
172
|
return
|
|
164
|
-
|
|
173
|
+
|
|
165
174
|
with console.status("Loading jobs..."):
|
|
166
175
|
try:
|
|
167
176
|
jobs = await get_network_jobs(active_only=active, limit=limit)
|
|
168
177
|
except Exception as e:
|
|
169
178
|
console.print(f"[red]Failed to load jobs: {e}[/red]")
|
|
170
179
|
return
|
|
171
|
-
|
|
180
|
+
|
|
172
181
|
if not jobs:
|
|
173
182
|
console.print("[yellow]No jobs found[/yellow]")
|
|
174
183
|
return
|
|
175
|
-
|
|
184
|
+
|
|
176
185
|
table = Table(title="Network Jobs")
|
|
177
186
|
table.add_column("ID", style="cyan")
|
|
178
187
|
table.add_column("Status", style="green")
|
|
179
188
|
table.add_column("Agents", style="yellow")
|
|
180
189
|
table.add_column("Created", style="blue")
|
|
181
190
|
table.add_column("Duration", style="magenta")
|
|
182
|
-
|
|
191
|
+
|
|
183
192
|
for job in jobs:
|
|
184
193
|
table.add_row(
|
|
185
194
|
job["id"][:8],
|
|
186
195
|
job["status"],
|
|
187
196
|
str(job["num_agents"]),
|
|
188
197
|
job["created_at"],
|
|
189
|
-
f"{job.get('duration', 0)}s" if job.get("duration") else "-"
|
|
198
|
+
f"{job.get('duration', 0)}s" if job.get("duration") else "-",
|
|
190
199
|
)
|
|
191
|
-
|
|
200
|
+
|
|
192
201
|
console.print(table)
|
|
193
202
|
|
|
194
203
|
|
|
@@ -202,27 +211,27 @@ async def job(ctx, job_id: str):
|
|
|
202
211
|
except ImportError:
|
|
203
212
|
console.print("[red]Error:[/red] hanzo-network not installed")
|
|
204
213
|
return
|
|
205
|
-
|
|
214
|
+
|
|
206
215
|
with console.status("Loading job details..."):
|
|
207
216
|
try:
|
|
208
217
|
job = await get_job_details(job_id)
|
|
209
218
|
except Exception as e:
|
|
210
219
|
console.print(f"[red]Failed to load job: {e}[/red]")
|
|
211
220
|
return
|
|
212
|
-
|
|
221
|
+
|
|
213
222
|
console.print(f"[cyan]Job {job_id}[/cyan]")
|
|
214
223
|
console.print(f" Status: {job['status']}")
|
|
215
224
|
console.print(f" Created: {job['created_at']}")
|
|
216
225
|
console.print(f" Agents: {job['num_agents']}")
|
|
217
226
|
console.print(f" Mode: {job['mode']}")
|
|
218
|
-
|
|
227
|
+
|
|
219
228
|
if job["status"] == "completed":
|
|
220
229
|
console.print(f" Duration: {job['duration']}s")
|
|
221
230
|
console.print(f" Cost: ${job.get('total_cost', 0):.4f}")
|
|
222
|
-
|
|
231
|
+
|
|
223
232
|
console.print(f"\n[cyan]Prompt:[/cyan]")
|
|
224
233
|
console.print(job["prompt"])
|
|
225
|
-
|
|
234
|
+
|
|
226
235
|
if job["status"] == "completed" and job.get("results"):
|
|
227
236
|
console.print("\n[cyan]Results:[/cyan]")
|
|
228
237
|
for i, result in enumerate(job["results"], 1):
|
|
@@ -242,16 +251,16 @@ async def swarm(ctx, name: str, agents: int, model: str):
|
|
|
242
251
|
except ImportError:
|
|
243
252
|
console.print("[red]Error:[/red] hanzo-network not installed")
|
|
244
253
|
return
|
|
245
|
-
|
|
254
|
+
|
|
246
255
|
swarm = LocalSwarm(name=name, size=agents, model=model)
|
|
247
|
-
|
|
256
|
+
|
|
248
257
|
with Progress(
|
|
249
258
|
SpinnerColumn(),
|
|
250
259
|
TextColumn("[progress.description]{task.description}"),
|
|
251
260
|
console=console,
|
|
252
261
|
) as progress:
|
|
253
262
|
task = progress.add_task("Starting swarm...", total=None)
|
|
254
|
-
|
|
263
|
+
|
|
255
264
|
try:
|
|
256
265
|
await swarm.start()
|
|
257
266
|
progress.update(task, completed=True)
|
|
@@ -259,11 +268,11 @@ async def swarm(ctx, name: str, agents: int, model: str):
|
|
|
259
268
|
progress.stop()
|
|
260
269
|
console.print(f"[red]Failed to start swarm: {e}[/red]")
|
|
261
270
|
return
|
|
262
|
-
|
|
271
|
+
|
|
263
272
|
console.print(f"[green]✓[/green] Swarm '{name}' started with {agents} agents")
|
|
264
273
|
console.print("Use 'hanzo network dispatch --mode local' to send work to swarm")
|
|
265
274
|
console.print("\nPress Ctrl+C to stop swarm")
|
|
266
|
-
|
|
275
|
+
|
|
267
276
|
try:
|
|
268
277
|
# Keep swarm running
|
|
269
278
|
await swarm.run_forever()
|
|
@@ -282,26 +291,26 @@ async def stats(ctx):
|
|
|
282
291
|
except ImportError:
|
|
283
292
|
console.print("[red]Error:[/red] hanzo-network not installed")
|
|
284
293
|
return
|
|
285
|
-
|
|
294
|
+
|
|
286
295
|
with console.status("Loading network stats..."):
|
|
287
296
|
try:
|
|
288
297
|
stats = await get_network_stats()
|
|
289
298
|
except Exception as e:
|
|
290
299
|
console.print(f"[red]Failed to load stats: {e}[/red]")
|
|
291
300
|
return
|
|
292
|
-
|
|
301
|
+
|
|
293
302
|
console.print("[cyan]Network Statistics[/cyan]")
|
|
294
303
|
console.print(f" Total agents: {stats['total_agents']}")
|
|
295
304
|
console.print(f" Active agents: {stats['active_agents']}")
|
|
296
305
|
console.print(f" Total jobs: {stats['total_jobs']}")
|
|
297
306
|
console.print(f" Active jobs: {stats['active_jobs']}")
|
|
298
307
|
console.print(f" Success rate: {stats['success_rate']}%")
|
|
299
|
-
|
|
308
|
+
|
|
300
309
|
console.print(f"\n[cyan]Performance:[/cyan]")
|
|
301
310
|
console.print(f" Average latency: {stats['avg_latency']}ms")
|
|
302
311
|
console.print(f" Average job time: {stats['avg_job_time']}s")
|
|
303
312
|
console.print(f" Throughput: {stats['throughput']} jobs/min")
|
|
304
|
-
|
|
313
|
+
|
|
305
314
|
console.print(f"\n[cyan]Economics:[/cyan]")
|
|
306
315
|
console.print(f" Total tokens: {stats['total_tokens']:,}")
|
|
307
316
|
console.print(f" Average cost: ${stats['avg_cost']:.4f}/job")
|
|
@@ -318,16 +327,16 @@ async def discovery(ctx, enable: bool):
|
|
|
318
327
|
except ImportError:
|
|
319
328
|
console.print("[red]Error:[/red] hanzo-network not installed")
|
|
320
329
|
return
|
|
321
|
-
|
|
330
|
+
|
|
322
331
|
try:
|
|
323
332
|
await configure_discovery(enabled=enable)
|
|
324
|
-
|
|
333
|
+
|
|
325
334
|
if enable:
|
|
326
335
|
console.print("[green]✓[/green] Network discovery enabled")
|
|
327
336
|
console.print("Your agents will be discoverable by the network")
|
|
328
337
|
else:
|
|
329
338
|
console.print("[green]✓[/green] Network discovery disabled")
|
|
330
339
|
console.print("Your agents will only be accessible locally")
|
|
331
|
-
|
|
340
|
+
|
|
332
341
|
except Exception as e:
|
|
333
|
-
console.print(f"[red]Failed to configure discovery: {e}[/red]")
|
|
342
|
+
console.print(f"[red]Failed to configure discovery: {e}[/red]")
|
hanzo/commands/repl.py
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
6
|
import click
|
|
8
7
|
|
|
@@ -32,19 +31,19 @@ def start(ctx, model: str, local: bool, ipython: bool, tui: bool, voice: bool):
|
|
|
32
31
|
os.environ["HANZO_USE_LOCAL"] = "true"
|
|
33
32
|
if voice:
|
|
34
33
|
os.environ["HANZO_ENABLE_VOICE"] = "true"
|
|
35
|
-
|
|
34
|
+
|
|
36
35
|
if ipython:
|
|
37
36
|
from hanzo_repl.ipython_repl import main
|
|
38
37
|
elif tui:
|
|
39
38
|
from hanzo_repl.textual_repl import main
|
|
40
39
|
else:
|
|
41
40
|
from hanzo_repl.cli import main
|
|
42
|
-
|
|
41
|
+
|
|
43
42
|
console.print("[cyan]Starting Hanzo REPL...[/cyan]")
|
|
44
43
|
console.print("All MCP tools available. Type 'help' for commands.\n")
|
|
45
|
-
|
|
44
|
+
|
|
46
45
|
sys.exit(main())
|
|
47
|
-
|
|
46
|
+
|
|
48
47
|
except ImportError:
|
|
49
48
|
console.print("[red]Error:[/red] hanzo-repl not installed")
|
|
50
49
|
console.print("Install with: pip install hanzo[repl]")
|
|
@@ -61,35 +60,38 @@ def start(ctx, model: str, local: bool, ipython: bool, tui: bool, voice: bool):
|
|
|
61
60
|
def info(ctx):
|
|
62
61
|
"""Show REPL information and status."""
|
|
63
62
|
try:
|
|
64
|
-
from hanzo_repl import __version__
|
|
65
63
|
import hanzo_mcp
|
|
66
|
-
|
|
64
|
+
from hanzo_repl import __version__
|
|
65
|
+
|
|
67
66
|
console.print("[cyan]Hanzo REPL[/cyan]")
|
|
68
67
|
console.print(f" Version: {__version__}")
|
|
69
68
|
console.print(f" MCP Tools: {len(hanzo_mcp.get_all_tools())}")
|
|
70
|
-
|
|
69
|
+
|
|
71
70
|
# Check available interfaces
|
|
72
71
|
interfaces = []
|
|
73
72
|
try:
|
|
74
73
|
import IPython
|
|
74
|
+
|
|
75
75
|
interfaces.append("IPython")
|
|
76
76
|
except ImportError:
|
|
77
77
|
pass
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
try:
|
|
80
80
|
import textual
|
|
81
|
+
|
|
81
82
|
interfaces.append("TUI")
|
|
82
83
|
except ImportError:
|
|
83
84
|
pass
|
|
84
|
-
|
|
85
|
+
|
|
85
86
|
try:
|
|
86
87
|
import speech_recognition
|
|
88
|
+
|
|
87
89
|
interfaces.append("Voice")
|
|
88
90
|
except ImportError:
|
|
89
91
|
pass
|
|
90
|
-
|
|
92
|
+
|
|
91
93
|
console.print(f" Interfaces: {', '.join(interfaces) or 'Basic'}")
|
|
92
|
-
|
|
94
|
+
|
|
93
95
|
# Check LLM providers
|
|
94
96
|
providers = []
|
|
95
97
|
if os.environ.get("OPENAI_API_KEY"):
|
|
@@ -98,41 +100,45 @@ def info(ctx):
|
|
|
98
100
|
providers.append("Anthropic")
|
|
99
101
|
if os.environ.get("HANZO_API_KEY"):
|
|
100
102
|
providers.append("Hanzo AI")
|
|
101
|
-
|
|
103
|
+
|
|
102
104
|
console.print(f" Providers: {', '.join(providers) or 'None configured'}")
|
|
103
|
-
|
|
105
|
+
|
|
104
106
|
if not providers:
|
|
105
107
|
console.print("\n[yellow]No LLM providers configured[/yellow]")
|
|
106
|
-
console.print(
|
|
107
|
-
|
|
108
|
+
console.print(
|
|
109
|
+
"Set one of: OPENAI_API_KEY, ANTHROPIC_API_KEY, HANZO_API_KEY"
|
|
110
|
+
)
|
|
111
|
+
|
|
108
112
|
except ImportError:
|
|
109
113
|
console.print("[red]Error:[/red] hanzo-repl not installed")
|
|
110
114
|
|
|
111
115
|
|
|
112
116
|
@repl_group.command()
|
|
113
|
-
@click.option(
|
|
117
|
+
@click.option(
|
|
118
|
+
"--interface", type=click.Choice(["all", "ipython", "tui", "voice"]), default="all"
|
|
119
|
+
)
|
|
114
120
|
@click.pass_context
|
|
115
121
|
def install_extras(ctx, interface: str):
|
|
116
122
|
"""Install optional REPL components."""
|
|
117
123
|
import subprocess
|
|
118
|
-
|
|
124
|
+
|
|
119
125
|
packages = {
|
|
120
126
|
"ipython": ["ipython>=8.0.0", "jupyter>=1.0.0"],
|
|
121
127
|
"tui": ["textual>=0.41.0", "textual-dev>=1.2.0"],
|
|
122
|
-
"voice": ["speechrecognition>=3.10.0", "pyttsx3>=2.90", "pyaudio>=0.2.11"]
|
|
128
|
+
"voice": ["speechrecognition>=3.10.0", "pyttsx3>=2.90", "pyaudio>=0.2.11"],
|
|
123
129
|
}
|
|
124
|
-
|
|
130
|
+
|
|
125
131
|
if interface == "all":
|
|
126
132
|
to_install = []
|
|
127
133
|
for pkgs in packages.values():
|
|
128
134
|
to_install.extend(pkgs)
|
|
129
135
|
else:
|
|
130
136
|
to_install = packages.get(interface, [])
|
|
131
|
-
|
|
137
|
+
|
|
132
138
|
if to_install:
|
|
133
139
|
console.print(f"[cyan]Installing {interface} components...[/cyan]")
|
|
134
140
|
cmd = [sys.executable, "-m", "pip", "install"] + to_install
|
|
135
|
-
|
|
141
|
+
|
|
136
142
|
try:
|
|
137
143
|
subprocess.run(cmd, check=True)
|
|
138
144
|
console.print(f"[green]✓[/green] Installed {interface} components")
|
|
@@ -148,18 +154,19 @@ def install_extras(ctx, interface: str):
|
|
|
148
154
|
def exec(ctx, command: tuple, model: str):
|
|
149
155
|
"""Execute a command in REPL and exit."""
|
|
150
156
|
try:
|
|
151
|
-
from hanzo_repl import create_repl
|
|
152
157
|
import asyncio
|
|
153
|
-
|
|
158
|
+
|
|
159
|
+
from hanzo_repl import create_repl
|
|
160
|
+
|
|
154
161
|
repl = create_repl(model=model)
|
|
155
162
|
command_str = " ".join(command)
|
|
156
|
-
|
|
163
|
+
|
|
157
164
|
async def run():
|
|
158
165
|
result = await repl.execute(command_str)
|
|
159
166
|
console.print(result)
|
|
160
|
-
|
|
167
|
+
|
|
161
168
|
asyncio.run(run())
|
|
162
|
-
|
|
169
|
+
|
|
163
170
|
except ImportError:
|
|
164
171
|
console.print("[red]Error:[/red] hanzo-repl not installed")
|
|
165
172
|
except Exception as e:
|
|
@@ -172,10 +179,10 @@ def demo(ctx):
|
|
|
172
179
|
"""Run REPL demo showcasing features."""
|
|
173
180
|
try:
|
|
174
181
|
from hanzo_repl.demos import run_demo
|
|
175
|
-
|
|
182
|
+
|
|
176
183
|
console.print("[cyan]Running Hanzo REPL demo...[/cyan]\n")
|
|
177
184
|
run_demo()
|
|
178
|
-
|
|
185
|
+
|
|
179
186
|
except ImportError:
|
|
180
187
|
console.print("[red]Error:[/red] hanzo-repl not installed")
|
|
181
188
|
console.print("\nThe demo would show:")
|
|
@@ -183,4 +190,4 @@ def demo(ctx):
|
|
|
183
190
|
console.print(" • Code search and analysis")
|
|
184
191
|
console.print(" • AI chat with tool usage")
|
|
185
192
|
console.print(" • IPython magic commands")
|
|
186
|
-
console.print(" • Voice interaction (if available)")
|
|
193
|
+
console.print(" • Voice interaction (if available)")
|