hypercli-cli 2026.3.25__tar.gz → 2026.4.5__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-2026.3.25 → hypercli_cli-2026.4.5}/PKG-INFO +4 -4
- hypercli_cli-2026.4.5/hypercli_cli/__init__.py +1 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/cli.py +12 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/flow.py +1 -1
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/jobs.py +3 -3
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/keys.py +9 -2
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/voice.py +60 -61
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/pyproject.toml +4 -4
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/tests/test_agent_env_resolution.py +33 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/tests/test_jobs_list_tags.py +1 -1
- hypercli_cli-2026.4.5/tests/test_me_command.py +36 -0
- hypercli_cli-2026.3.25/hypercli_cli/__init__.py +0 -1
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/.gitignore +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/README.md +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/agent.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/agents.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/billing.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/comfyui.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/embed.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/files.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/instances.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/onboard.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/output.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/renders.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/stt.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/tui/__init__.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/tui/job_monitor.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/user.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/hypercli_cli/wallet.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/tests/test_exec_shell_dryrun.py +0 -0
- {hypercli_cli-2026.3.25 → hypercli_cli-2026.4.5}/tests/test_openclaw_config.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hypercli-cli
|
|
3
|
-
Version: 2026.
|
|
3
|
+
Version: 2026.4.5
|
|
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
|
|
@@ -9,7 +9,7 @@ Author-email: HyperCLI <support@hypercli.com>
|
|
|
9
9
|
License: MIT
|
|
10
10
|
Requires-Python: >=3.10
|
|
11
11
|
Requires-Dist: httpx>=0.27.0
|
|
12
|
-
Requires-Dist: hypercli-sdk>=2026.
|
|
12
|
+
Requires-Dist: hypercli-sdk>=2026.4.5
|
|
13
13
|
Requires-Dist: mutagen>=1.47.0
|
|
14
14
|
Requires-Dist: pyyaml>=6.0
|
|
15
15
|
Requires-Dist: rich>=14.2.0
|
|
@@ -19,11 +19,11 @@ Provides-Extra: all
|
|
|
19
19
|
Requires-Dist: argon2-cffi>=25.0.0; extra == 'all'
|
|
20
20
|
Requires-Dist: eth-account>=0.13.0; extra == 'all'
|
|
21
21
|
Requires-Dist: faster-whisper>=1.1.0; extra == 'all'
|
|
22
|
-
Requires-Dist: hypercli-sdk[comfyui]>=2026.
|
|
22
|
+
Requires-Dist: hypercli-sdk[comfyui]>=2026.4.5; extra == 'all'
|
|
23
23
|
Requires-Dist: web3>=7.0.0; extra == 'all'
|
|
24
24
|
Requires-Dist: x402[evm,httpx]>=2.0.0; extra == 'all'
|
|
25
25
|
Provides-Extra: comfyui
|
|
26
|
-
Requires-Dist: hypercli-sdk[comfyui]>=2026.
|
|
26
|
+
Requires-Dist: hypercli-sdk[comfyui]>=2026.4.5; extra == 'comfyui'
|
|
27
27
|
Provides-Extra: dev
|
|
28
28
|
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
29
29
|
Requires-Dist: ruff>=0.3.0; extra == 'dev'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2026.4.5"
|
|
@@ -9,6 +9,7 @@ from hypercli import HyperCLI, APIError, configure
|
|
|
9
9
|
from hypercli.config import CONFIG_FILE
|
|
10
10
|
|
|
11
11
|
from . import agent, agents, billing, comfyui, files, flow, instances, jobs, keys, user, wallet
|
|
12
|
+
from .output import output, spinner
|
|
12
13
|
|
|
13
14
|
console = Console()
|
|
14
15
|
|
|
@@ -70,6 +71,17 @@ app.add_typer(user.app, name="user")
|
|
|
70
71
|
app.add_typer(wallet.app, name="wallet")
|
|
71
72
|
|
|
72
73
|
|
|
74
|
+
@app.command("me")
|
|
75
|
+
def me_cmd(
|
|
76
|
+
fmt: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
|
|
77
|
+
):
|
|
78
|
+
"""Resolve the current auth context and show key capabilities."""
|
|
79
|
+
client = HyperCLI()
|
|
80
|
+
with spinner("Resolving auth context..."):
|
|
81
|
+
auth_me = client.user.auth_me()
|
|
82
|
+
output(auth_me, fmt)
|
|
83
|
+
|
|
84
|
+
|
|
73
85
|
@app.command("configure")
|
|
74
86
|
def configure_cmd():
|
|
75
87
|
"""Configure HyperCLI with your API key and API URL"""
|
|
@@ -117,7 +117,7 @@ def _create_flow_render(
|
|
|
117
117
|
return x402_result.render, x402_result
|
|
118
118
|
|
|
119
119
|
with spinner("Creating render..."):
|
|
120
|
-
render = get_client().renders.
|
|
120
|
+
render = get_client().renders.create_flow(flow_type, **clean_payload)
|
|
121
121
|
return render, None
|
|
122
122
|
|
|
123
123
|
|
|
@@ -11,14 +11,14 @@ def get_client() -> HyperCLI:
|
|
|
11
11
|
return HyperCLI()
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def _parse_tags(tag_args: list[str]) ->
|
|
15
|
-
tags:
|
|
14
|
+
def _parse_tags(tag_args: list[str]) -> list[str]:
|
|
15
|
+
tags: list[str] = []
|
|
16
16
|
for tag in tag_args:
|
|
17
17
|
key, sep, value = tag.partition("=")
|
|
18
18
|
if not sep or not key or not value:
|
|
19
19
|
console.print(f"[red]Error:[/red] Invalid tag '{tag}'. Expected KEY=VALUE.")
|
|
20
20
|
raise typer.Exit(1)
|
|
21
|
-
tags
|
|
21
|
+
tags.append(tag)
|
|
22
22
|
return tags
|
|
23
23
|
|
|
24
24
|
|
|
@@ -23,13 +23,18 @@ def _get_client():
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
@app.command("create")
|
|
26
|
-
def create_key(
|
|
26
|
+
def create_key(
|
|
27
|
+
name: str = typer.Option("default", help="Key name"),
|
|
28
|
+
tag: list[str] = typer.Option(None, "--tag", help="Repeat as --tag team=dev"),
|
|
29
|
+
):
|
|
27
30
|
"""Create a new API key"""
|
|
28
31
|
client = _get_client()
|
|
29
|
-
key = client.keys.create(name=name)
|
|
32
|
+
key = client.keys.create(name=name, tags=tag or None)
|
|
30
33
|
console.print(f"\n[bold green]API key created![/bold green]\n")
|
|
31
34
|
console.print(f" Key ID: {key.key_id}")
|
|
32
35
|
console.print(f" Name: {key.name}")
|
|
36
|
+
if key.tags:
|
|
37
|
+
console.print(f" Tags: {', '.join(key.tags)}")
|
|
33
38
|
console.print(f" API Key: [bold]{key.api_key}[/bold]")
|
|
34
39
|
console.print(f"\n[yellow]⚠ Save this key now — it won't be shown again.[/yellow]\n")
|
|
35
40
|
|
|
@@ -47,6 +52,7 @@ def list_keys():
|
|
|
47
52
|
table = Table(title="API Keys")
|
|
48
53
|
table.add_column("Key ID", style="dim")
|
|
49
54
|
table.add_column("Name")
|
|
55
|
+
table.add_column("Tags")
|
|
50
56
|
table.add_column("Key Preview")
|
|
51
57
|
table.add_column("Active", justify="center")
|
|
52
58
|
table.add_column("Created")
|
|
@@ -58,6 +64,7 @@ def list_keys():
|
|
|
58
64
|
table.add_row(
|
|
59
65
|
key.key_id[:8] + "...",
|
|
60
66
|
key.name or "",
|
|
67
|
+
", ".join(key.tags or []),
|
|
61
68
|
key.api_key_preview or "",
|
|
62
69
|
f"[{active_style}]{active}[/{active_style}]",
|
|
63
70
|
_fmt_ts(key.created_at),
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
"""HyperClaw Voice API commands — TTS, clone, design"""
|
|
2
|
-
import base64
|
|
3
2
|
import json
|
|
4
3
|
import os
|
|
5
|
-
import sys
|
|
6
4
|
from pathlib import Path
|
|
7
5
|
|
|
8
|
-
import httpx
|
|
9
6
|
import typer
|
|
10
7
|
from rich.console import Console
|
|
8
|
+
from hypercli import HyperCLI, APIError
|
|
11
9
|
|
|
12
10
|
app = typer.Typer(help="Voice API — text-to-speech, voice cloning, voice design")
|
|
13
11
|
console = Console()
|
|
@@ -50,43 +48,39 @@ def _resolve_api_base(base_url: str | None) -> str:
|
|
|
50
48
|
return DEFAULT_API_BASE
|
|
51
49
|
|
|
52
50
|
|
|
53
|
-
def
|
|
54
|
-
endpoint: str,
|
|
55
|
-
payload: dict,
|
|
56
|
-
api_key: str,
|
|
57
|
-
output: Path,
|
|
58
|
-
base_url: str | None = None,
|
|
59
|
-
):
|
|
60
|
-
"""POST to voice endpoint and save audio output."""
|
|
51
|
+
def _voice_client(api_key: str, base_url: str | None = None) -> HyperCLI:
|
|
61
52
|
api_base = _resolve_api_base(base_url)
|
|
62
|
-
|
|
53
|
+
return HyperCLI(api_key=api_key, api_url=api_base)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _save_voice_output(output: Path, audio: bytes) -> None:
|
|
57
|
+
output.parent.mkdir(parents=True, exist_ok=True)
|
|
58
|
+
output.write_bytes(audio)
|
|
59
|
+
size_kb = len(audio) / 1024
|
|
60
|
+
console.print(f"[green]✅ Saved {output} ({size_kb:.1f} KB)[/green]")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _handle_voice_error(error: APIError) -> None:
|
|
64
|
+
detail = error.detail if isinstance(error.detail, str) else json.dumps(error.detail)
|
|
65
|
+
console.print(f"[red]❌ {error.status_code}: {detail[:500]}[/red]")
|
|
66
|
+
raise typer.Exit(1)
|
|
67
|
+
|
|
63
68
|
|
|
69
|
+
def _post_voice(endpoint: str, api_key: str, output: Path, base_url: str | None = None, **kwargs) -> None:
|
|
70
|
+
"""POST to voice endpoint through the SDK and save audio output."""
|
|
71
|
+
api_base = _resolve_api_base(base_url)
|
|
72
|
+
url = f"{api_base}/agents/voice/{endpoint}"
|
|
64
73
|
console.print(f"[dim]→ POST {url}[/dim]")
|
|
65
74
|
|
|
66
75
|
try:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
if resp.status_code != 200:
|
|
78
|
-
console.print(f"[red]❌ {resp.status_code}: {resp.text[:500]}[/red]")
|
|
79
|
-
raise typer.Exit(1)
|
|
80
|
-
|
|
81
|
-
output.parent.mkdir(parents=True, exist_ok=True)
|
|
82
|
-
with open(output, "wb") as f:
|
|
83
|
-
f.write(resp.content)
|
|
84
|
-
|
|
85
|
-
size_kb = len(resp.content) / 1024
|
|
86
|
-
console.print(f"[green]✅ Saved {output} ({size_kb:.1f} KB)[/green]")
|
|
87
|
-
|
|
88
|
-
except httpx.HTTPError as e:
|
|
89
|
-
console.print(f"[red]❌ Request failed: {e}[/red]")
|
|
76
|
+
client = _voice_client(api_key, base_url)
|
|
77
|
+
method = getattr(client.voice, endpoint)
|
|
78
|
+
audio = method(**kwargs)
|
|
79
|
+
_save_voice_output(output, audio)
|
|
80
|
+
except APIError as error:
|
|
81
|
+
_handle_voice_error(error)
|
|
82
|
+
except OSError as e:
|
|
83
|
+
console.print(f"[red]❌ File error: {e}[/red]")
|
|
90
84
|
raise typer.Exit(1)
|
|
91
85
|
|
|
92
86
|
|
|
@@ -109,13 +103,16 @@ def tts(
|
|
|
109
103
|
api_key = _get_api_key(key)
|
|
110
104
|
if output is None:
|
|
111
105
|
output = Path(f"output.{format}")
|
|
112
|
-
|
|
113
|
-
"
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
106
|
+
_post_voice(
|
|
107
|
+
"tts",
|
|
108
|
+
api_key,
|
|
109
|
+
output,
|
|
110
|
+
base_url,
|
|
111
|
+
text=text,
|
|
112
|
+
voice=voice,
|
|
113
|
+
language=language,
|
|
114
|
+
response_format=format,
|
|
115
|
+
)
|
|
119
116
|
|
|
120
117
|
|
|
121
118
|
@app.command("clone")
|
|
@@ -143,19 +140,18 @@ def clone(
|
|
|
143
140
|
console.print(f"[red]❌ Reference audio not found: {ref_audio}[/red]")
|
|
144
141
|
raise typer.Exit(1)
|
|
145
142
|
|
|
146
|
-
with open(ref_audio, "rb") as f:
|
|
147
|
-
ref_b64 = base64.b64encode(f.read()).decode()
|
|
148
|
-
|
|
149
143
|
console.print(f"[dim]Reference: {ref_audio} ({ref_audio.stat().st_size / 1024:.1f} KB)[/dim]")
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
144
|
+
_post_voice(
|
|
145
|
+
"clone",
|
|
146
|
+
api_key,
|
|
147
|
+
output,
|
|
148
|
+
base_url,
|
|
149
|
+
text=text,
|
|
150
|
+
ref_audio=ref_audio,
|
|
151
|
+
language=language,
|
|
152
|
+
x_vector_only=x_vector_only,
|
|
153
|
+
response_format=format,
|
|
154
|
+
)
|
|
159
155
|
|
|
160
156
|
|
|
161
157
|
@app.command("design")
|
|
@@ -177,10 +173,13 @@ def design(
|
|
|
177
173
|
api_key = _get_api_key(key)
|
|
178
174
|
if output is None:
|
|
179
175
|
output = Path(f"output.{format}")
|
|
180
|
-
|
|
181
|
-
"
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
176
|
+
_post_voice(
|
|
177
|
+
"design",
|
|
178
|
+
api_key,
|
|
179
|
+
output,
|
|
180
|
+
base_url,
|
|
181
|
+
text=text,
|
|
182
|
+
description=description,
|
|
183
|
+
language=language,
|
|
184
|
+
response_format=format,
|
|
185
|
+
)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "hypercli-cli"
|
|
7
|
-
version = "2026.
|
|
7
|
+
version = "2026.4.5"
|
|
8
8
|
description = "CLI for HyperCLI - GPU orchestration and LLM API"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -13,7 +13,7 @@ authors = [
|
|
|
13
13
|
{ name = "HyperCLI", email = "support@hypercli.com" }
|
|
14
14
|
]
|
|
15
15
|
dependencies = [
|
|
16
|
-
"hypercli-sdk>=2026.
|
|
16
|
+
"hypercli-sdk>=2026.4.5",
|
|
17
17
|
"typer>=0.20.0",
|
|
18
18
|
"rich>=14.2.0",
|
|
19
19
|
"websocket-client>=1.6.0",
|
|
@@ -24,7 +24,7 @@ dependencies = [
|
|
|
24
24
|
|
|
25
25
|
[project.optional-dependencies]
|
|
26
26
|
comfyui = [
|
|
27
|
-
"hypercli-sdk[comfyui]>=2026.
|
|
27
|
+
"hypercli-sdk[comfyui]>=2026.4.5",
|
|
28
28
|
]
|
|
29
29
|
wallet = [
|
|
30
30
|
"x402[httpx,evm]>=2.0.0",
|
|
@@ -37,7 +37,7 @@ stt = [
|
|
|
37
37
|
"faster-whisper>=1.1.0",
|
|
38
38
|
]
|
|
39
39
|
all = [
|
|
40
|
-
"hypercli-sdk[comfyui]>=2026.
|
|
40
|
+
"hypercli-sdk[comfyui]>=2026.4.5",
|
|
41
41
|
"x402[httpx,evm]>=2.0.0",
|
|
42
42
|
"eth-account>=0.13.0",
|
|
43
43
|
"web3>=7.0.0",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import importlib
|
|
2
|
+
from pathlib import Path
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
def test_agents_cli_prefers_agent_key_env(monkeypatch):
|
|
@@ -37,3 +38,35 @@ def test_voice_cli_prefers_product_envs(monkeypatch):
|
|
|
37
38
|
|
|
38
39
|
assert voice._get_api_key(None) == "sk-product"
|
|
39
40
|
assert voice._resolve_api_base(None) == "https://api.hypercli.com"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_voice_cli_posts_to_agents_voice_prefix(monkeypatch, tmp_path):
|
|
44
|
+
monkeypatch.setenv("HYPER_API_KEY", "sk-product")
|
|
45
|
+
monkeypatch.setenv("HYPER_API_BASE", "https://api.dev.hypercli.com")
|
|
46
|
+
|
|
47
|
+
import hypercli_cli.voice as voice
|
|
48
|
+
|
|
49
|
+
importlib.reload(voice)
|
|
50
|
+
|
|
51
|
+
called = {}
|
|
52
|
+
|
|
53
|
+
class _FakeVoice:
|
|
54
|
+
def tts(self, **kwargs):
|
|
55
|
+
called["kwargs"] = kwargs
|
|
56
|
+
return b"audio"
|
|
57
|
+
|
|
58
|
+
class _FakeHyperCLI:
|
|
59
|
+
def __init__(self, *, api_key, api_url):
|
|
60
|
+
called["api_key"] = api_key
|
|
61
|
+
called["api_url"] = api_url
|
|
62
|
+
self.voice = _FakeVoice()
|
|
63
|
+
|
|
64
|
+
monkeypatch.setattr(voice, "HyperCLI", _FakeHyperCLI)
|
|
65
|
+
|
|
66
|
+
out = tmp_path / "voice.wav"
|
|
67
|
+
voice._post_voice("tts", "sk-product", out, text="hello", voice="Chelsie")
|
|
68
|
+
|
|
69
|
+
assert called["api_url"] == "https://api.dev.hypercli.com"
|
|
70
|
+
assert called["api_key"] == "sk-product"
|
|
71
|
+
assert called["kwargs"] == {"text": "hello", "voice": "Chelsie"}
|
|
72
|
+
assert out.read_bytes() == b"audio"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from types import SimpleNamespace
|
|
2
|
+
|
|
3
|
+
from typer.testing import CliRunner
|
|
4
|
+
|
|
5
|
+
from hypercli_cli.cli import app
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
runner = CliRunner()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_me_command_outputs_capabilities(monkeypatch):
|
|
12
|
+
class FakeUserAPI:
|
|
13
|
+
def auth_me(self):
|
|
14
|
+
return SimpleNamespace(
|
|
15
|
+
user_id="user-123",
|
|
16
|
+
orchestra_user_id="orch-123",
|
|
17
|
+
team_id="team-123",
|
|
18
|
+
plan_id="pro",
|
|
19
|
+
email="user@example.com",
|
|
20
|
+
auth_type="orchestra_key",
|
|
21
|
+
capabilities=["models:*", "voice:*"],
|
|
22
|
+
key_id="key-123",
|
|
23
|
+
key_name="runtime-key",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
class FakeClient:
|
|
27
|
+
user = FakeUserAPI()
|
|
28
|
+
|
|
29
|
+
monkeypatch.setattr("hypercli_cli.cli.HyperCLI", lambda: FakeClient())
|
|
30
|
+
|
|
31
|
+
result = runner.invoke(app, ["me"])
|
|
32
|
+
|
|
33
|
+
assert result.exit_code == 0
|
|
34
|
+
assert "models:*" in result.stdout
|
|
35
|
+
assert "voice:*" in result.stdout
|
|
36
|
+
assert "runtime-key" in result.stdout
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2026.3.22"
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|