hypercli-cli 1.0.6__tar.gz → 1.0.9__tar.gz
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.
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/.gitignore +1 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/PKG-INFO +1 -1
- hypercli_cli-1.0.9/hypercli_cli/__init__.py +1 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/claw.py +21 -2
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/embed.py +6 -1
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/instances.py +26 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/voice.py +28 -15
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/pyproject.toml +1 -1
- hypercli_cli-1.0.6/hypercli_cli/__init__.py +0 -1
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/README.md +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/agents.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/billing.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/cli.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/comfyui.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/flow.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/jobs.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/keys.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/onboard.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/output.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/renders.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/stt.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/tui/__init__.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/tui/job_monitor.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/user.py +0 -0
- {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/wallet.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.8"
|
|
@@ -9,7 +9,7 @@ from rich.table import Table
|
|
|
9
9
|
|
|
10
10
|
from .onboard import onboard as _onboard_fn
|
|
11
11
|
from .voice import app as voice_app
|
|
12
|
-
from .stt import
|
|
12
|
+
from .stt import transcribe as _stt_transcribe
|
|
13
13
|
from .embed import app as embed_app
|
|
14
14
|
|
|
15
15
|
app = typer.Typer(help="HyperClaw inference commands")
|
|
@@ -18,9 +18,28 @@ console = Console()
|
|
|
18
18
|
# Register subcommands
|
|
19
19
|
app.command("onboard")(_onboard_fn)
|
|
20
20
|
app.add_typer(voice_app, name="voice")
|
|
21
|
-
app.add_typer(stt_app, name="stt")
|
|
22
21
|
app.add_typer(embed_app, name="embed")
|
|
23
22
|
|
|
23
|
+
|
|
24
|
+
@app.command("transcribe")
|
|
25
|
+
def transcribe(
|
|
26
|
+
audio_file: Path = typer.Argument(..., help="Audio file to transcribe (wav, mp3, ogg, m4a, etc.)"),
|
|
27
|
+
model: str = typer.Option("turbo", "--model", "-m", help="Whisper model: tiny, base, small, medium, large-v3, turbo"),
|
|
28
|
+
language: str = typer.Option(None, "--language", "-l", help="Language code (e.g. en, de, fr). Auto-detect if omitted."),
|
|
29
|
+
device: str = typer.Option("auto", "--device", "-d", help="Device: auto, cpu, cuda"),
|
|
30
|
+
compute_type: str = typer.Option("auto", "--compute", help="Compute type: auto, int8, float16, float32"),
|
|
31
|
+
json_output: bool = typer.Option(False, "--json", help="Output as JSON with timestamps"),
|
|
32
|
+
output: Path = typer.Option(None, "--output", "-o", help="Write transcript to file"),
|
|
33
|
+
):
|
|
34
|
+
"""Transcribe audio to text using faster-whisper (runs locally).
|
|
35
|
+
|
|
36
|
+
Examples:
|
|
37
|
+
hyper claw transcribe voice.ogg
|
|
38
|
+
hyper claw transcribe meeting.mp3 --model large-v3 --language en
|
|
39
|
+
hyper claw transcribe audio.wav --json -o transcript.json
|
|
40
|
+
"""
|
|
41
|
+
_stt_transcribe(audio_file, model, language, device, compute_type, json_output, output)
|
|
42
|
+
|
|
24
43
|
# Check if wallet dependencies are available
|
|
25
44
|
try:
|
|
26
45
|
from x402 import x402Client
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""HyperClaw Embed — text embeddings via HyperClaw API."""
|
|
2
2
|
import json
|
|
3
|
+
import os
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
|
|
5
6
|
import httpx
|
|
@@ -16,15 +17,19 @@ DEV_API_BASE = "https://api.dev.hyperclaw.app"
|
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
def _get_api_key(key: str | None) -> str:
|
|
20
|
+
"""Resolve API key: --key flag > env HYPERCLAW_API_KEY > claw-key.json."""
|
|
19
21
|
if key:
|
|
20
22
|
return key
|
|
23
|
+
env_key = os.environ.get("HYPERCLAW_API_KEY", "").strip()
|
|
24
|
+
if env_key:
|
|
25
|
+
return env_key
|
|
21
26
|
if CLAW_KEY_PATH.exists():
|
|
22
27
|
with open(CLAW_KEY_PATH) as f:
|
|
23
28
|
k = json.load(f).get("key", "")
|
|
24
29
|
if k:
|
|
25
30
|
return k
|
|
26
31
|
console.print("[red]❌ No API key found.[/red]")
|
|
27
|
-
console.print("Pass [bold]--key sk-...[/bold] or run [bold]hyper claw subscribe[/bold]")
|
|
32
|
+
console.print("Pass [bold]--key sk-...[/bold], set [bold]HYPERCLAW_API_KEY[/bold], or run [bold]hyper claw subscribe[/bold]")
|
|
28
33
|
raise typer.Exit(1)
|
|
29
34
|
|
|
30
35
|
|
|
@@ -231,6 +231,12 @@ def launch(
|
|
|
231
231
|
if lb:
|
|
232
232
|
ports_dict["lb"] = lb
|
|
233
233
|
|
|
234
|
+
raw_tcp_ports = []
|
|
235
|
+
if ports_dict:
|
|
236
|
+
raw_tcp_ports = sorted(
|
|
237
|
+
int(p.split("/")[0]) for p in ports_dict.keys() if p.endswith("/tcp")
|
|
238
|
+
)
|
|
239
|
+
|
|
234
240
|
# Build registry auth if provided
|
|
235
241
|
registry_auth = None
|
|
236
242
|
if registry_user and registry_password:
|
|
@@ -302,6 +308,13 @@ def launch(
|
|
|
302
308
|
console.print(f" Price: ${job.price_per_hour:.2f}/hr")
|
|
303
309
|
if job.hostname:
|
|
304
310
|
console.print(f" Hostname: {job.hostname}")
|
|
311
|
+
if lb:
|
|
312
|
+
console.print(f" HTTPS LB: Traefik TLS on https://{job.hostname}")
|
|
313
|
+
console.print(f" LB Target: container port {lb}")
|
|
314
|
+
if lb_auth:
|
|
315
|
+
console.print(" LB Auth: enabled (Bearer token required)")
|
|
316
|
+
if raw_tcp_ports:
|
|
317
|
+
console.print(f" TCP Ports: raw TCP exposed: {', '.join(map(str, raw_tcp_ports))}")
|
|
305
318
|
console.print(f" Access Key: {x402_job.access_key}")
|
|
306
319
|
console.print(f" Status URL: {x402_job.status_url}")
|
|
307
320
|
console.print(f" Logs URL: {x402_job.logs_url}")
|
|
@@ -336,6 +349,12 @@ def launch(
|
|
|
336
349
|
console.print(f" Region: {job.region}")
|
|
337
350
|
console.print(f" Price: ${job.price_per_hour:.2f}/hr")
|
|
338
351
|
console.print(f" Runtime: {job.runtime}s")
|
|
352
|
+
if lb:
|
|
353
|
+
console.print(f" HTTPS LB: Traefik TLS will be provisioned for container port {lb}")
|
|
354
|
+
if lb_auth:
|
|
355
|
+
console.print(" LB Auth: enabled (Bearer token required)")
|
|
356
|
+
if raw_tcp_ports:
|
|
357
|
+
console.print(f" TCP: raw TCP ports: {', '.join(map(str, raw_tcp_ports))}")
|
|
339
358
|
# Display cold boot status
|
|
340
359
|
import sys
|
|
341
360
|
if job.cold_boot:
|
|
@@ -350,6 +369,13 @@ def launch(
|
|
|
350
369
|
console.print(f" Price: ${job.price_per_hour:.2f}/hr")
|
|
351
370
|
if job.hostname:
|
|
352
371
|
console.print(f" Hostname: {job.hostname}")
|
|
372
|
+
if lb and job.hostname:
|
|
373
|
+
console.print(f" HTTPS LB: Traefik TLS endpoint https://{job.hostname}")
|
|
374
|
+
console.print(f" LB Target: container port {lb}")
|
|
375
|
+
if lb_auth:
|
|
376
|
+
console.print(" LB Auth: enabled (Bearer token required)")
|
|
377
|
+
if raw_tcp_ports:
|
|
378
|
+
console.print(f" TCP: raw TCP ports: {', '.join(map(str, raw_tcp_ports))}")
|
|
353
379
|
# Display cold boot status for real launches too
|
|
354
380
|
if job.cold_boot:
|
|
355
381
|
console.print("[yellow]⏳ Cold boot — instance provisioning may take up to 15 minutes[/]")
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""HyperClaw Voice API commands — TTS, clone, design"""
|
|
2
2
|
import base64
|
|
3
3
|
import json
|
|
4
|
+
import os
|
|
4
5
|
import sys
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
|
|
@@ -13,33 +14,45 @@ console = Console()
|
|
|
13
14
|
|
|
14
15
|
HYPERCLI_DIR = Path.home() / ".hypercli"
|
|
15
16
|
CLAW_KEY_PATH = HYPERCLI_DIR / "claw-key.json"
|
|
16
|
-
|
|
17
|
-
DEV_API_BASE = "https://dev-api.hyperclaw.app"
|
|
17
|
+
DEFAULT_API_BASE = "https://api.hyperclaw.app"
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def _get_api_key(key: str | None) -> str:
|
|
21
|
-
"""Resolve API key
|
|
21
|
+
"""Resolve API key: --key flag > env HYPERCLAW_API_KEY > claw-key.json."""
|
|
22
22
|
if key:
|
|
23
23
|
return key
|
|
24
|
+
env_key = os.environ.get("HYPERCLAW_API_KEY", "").strip()
|
|
25
|
+
if env_key:
|
|
26
|
+
return env_key
|
|
24
27
|
if CLAW_KEY_PATH.exists():
|
|
25
28
|
with open(CLAW_KEY_PATH) as f:
|
|
26
29
|
k = json.load(f).get("key", "")
|
|
27
30
|
if k:
|
|
28
31
|
return k
|
|
29
32
|
console.print("[red]❌ No API key found.[/red]")
|
|
30
|
-
console.print("Pass [bold]--key sk-...[/bold] or run [bold]hyper claw subscribe[/bold]")
|
|
33
|
+
console.print("Pass [bold]--key sk-...[/bold], set [bold]HYPERCLAW_API_KEY[/bold], or run [bold]hyper claw subscribe[/bold]")
|
|
31
34
|
raise typer.Exit(1)
|
|
32
35
|
|
|
33
36
|
|
|
37
|
+
def _resolve_api_base(base_url: str | None) -> str:
|
|
38
|
+
"""Resolve API base: --base-url > HYPERCLAW_API_BASE env > default."""
|
|
39
|
+
if base_url:
|
|
40
|
+
return base_url.rstrip("/")
|
|
41
|
+
env_base = os.environ.get("HYPERCLAW_API_BASE", "").strip()
|
|
42
|
+
if env_base:
|
|
43
|
+
return env_base.rstrip("/")
|
|
44
|
+
return DEFAULT_API_BASE
|
|
45
|
+
|
|
46
|
+
|
|
34
47
|
def _post_voice(
|
|
35
48
|
endpoint: str,
|
|
36
49
|
payload: dict,
|
|
37
50
|
api_key: str,
|
|
38
51
|
output: Path,
|
|
39
|
-
|
|
52
|
+
base_url: str | None = None,
|
|
40
53
|
):
|
|
41
54
|
"""POST to voice endpoint and save audio output."""
|
|
42
|
-
api_base =
|
|
55
|
+
api_base = _resolve_api_base(base_url)
|
|
43
56
|
url = f"{api_base}/voice/{endpoint}"
|
|
44
57
|
|
|
45
58
|
console.print(f"[dim]→ POST {url}[/dim]")
|
|
@@ -79,10 +92,10 @@ def tts(
|
|
|
79
92
|
format: str = typer.Option("mp3", "--format", "-f", help="Output format: wav, mp3, opus, ogg, flac"),
|
|
80
93
|
output: Path = typer.Option(None, "--output", "-o", help="Output audio file (default: output.<format>)"),
|
|
81
94
|
key: str = typer.Option(None, "--key", "-k", help="API key (sk-...)"),
|
|
82
|
-
|
|
95
|
+
base_url: str = typer.Option(None, "--base-url", "-b", help="API base URL (default: api.hyperclaw.app)"),
|
|
83
96
|
):
|
|
84
97
|
"""Generate speech from text using a preset voice.
|
|
85
|
-
|
|
98
|
+
|
|
86
99
|
Examples:
|
|
87
100
|
hyper claw voice tts "Hello world"
|
|
88
101
|
hyper claw voice tts "Bonjour" -v Etienne -l french -f opus -o hello.opus
|
|
@@ -96,7 +109,7 @@ def tts(
|
|
|
96
109
|
"language": language,
|
|
97
110
|
"response_format": format,
|
|
98
111
|
}
|
|
99
|
-
_post_voice("tts", payload, api_key, output,
|
|
112
|
+
_post_voice("tts", payload, api_key, output, base_url)
|
|
100
113
|
|
|
101
114
|
|
|
102
115
|
@app.command("clone")
|
|
@@ -108,10 +121,10 @@ def clone(
|
|
|
108
121
|
format: str = typer.Option("mp3", "--format", "-f", help="Output format: wav, mp3, opus, ogg, flac"),
|
|
109
122
|
output: Path = typer.Option(None, "--output", "-o", help="Output audio file (default: output.<format>)"),
|
|
110
123
|
key: str = typer.Option(None, "--key", "-k", help="API key (sk-...)"),
|
|
111
|
-
|
|
124
|
+
base_url: str = typer.Option(None, "--base-url", "-b", help="API base URL (default: api.hyperclaw.app)"),
|
|
112
125
|
):
|
|
113
126
|
"""Clone a voice from reference audio.
|
|
114
|
-
|
|
127
|
+
|
|
115
128
|
Examples:
|
|
116
129
|
hyper claw voice clone "Hello" --ref voice.wav
|
|
117
130
|
hyper claw voice clone "Test" -r ref.wav -l english -f mp3 -o cloned.mp3
|
|
@@ -136,7 +149,7 @@ def clone(
|
|
|
136
149
|
"x_vector_only": x_vector_only,
|
|
137
150
|
"response_format": format,
|
|
138
151
|
}
|
|
139
|
-
_post_voice("clone", payload, api_key, output,
|
|
152
|
+
_post_voice("clone", payload, api_key, output, base_url)
|
|
140
153
|
|
|
141
154
|
|
|
142
155
|
@app.command("design")
|
|
@@ -147,10 +160,10 @@ def design(
|
|
|
147
160
|
format: str = typer.Option("mp3", "--format", "-f", help="Output format: wav, mp3, opus, ogg, flac"),
|
|
148
161
|
output: Path = typer.Option(None, "--output", "-o", help="Output audio file (default: output.<format>)"),
|
|
149
162
|
key: str = typer.Option(None, "--key", "-k", help="API key (sk-...)"),
|
|
150
|
-
|
|
163
|
+
base_url: str = typer.Option(None, "--base-url", "-b", help="API base URL (default: api.hyperclaw.app)"),
|
|
151
164
|
):
|
|
152
165
|
"""Design a voice from a text description.
|
|
153
|
-
|
|
166
|
+
|
|
154
167
|
Examples:
|
|
155
168
|
hyper claw voice design "Hello" --desc "deep male voice, British accent"
|
|
156
169
|
hyper claw voice design "Test" -d "young woman, cheerful" -f mp3 -o designed.mp3
|
|
@@ -164,4 +177,4 @@ def design(
|
|
|
164
177
|
"language": language,
|
|
165
178
|
"response_format": format,
|
|
166
179
|
}
|
|
167
|
-
_post_voice("design", payload, api_key, output,
|
|
180
|
+
_post_voice("design", payload, api_key, output, base_url)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.8.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|