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.
Files changed (25) hide show
  1. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/.gitignore +1 -0
  2. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/PKG-INFO +1 -1
  3. hypercli_cli-1.0.9/hypercli_cli/__init__.py +1 -0
  4. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/claw.py +21 -2
  5. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/embed.py +6 -1
  6. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/instances.py +26 -0
  7. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/voice.py +28 -15
  8. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/pyproject.toml +1 -1
  9. hypercli_cli-1.0.6/hypercli_cli/__init__.py +0 -1
  10. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/README.md +0 -0
  11. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/agents.py +0 -0
  12. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/billing.py +0 -0
  13. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/cli.py +0 -0
  14. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/comfyui.py +0 -0
  15. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/flow.py +0 -0
  16. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/jobs.py +0 -0
  17. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/keys.py +0 -0
  18. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/onboard.py +0 -0
  19. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/output.py +0 -0
  20. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/renders.py +0 -0
  21. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/stt.py +0 -0
  22. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/tui/__init__.py +0 -0
  23. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/tui/job_monitor.py +0 -0
  24. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/user.py +0 -0
  25. {hypercli_cli-1.0.6 → hypercli_cli-1.0.9}/hypercli_cli/wallet.py +0 -0
@@ -49,3 +49,4 @@ next-env.d.ts
49
49
 
50
50
  # Turbo
51
51
  .turbo
52
+ .netlify
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hypercli-cli
3
- Version: 1.0.6
3
+ Version: 1.0.9
4
4
  Summary: CLI for HyperCLI - GPU orchestration and LLM API
5
5
  Project-URL: Homepage, https://hypercli.com
6
6
  Project-URL: Documentation, https://docs.hypercli.com
@@ -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 app as stt_app
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
- PROD_API_BASE = "https://api.hyperclaw.app"
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 from flag or saved claw 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
- dev: bool = False,
52
+ base_url: str | None = None,
40
53
  ):
41
54
  """POST to voice endpoint and save audio output."""
42
- api_base = DEV_API_BASE if dev else PROD_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
- dev: bool = typer.Option(False, "--dev", help="Use dev API"),
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, dev)
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
- dev: bool = typer.Option(False, "--dev", help="Use dev API"),
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, dev)
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
- dev: bool = typer.Option(False, "--dev", help="Use dev API"),
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, dev)
180
+ _post_voice("design", payload, api_key, output, base_url)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "hypercli-cli"
7
- version = "1.0.6"
7
+ version = "1.0.9"
8
8
  description = "CLI for HyperCLI - GPU orchestration and LLM API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1 +0,0 @@
1
- __version__ = "0.8.9"
File without changes