deepctl-cmd-models 0.1.0__tar.gz → 0.1.1__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.
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/PKG-INFO +1 -1
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/pyproject.toml +1 -1
- deepctl_cmd_models-0.1.1/src/deepctl_cmd_models/command.py +216 -0
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models/models.py +6 -1
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models.egg-info/PKG-INFO +1 -1
- deepctl_cmd_models-0.1.0/src/deepctl_cmd_models/command.py +0 -141
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/README.md +0 -0
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/setup.cfg +0 -0
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models/__init__.py +0 -0
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models.egg-info/SOURCES.txt +0 -0
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models.egg-info/dependency_links.txt +0 -0
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models.egg-info/entry_points.txt +0 -0
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models.egg-info/requires.txt +0 -0
- {deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"""Models command for deepctl."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from deepctl_core import (
|
|
8
|
+
AuthManager,
|
|
9
|
+
BaseCommand,
|
|
10
|
+
BaseResult,
|
|
11
|
+
Config,
|
|
12
|
+
DeepgramClient,
|
|
13
|
+
get_output_format,
|
|
14
|
+
get_status_console,
|
|
15
|
+
)
|
|
16
|
+
from rich.console import Console
|
|
17
|
+
from rich.table import Table
|
|
18
|
+
|
|
19
|
+
from .models import ModelInfo, ModelsResult
|
|
20
|
+
|
|
21
|
+
console = Console()
|
|
22
|
+
# Status/progress chrome must never touch stdout, or it corrupts JSON/CSV
|
|
23
|
+
# output that callers pipe into jq and friends.
|
|
24
|
+
status_console = get_status_console()
|
|
25
|
+
|
|
26
|
+
# Models the API still lists but which are legacy. The catalog flags them so
|
|
27
|
+
# that nobody — human or coding agent — treats them as a current model family
|
|
28
|
+
# or composes new model names from them. (Paying accounts have requested the
|
|
29
|
+
# nonexistent "nova-3-conversational", a natural composition of "nova-3" and
|
|
30
|
+
# the legacy name below.)
|
|
31
|
+
DEPRECATED_MODELS: dict[str, str] = {
|
|
32
|
+
"conversationalai": (
|
|
33
|
+
"Legacy model. For conversational audio use 'nova-3'. There is no "
|
|
34
|
+
"model named 'nova-3-conversational'."
|
|
35
|
+
),
|
|
36
|
+
"2-conversationalai": (
|
|
37
|
+
"Legacy model. For conversational audio use 'nova-3'. There is no "
|
|
38
|
+
"model named 'nova-3-conversational'."
|
|
39
|
+
),
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _build_model_info(m: dict[str, Any], model_type: str) -> ModelInfo:
|
|
44
|
+
"""Map one API model entry onto ModelInfo.
|
|
45
|
+
|
|
46
|
+
The Deepgram Python SDK's generated response classes rename the API's
|
|
47
|
+
``uuid`` field to ``uuid_`` (to avoid shadowing), so ``model_dump()``
|
|
48
|
+
emits ``uuid_`` — both spellings are read here. The API also reports
|
|
49
|
+
``languages`` as a list; the older singular ``language`` key is kept as
|
|
50
|
+
a fallback for compatibility.
|
|
51
|
+
"""
|
|
52
|
+
model_id = m.get("uuid_") or m.get("uuid") or m.get("model_id") or ""
|
|
53
|
+
|
|
54
|
+
raw_languages = m.get("languages") or []
|
|
55
|
+
if not isinstance(raw_languages, list):
|
|
56
|
+
raw_languages = [raw_languages]
|
|
57
|
+
languages = [str(lang) for lang in raw_languages]
|
|
58
|
+
primary_language = str(m.get("language") or (languages[0] if languages else ""))
|
|
59
|
+
|
|
60
|
+
name = str(m.get("name") or "")
|
|
61
|
+
deprecation_note = DEPRECATED_MODELS.get(name.lower(), "")
|
|
62
|
+
|
|
63
|
+
return ModelInfo(
|
|
64
|
+
model_id=str(model_id),
|
|
65
|
+
name=name,
|
|
66
|
+
canonical_name=str(m.get("canonical_name") or ""),
|
|
67
|
+
architecture=str(m.get("architecture") or ""),
|
|
68
|
+
version=str(m.get("version") or ""),
|
|
69
|
+
language=primary_language,
|
|
70
|
+
languages=languages,
|
|
71
|
+
model_type=model_type,
|
|
72
|
+
deprecated=bool(deprecation_note),
|
|
73
|
+
deprecation_note=deprecation_note,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _format_languages(languages: list[str], limit: int = 4) -> str:
|
|
78
|
+
"""Join a language list for table display, truncating long lists."""
|
|
79
|
+
if len(languages) <= limit:
|
|
80
|
+
return ", ".join(languages)
|
|
81
|
+
return ", ".join(languages[:limit]) + f" +{len(languages) - limit}"
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ModelsCommand(BaseCommand):
|
|
85
|
+
"""Command for listing available Deepgram models."""
|
|
86
|
+
|
|
87
|
+
name = "models"
|
|
88
|
+
help = "List available Deepgram models"
|
|
89
|
+
short_help = "List models"
|
|
90
|
+
|
|
91
|
+
requires_auth = True
|
|
92
|
+
requires_project = False
|
|
93
|
+
ci_friendly = True
|
|
94
|
+
|
|
95
|
+
examples = [
|
|
96
|
+
"dg models",
|
|
97
|
+
"dg models --type stt",
|
|
98
|
+
"dg models --type tts",
|
|
99
|
+
"dg models --include-outdated",
|
|
100
|
+
]
|
|
101
|
+
agent_help = (
|
|
102
|
+
"List available Deepgram speech-to-text and text-to-speech models. "
|
|
103
|
+
"Filter by type (stt/tts) and optionally include outdated versions. "
|
|
104
|
+
"Use the canonical_name field as the `model` request parameter. "
|
|
105
|
+
"Entries flagged deprecated are legacy: do not use them or derive "
|
|
106
|
+
"new model names from them. Requires authentication."
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def get_arguments(self) -> list[dict[str, Any]]:
|
|
110
|
+
return [
|
|
111
|
+
{
|
|
112
|
+
"names": ["--type", "-t"],
|
|
113
|
+
"help": "Filter by model type (stt, tts)",
|
|
114
|
+
"type": str,
|
|
115
|
+
"is_option": True,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"names": ["--include-outdated"],
|
|
119
|
+
"help": "Include outdated model versions",
|
|
120
|
+
"is_flag": True,
|
|
121
|
+
"is_option": True,
|
|
122
|
+
},
|
|
123
|
+
]
|
|
124
|
+
|
|
125
|
+
def handle(
|
|
126
|
+
self,
|
|
127
|
+
config: Config,
|
|
128
|
+
auth_manager: AuthManager,
|
|
129
|
+
client: DeepgramClient,
|
|
130
|
+
**kwargs: Any,
|
|
131
|
+
) -> BaseResult:
|
|
132
|
+
model_type = kwargs.get("type")
|
|
133
|
+
include_outdated = kwargs.get("include_outdated", False)
|
|
134
|
+
|
|
135
|
+
try:
|
|
136
|
+
result = client.list_models(include_outdated=include_outdated)
|
|
137
|
+
|
|
138
|
+
# `or []` also covers an explicit null in the response body.
|
|
139
|
+
stt_models = result.get("stt") or []
|
|
140
|
+
tts_models = result.get("tts") or []
|
|
141
|
+
|
|
142
|
+
all_models: list[ModelInfo] = []
|
|
143
|
+
|
|
144
|
+
if model_type != "tts":
|
|
145
|
+
for m in stt_models:
|
|
146
|
+
all_models.append(_build_model_info(m, "stt"))
|
|
147
|
+
if not stt_models:
|
|
148
|
+
status_console.print(
|
|
149
|
+
"[yellow]Warning: the API returned zero speech-to-text "
|
|
150
|
+
"models. Deepgram publishes speech-to-text models "
|
|
151
|
+
"(Nova-3, Flux), so an empty list usually means an API "
|
|
152
|
+
"or account problem, not an empty catalog.[/yellow]"
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
if model_type != "stt":
|
|
156
|
+
for m in tts_models:
|
|
157
|
+
all_models.append(_build_model_info(m, "tts"))
|
|
158
|
+
if not tts_models:
|
|
159
|
+
status_console.print(
|
|
160
|
+
"[yellow]Warning: the API returned zero text-to-speech "
|
|
161
|
+
"models. Deepgram publishes text-to-speech models "
|
|
162
|
+
"(Aura-2), so an empty list usually means an API or "
|
|
163
|
+
"account problem, not an empty catalog.[/yellow]"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
if not all_models:
|
|
167
|
+
status_console.print("[yellow]No models found[/yellow]")
|
|
168
|
+
return ModelsResult(status="info", message="No models found")
|
|
169
|
+
|
|
170
|
+
# Render the human table only in default mode. For json/yaml/csv
|
|
171
|
+
# the framework serialises the returned result to stdout, so
|
|
172
|
+
# printing the table here would corrupt that output for piping.
|
|
173
|
+
if get_output_format() == "default":
|
|
174
|
+
table = Table(
|
|
175
|
+
title="Deepgram Models", show_header=True, header_style="bold blue"
|
|
176
|
+
)
|
|
177
|
+
table.add_column("Name", style="green")
|
|
178
|
+
table.add_column("Canonical name", style="green")
|
|
179
|
+
table.add_column("Architecture")
|
|
180
|
+
table.add_column("Type", style="cyan")
|
|
181
|
+
table.add_column("Languages")
|
|
182
|
+
table.add_column("Version")
|
|
183
|
+
table.add_column("ID", style="dim")
|
|
184
|
+
|
|
185
|
+
for m in all_models:
|
|
186
|
+
display_name = m.name
|
|
187
|
+
if m.deprecated:
|
|
188
|
+
display_name = f"{m.name} [yellow](deprecated)[/yellow]"
|
|
189
|
+
table.add_row(
|
|
190
|
+
display_name,
|
|
191
|
+
m.canonical_name,
|
|
192
|
+
m.architecture,
|
|
193
|
+
m.model_type.upper(),
|
|
194
|
+
_format_languages(m.languages),
|
|
195
|
+
m.version,
|
|
196
|
+
m.model_id,
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
console.print(table)
|
|
200
|
+
console.print(f"\n[dim]{len(all_models)} model(s) found[/dim]")
|
|
201
|
+
|
|
202
|
+
deprecated_notes = {
|
|
203
|
+
m.name: m.deprecation_note for m in all_models if m.deprecated
|
|
204
|
+
}
|
|
205
|
+
for name, note in sorted(deprecated_notes.items()):
|
|
206
|
+
console.print(f"[yellow]Deprecated:[/yellow] {name} — {note}")
|
|
207
|
+
|
|
208
|
+
return ModelsResult(
|
|
209
|
+
status="success",
|
|
210
|
+
models=all_models,
|
|
211
|
+
count=len(all_models),
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
except Exception as e:
|
|
215
|
+
status_console.print(f"[red]Error listing models:[/red] {e}")
|
|
216
|
+
return BaseResult(status="error", message=str(e))
|
|
@@ -9,9 +9,14 @@ from pydantic import BaseModel, Field
|
|
|
9
9
|
class ModelInfo(BaseModel):
|
|
10
10
|
model_id: str = ""
|
|
11
11
|
name: str = ""
|
|
12
|
+
canonical_name: str = "" # the value to pass as the `model` parameter
|
|
13
|
+
architecture: str = ""
|
|
12
14
|
version: str = ""
|
|
13
|
-
language: str = ""
|
|
15
|
+
language: str = "" # primary language (first entry of `languages`)
|
|
16
|
+
languages: list[str] = Field(default_factory=list)
|
|
14
17
|
model_type: str = "" # "stt" or "tts"
|
|
18
|
+
deprecated: bool = False
|
|
19
|
+
deprecation_note: str = ""
|
|
15
20
|
|
|
16
21
|
|
|
17
22
|
class ModelsResult(BaseResult):
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
"""Models command for deepctl."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import Any
|
|
6
|
-
|
|
7
|
-
from deepctl_core import (
|
|
8
|
-
AuthManager,
|
|
9
|
-
BaseCommand,
|
|
10
|
-
BaseResult,
|
|
11
|
-
Config,
|
|
12
|
-
DeepgramClient,
|
|
13
|
-
get_output_format,
|
|
14
|
-
get_status_console,
|
|
15
|
-
)
|
|
16
|
-
from rich.console import Console
|
|
17
|
-
from rich.table import Table
|
|
18
|
-
|
|
19
|
-
from .models import ModelInfo, ModelsResult
|
|
20
|
-
|
|
21
|
-
console = Console()
|
|
22
|
-
# Status/progress chrome must never touch stdout, or it corrupts JSON/CSV
|
|
23
|
-
# output that callers pipe into jq and friends.
|
|
24
|
-
status_console = get_status_console()
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class ModelsCommand(BaseCommand):
|
|
28
|
-
"""Command for listing available Deepgram models."""
|
|
29
|
-
|
|
30
|
-
name = "models"
|
|
31
|
-
help = "List available Deepgram models"
|
|
32
|
-
short_help = "List models"
|
|
33
|
-
|
|
34
|
-
requires_auth = True
|
|
35
|
-
requires_project = False
|
|
36
|
-
ci_friendly = True
|
|
37
|
-
|
|
38
|
-
examples = [
|
|
39
|
-
"dg models",
|
|
40
|
-
"dg models --type stt",
|
|
41
|
-
"dg models --type tts",
|
|
42
|
-
"dg models --include-outdated",
|
|
43
|
-
]
|
|
44
|
-
agent_help = (
|
|
45
|
-
"List available Deepgram speech-to-text and text-to-speech models. "
|
|
46
|
-
"Filter by type (stt/tts) and optionally include outdated versions. "
|
|
47
|
-
"Requires authentication."
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
def get_arguments(self) -> list[dict[str, Any]]:
|
|
51
|
-
return [
|
|
52
|
-
{
|
|
53
|
-
"names": ["--type", "-t"],
|
|
54
|
-
"help": "Filter by model type (stt, tts)",
|
|
55
|
-
"type": str,
|
|
56
|
-
"is_option": True,
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"names": ["--include-outdated"],
|
|
60
|
-
"help": "Include outdated model versions",
|
|
61
|
-
"is_flag": True,
|
|
62
|
-
"is_option": True,
|
|
63
|
-
},
|
|
64
|
-
]
|
|
65
|
-
|
|
66
|
-
def handle(
|
|
67
|
-
self,
|
|
68
|
-
config: Config,
|
|
69
|
-
auth_manager: AuthManager,
|
|
70
|
-
client: DeepgramClient,
|
|
71
|
-
**kwargs: Any,
|
|
72
|
-
) -> BaseResult:
|
|
73
|
-
model_type = kwargs.get("type")
|
|
74
|
-
include_outdated = kwargs.get("include_outdated", False)
|
|
75
|
-
|
|
76
|
-
try:
|
|
77
|
-
result = client.list_models(include_outdated=include_outdated)
|
|
78
|
-
|
|
79
|
-
stt_models = result.get("stt", [])
|
|
80
|
-
tts_models = result.get("tts", [])
|
|
81
|
-
|
|
82
|
-
all_models: list[ModelInfo] = []
|
|
83
|
-
|
|
84
|
-
if model_type != "tts":
|
|
85
|
-
for m in stt_models:
|
|
86
|
-
all_models.append(
|
|
87
|
-
ModelInfo(
|
|
88
|
-
model_id=m.get("uuid", m.get("model_id", "")),
|
|
89
|
-
name=m.get("name", ""),
|
|
90
|
-
version=m.get("version", ""),
|
|
91
|
-
language=m.get("language", ""),
|
|
92
|
-
model_type="stt",
|
|
93
|
-
)
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
if model_type != "stt":
|
|
97
|
-
for m in tts_models:
|
|
98
|
-
all_models.append(
|
|
99
|
-
ModelInfo(
|
|
100
|
-
model_id=m.get("uuid", m.get("model_id", "")),
|
|
101
|
-
name=m.get("name", ""),
|
|
102
|
-
version=m.get("version", ""),
|
|
103
|
-
language=m.get("language", ""),
|
|
104
|
-
model_type="tts",
|
|
105
|
-
)
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
if not all_models:
|
|
109
|
-
status_console.print("[yellow]No models found[/yellow]")
|
|
110
|
-
return ModelsResult(status="info", message="No models found")
|
|
111
|
-
|
|
112
|
-
# Render the human table only in default mode. For json/yaml/csv
|
|
113
|
-
# the framework serialises the returned result to stdout, so
|
|
114
|
-
# printing the table here would corrupt that output for piping.
|
|
115
|
-
if get_output_format() == "default":
|
|
116
|
-
table = Table(
|
|
117
|
-
title="Deepgram Models", show_header=True, header_style="bold blue"
|
|
118
|
-
)
|
|
119
|
-
table.add_column("Name", style="green")
|
|
120
|
-
table.add_column("Type", style="cyan")
|
|
121
|
-
table.add_column("Language")
|
|
122
|
-
table.add_column("Version")
|
|
123
|
-
table.add_column("ID", style="dim")
|
|
124
|
-
|
|
125
|
-
for m in all_models:
|
|
126
|
-
table.add_row(
|
|
127
|
-
m.name, m.model_type.upper(), m.language, m.version, m.model_id
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
console.print(table)
|
|
131
|
-
console.print(f"\n[dim]{len(all_models)} model(s) found[/dim]")
|
|
132
|
-
|
|
133
|
-
return ModelsResult(
|
|
134
|
-
status="success",
|
|
135
|
-
models=all_models,
|
|
136
|
-
count=len(all_models),
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
except Exception as e:
|
|
140
|
-
status_console.print(f"[red]Error listing models:[/red] {e}")
|
|
141
|
-
return BaseResult(status="error", message=str(e))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models.egg-info/requires.txt
RENAMED
|
File without changes
|
{deepctl_cmd_models-0.1.0 → deepctl_cmd_models-0.1.1}/src/deepctl_cmd_models.egg-info/top_level.txt
RENAMED
|
File without changes
|