lql-cli 0.3.0__tar.gz → 0.5.0__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.
- lql_cli-0.3.0/README.md → lql_cli-0.5.0/PKG-INFO +50 -7
- lql_cli-0.3.0/PKG-INFO → lql_cli-0.5.0/README.md +34 -22
- {lql_cli-0.3.0 → lql_cli-0.5.0}/pyproject.toml +3 -2
- lql_cli-0.5.0/src/lql/__init__.py +1 -0
- lql_cli-0.5.0/src/lql/_group.py +50 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/cli.py +3 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/annotations.py +3 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/auth.py +3 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/buckets.py +3 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/datasets.py +16 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/edits.py +3 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/evals.py +3 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/highlights.py +3 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/instructions.py +24 -3
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/issues.py +3 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/preview.py +254 -37
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/reports.py +3 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/skills.py +3 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/spec.py +3 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/tui.py +207 -13
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/workspaces.py +23 -4
- {lql_cli-0.3.0 → lql_cli-0.5.0}/uv.lock +109 -280
- lql_cli-0.3.0/src/lql/__init__.py +0 -1
- {lql_cli-0.3.0 → lql_cli-0.5.0}/.claude/settings.local.json +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/.gitignore +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/examples/agent-traces.jsonl +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/package-lock.json +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/_opts.py +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/api.py +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/__init__.py +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/commands/update.py +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/config.py +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/output.py +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/sessions.py +0 -0
- {lql_cli-0.3.0 → lql_cli-0.5.0}/src/lql/util.py +0 -0
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lql-cli
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: lql — CLI for the Liquid DataViewer platform
|
|
5
|
+
Project-URL: Homepage, https://github.com/Liquid4All/lql
|
|
6
|
+
Author: Liquid AI
|
|
7
|
+
License: MIT
|
|
8
|
+
Requires-Python: >=3.12
|
|
9
|
+
Requires-Dist: httpx>=0.27
|
|
10
|
+
Requires-Dist: huggingface-hub>=0.24
|
|
11
|
+
Requires-Dist: rich>=13.0
|
|
12
|
+
Requires-Dist: textual-image>=0.7
|
|
13
|
+
Requires-Dist: textual>=0.50
|
|
14
|
+
Requires-Dist: typer>=0.12
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
1
17
|
# lql — Liquid Query Language CLI
|
|
2
18
|
|
|
3
19
|
Scriptable CLI for the [Liquid DataViewer](https://dataviewer.liquid.ai) platform. Designed for both humans and AI agents (Claude Code, Codex, etc.) to automate datasets, eval analysis, spec docs, annotations, and more.
|
|
4
20
|
|
|
5
|
-
A Python package (Python ≥ 3.
|
|
21
|
+
A Python package (Python ≥ 3.12), published on PyPI as **[`lql-cli`](https://pypi.org/project/lql-cli/)** — the installed command is `lql`.
|
|
6
22
|
|
|
7
23
|
## Quick start
|
|
8
24
|
|
|
@@ -14,7 +30,7 @@ lql skills install # teach Claude Code + Codex how to use lql
|
|
|
14
30
|
|
|
15
31
|
## Install
|
|
16
32
|
|
|
17
|
-
`lql` is a Python package (requires Python ≥ 3.
|
|
33
|
+
`lql` is a Python package (requires Python ≥ 3.12), distributed on PyPI as **`lql-cli`** (the
|
|
18
34
|
command it installs is `lql`). Install it as a standalone CLI tool with
|
|
19
35
|
[uv](https://docs.astral.sh/uv/):
|
|
20
36
|
|
|
@@ -84,6 +100,13 @@ lql logout
|
|
|
84
100
|
|
|
85
101
|
## Command reference
|
|
86
102
|
|
|
103
|
+
Running a group with no subcommand (e.g. `lql datasets`) lists its subcommands.
|
|
104
|
+
For faster typing, **aliases** and **unique prefixes** resolve everywhere:
|
|
105
|
+
group aliases (`ds`, `ws`, `ev`, `ann`, `hl`, `rep`, `bkt`, `iss`), verb aliases
|
|
106
|
+
(`ls`=list, `rm`/`del`=delete, `new`/`mk`=create, `info`=show), and prefixes
|
|
107
|
+
(`lql datasets l` → `list`). So `lql ds ls --workspace <id>` ≡ `lql datasets list
|
|
108
|
+
--workspace <id>`. The canonical names below always work (use those in scripts).
|
|
109
|
+
|
|
87
110
|
### Auth
|
|
88
111
|
|
|
89
112
|
```
|
|
@@ -95,7 +118,7 @@ lql whoami Show current user
|
|
|
95
118
|
### Workspaces
|
|
96
119
|
|
|
97
120
|
```
|
|
98
|
-
lql workspaces list
|
|
121
|
+
lql workspaces list [--search <text>] List workspaces (--search filters by name/slug)
|
|
99
122
|
lql workspaces create <name> Create a workspace
|
|
100
123
|
lql workspaces show <id> Show workspace details
|
|
101
124
|
lql workspaces update <id> --name <n> Rename a workspace
|
|
@@ -108,7 +131,7 @@ lql workspaces members remove <id> <uid> Remove member by user ID
|
|
|
108
131
|
### Datasets
|
|
109
132
|
|
|
110
133
|
```
|
|
111
|
-
lql datasets list [--workspace <id>]
|
|
134
|
+
lql datasets list [--workspace <id>] [--search <text>] List datasets (--search filters by name/HF repo)
|
|
112
135
|
lql datasets show <id> Show dataset details
|
|
113
136
|
lql datasets create --workspace <id> --hf-repo <repo> [--name <n>] [--split <s>]
|
|
114
137
|
lql datasets create --workspace <id> --hf-bucket <org/bucket> --key <path-or-glob> [--name <n>]
|
|
@@ -134,23 +157,43 @@ multimodal content (text/image/audio), ShareGPT `{from, value}`, native OpenAI
|
|
|
134
157
|
`tool_calls`, plus `<think>` reasoning blocks, `<|tool_call_start|>…<|tool_call_end|>`
|
|
135
158
|
/ Python / XML / JSON tool calls, tool results, tool-definition tables, and code.
|
|
136
159
|
|
|
137
|
-
Works on a local `.jsonl`/`.json` file
|
|
138
|
-
nothing to forward over SSH — it's just
|
|
160
|
+
Works on a local `.jsonl`/`.json` file, a platform dataset ID, or — with `--hf`
|
|
161
|
+
— a HuggingFace repo. No browser, and nothing to forward over SSH — it's just
|
|
162
|
+
the terminal.
|
|
139
163
|
|
|
140
164
|
```
|
|
141
165
|
lql preview <file.jsonl|file.json> Local file: each line/object is a row
|
|
142
166
|
lql preview <dataset-id> Platform dataset (fetched & paged lazily)
|
|
167
|
+
lql preview <org/name> --hf HuggingFace repo: sync to DataViewer, then view
|
|
143
168
|
lql preview <src> -c <field> Force field(s) as conversations (repeatable)
|
|
144
169
|
lql preview <src> -n <N> Page size when paging a platform dataset
|
|
145
170
|
lql preview <src> --offset N Start at row index N
|
|
146
171
|
lql preview <src> --title "<title>" Title shown in the viewer header
|
|
147
172
|
```
|
|
148
173
|
|
|
174
|
+
**HuggingFace datasets (`--hf`).** `lql preview org/name --hf` syncs the repo
|
|
175
|
+
into a DataViewer workspace, then opens it. You pick the target workspace from
|
|
176
|
+
an interactive list (or pass `--workspace <id>`; `--split` defaults to `train`).
|
|
177
|
+
Already-synced repos are reused — no duplicate, instant re-open.
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
lql preview tatsu-lab/alpaca --hf
|
|
181
|
+
lql preview org/name --hf --split validation --workspace <id>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Media.** Images render **inline** in terminals that support an image protocol
|
|
185
|
+
(Kitty/Ghostty, iTerm2, Sixel; falls back to a compact `🖼 …` placeholder
|
|
186
|
+
elsewhere) — both multimodal `image_url`/data-URI segments and image-mode
|
|
187
|
+
columns. Audio can't play inline in a terminal, so each clip shows a `♪` line
|
|
188
|
+
and **`p` plays** the current sample's audio via the system player (`afplay`/
|
|
189
|
+
`open`). Images render inline in pager mode (one sample at a time); scroll mode
|
|
190
|
+
shows placeholders to avoid decoding the whole buffer.
|
|
191
|
+
|
|
149
192
|
**Navigation** — two modes, toggle with `m` / `Tab`:
|
|
150
193
|
|
|
151
194
|
- **pager** (default): one sample at a time · `←/→` or `n`/`b` switch samples · `↑/↓`/`j`/`k`/PgUp-Dn scroll
|
|
152
195
|
- **scroll**: all samples in one buffer · `n`/`b` jump between samples · arrows scroll
|
|
153
|
-
- `q` quits
|
|
196
|
+
- `p` play audio · `q` quits
|
|
154
197
|
|
|
155
198
|
```
|
|
156
199
|
lql preview examples/agent-traces.jsonl # 20-sample file of agent-trace/tool-use formats
|
|
@@ -1,23 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: lql-cli
|
|
3
|
-
Version: 0.3.0
|
|
4
|
-
Summary: lql — CLI for the Liquid DataViewer platform
|
|
5
|
-
Project-URL: Homepage, https://github.com/Liquid4All/lql
|
|
6
|
-
Author: Liquid AI
|
|
7
|
-
License: MIT
|
|
8
|
-
Requires-Python: >=3.9
|
|
9
|
-
Requires-Dist: httpx>=0.27
|
|
10
|
-
Requires-Dist: huggingface-hub>=0.24
|
|
11
|
-
Requires-Dist: rich>=13.0
|
|
12
|
-
Requires-Dist: textual>=0.50
|
|
13
|
-
Requires-Dist: typer>=0.12
|
|
14
|
-
Description-Content-Type: text/markdown
|
|
15
|
-
|
|
16
1
|
# lql — Liquid Query Language CLI
|
|
17
2
|
|
|
18
3
|
Scriptable CLI for the [Liquid DataViewer](https://dataviewer.liquid.ai) platform. Designed for both humans and AI agents (Claude Code, Codex, etc.) to automate datasets, eval analysis, spec docs, annotations, and more.
|
|
19
4
|
|
|
20
|
-
A Python package (Python ≥ 3.
|
|
5
|
+
A Python package (Python ≥ 3.12), published on PyPI as **[`lql-cli`](https://pypi.org/project/lql-cli/)** — the installed command is `lql`.
|
|
21
6
|
|
|
22
7
|
## Quick start
|
|
23
8
|
|
|
@@ -29,7 +14,7 @@ lql skills install # teach Claude Code + Codex how to use lql
|
|
|
29
14
|
|
|
30
15
|
## Install
|
|
31
16
|
|
|
32
|
-
`lql` is a Python package (requires Python ≥ 3.
|
|
17
|
+
`lql` is a Python package (requires Python ≥ 3.12), distributed on PyPI as **`lql-cli`** (the
|
|
33
18
|
command it installs is `lql`). Install it as a standalone CLI tool with
|
|
34
19
|
[uv](https://docs.astral.sh/uv/):
|
|
35
20
|
|
|
@@ -99,6 +84,13 @@ lql logout
|
|
|
99
84
|
|
|
100
85
|
## Command reference
|
|
101
86
|
|
|
87
|
+
Running a group with no subcommand (e.g. `lql datasets`) lists its subcommands.
|
|
88
|
+
For faster typing, **aliases** and **unique prefixes** resolve everywhere:
|
|
89
|
+
group aliases (`ds`, `ws`, `ev`, `ann`, `hl`, `rep`, `bkt`, `iss`), verb aliases
|
|
90
|
+
(`ls`=list, `rm`/`del`=delete, `new`/`mk`=create, `info`=show), and prefixes
|
|
91
|
+
(`lql datasets l` → `list`). So `lql ds ls --workspace <id>` ≡ `lql datasets list
|
|
92
|
+
--workspace <id>`. The canonical names below always work (use those in scripts).
|
|
93
|
+
|
|
102
94
|
### Auth
|
|
103
95
|
|
|
104
96
|
```
|
|
@@ -110,7 +102,7 @@ lql whoami Show current user
|
|
|
110
102
|
### Workspaces
|
|
111
103
|
|
|
112
104
|
```
|
|
113
|
-
lql workspaces list
|
|
105
|
+
lql workspaces list [--search <text>] List workspaces (--search filters by name/slug)
|
|
114
106
|
lql workspaces create <name> Create a workspace
|
|
115
107
|
lql workspaces show <id> Show workspace details
|
|
116
108
|
lql workspaces update <id> --name <n> Rename a workspace
|
|
@@ -123,7 +115,7 @@ lql workspaces members remove <id> <uid> Remove member by user ID
|
|
|
123
115
|
### Datasets
|
|
124
116
|
|
|
125
117
|
```
|
|
126
|
-
lql datasets list [--workspace <id>]
|
|
118
|
+
lql datasets list [--workspace <id>] [--search <text>] List datasets (--search filters by name/HF repo)
|
|
127
119
|
lql datasets show <id> Show dataset details
|
|
128
120
|
lql datasets create --workspace <id> --hf-repo <repo> [--name <n>] [--split <s>]
|
|
129
121
|
lql datasets create --workspace <id> --hf-bucket <org/bucket> --key <path-or-glob> [--name <n>]
|
|
@@ -149,23 +141,43 @@ multimodal content (text/image/audio), ShareGPT `{from, value}`, native OpenAI
|
|
|
149
141
|
`tool_calls`, plus `<think>` reasoning blocks, `<|tool_call_start|>…<|tool_call_end|>`
|
|
150
142
|
/ Python / XML / JSON tool calls, tool results, tool-definition tables, and code.
|
|
151
143
|
|
|
152
|
-
Works on a local `.jsonl`/`.json` file
|
|
153
|
-
nothing to forward over SSH — it's just
|
|
144
|
+
Works on a local `.jsonl`/`.json` file, a platform dataset ID, or — with `--hf`
|
|
145
|
+
— a HuggingFace repo. No browser, and nothing to forward over SSH — it's just
|
|
146
|
+
the terminal.
|
|
154
147
|
|
|
155
148
|
```
|
|
156
149
|
lql preview <file.jsonl|file.json> Local file: each line/object is a row
|
|
157
150
|
lql preview <dataset-id> Platform dataset (fetched & paged lazily)
|
|
151
|
+
lql preview <org/name> --hf HuggingFace repo: sync to DataViewer, then view
|
|
158
152
|
lql preview <src> -c <field> Force field(s) as conversations (repeatable)
|
|
159
153
|
lql preview <src> -n <N> Page size when paging a platform dataset
|
|
160
154
|
lql preview <src> --offset N Start at row index N
|
|
161
155
|
lql preview <src> --title "<title>" Title shown in the viewer header
|
|
162
156
|
```
|
|
163
157
|
|
|
158
|
+
**HuggingFace datasets (`--hf`).** `lql preview org/name --hf` syncs the repo
|
|
159
|
+
into a DataViewer workspace, then opens it. You pick the target workspace from
|
|
160
|
+
an interactive list (or pass `--workspace <id>`; `--split` defaults to `train`).
|
|
161
|
+
Already-synced repos are reused — no duplicate, instant re-open.
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
lql preview tatsu-lab/alpaca --hf
|
|
165
|
+
lql preview org/name --hf --split validation --workspace <id>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Media.** Images render **inline** in terminals that support an image protocol
|
|
169
|
+
(Kitty/Ghostty, iTerm2, Sixel; falls back to a compact `🖼 …` placeholder
|
|
170
|
+
elsewhere) — both multimodal `image_url`/data-URI segments and image-mode
|
|
171
|
+
columns. Audio can't play inline in a terminal, so each clip shows a `♪` line
|
|
172
|
+
and **`p` plays** the current sample's audio via the system player (`afplay`/
|
|
173
|
+
`open`). Images render inline in pager mode (one sample at a time); scroll mode
|
|
174
|
+
shows placeholders to avoid decoding the whole buffer.
|
|
175
|
+
|
|
164
176
|
**Navigation** — two modes, toggle with `m` / `Tab`:
|
|
165
177
|
|
|
166
178
|
- **pager** (default): one sample at a time · `←/→` or `n`/`b` switch samples · `↑/↓`/`j`/`k`/PgUp-Dn scroll
|
|
167
179
|
- **scroll**: all samples in one buffer · `n`/`b` jump between samples · arrows scroll
|
|
168
|
-
- `q` quits
|
|
180
|
+
- `p` play audio · `q` quits
|
|
169
181
|
|
|
170
182
|
```
|
|
171
183
|
lql preview examples/agent-traces.jsonl # 20-sample file of agent-trace/tool-use formats
|
|
@@ -4,10 +4,10 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "lql-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.5.0"
|
|
8
8
|
description = "lql — CLI for the Liquid DataViewer platform"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
11
|
license = { text = "MIT" }
|
|
12
12
|
authors = [{ name = "Liquid AI" }]
|
|
13
13
|
dependencies = [
|
|
@@ -16,6 +16,7 @@ dependencies = [
|
|
|
16
16
|
"rich>=13.0",
|
|
17
17
|
"huggingface-hub>=0.24",
|
|
18
18
|
"textual>=0.50",
|
|
19
|
+
"textual-image>=0.7",
|
|
19
20
|
]
|
|
20
21
|
|
|
21
22
|
[project.scripts]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.5.0"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""A Typer/Click group that adds two conveniences to every command group:
|
|
2
|
+
|
|
3
|
+
* short aliases — `ds`→`datasets`, `ws`→`workspaces`, `ls`→`list`, …
|
|
4
|
+
* unique-prefix matching — `lql datasets l` resolves to `list`
|
|
5
|
+
|
|
6
|
+
Both are purely additive: the canonical command names always work, and
|
|
7
|
+
`lql instructions` documents the canonical forms, so agents are unaffected —
|
|
8
|
+
these are conveniences for humans typing at a prompt.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from typer.core import TyperGroup
|
|
12
|
+
|
|
13
|
+
# alias -> canonical. Kept intentionally small and unambiguous.
|
|
14
|
+
ALIASES = {
|
|
15
|
+
# command groups
|
|
16
|
+
"ds": "datasets",
|
|
17
|
+
"ws": "workspaces",
|
|
18
|
+
"ev": "eval",
|
|
19
|
+
"evals": "eval",
|
|
20
|
+
"ann": "annotations",
|
|
21
|
+
"hl": "highlights",
|
|
22
|
+
"rep": "reports",
|
|
23
|
+
"bkt": "buckets",
|
|
24
|
+
"iss": "issues",
|
|
25
|
+
# verbs
|
|
26
|
+
"ls": "list",
|
|
27
|
+
"rm": "delete",
|
|
28
|
+
"del": "delete",
|
|
29
|
+
"new": "create",
|
|
30
|
+
"mk": "create",
|
|
31
|
+
"info": "show",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class AliasGroup(TyperGroup):
|
|
36
|
+
def get_command(self, ctx, name):
|
|
37
|
+
# Exact name first so a real command is never shadowed by an alias;
|
|
38
|
+
# then explicit alias; then an unambiguous prefix.
|
|
39
|
+
cmd = super().get_command(ctx, name)
|
|
40
|
+
if cmd is not None:
|
|
41
|
+
return cmd
|
|
42
|
+
alias = ALIASES.get(name)
|
|
43
|
+
if alias is not None:
|
|
44
|
+
cmd = super().get_command(ctx, alias)
|
|
45
|
+
if cmd is not None:
|
|
46
|
+
return cmd
|
|
47
|
+
matches = [c for c in self.list_commands(ctx) if c.startswith(name)]
|
|
48
|
+
if len(matches) == 1:
|
|
49
|
+
return super().get_command(ctx, matches[0])
|
|
50
|
+
return None
|
|
@@ -3,6 +3,8 @@ from typing import Annotated, Optional
|
|
|
3
3
|
|
|
4
4
|
import typer
|
|
5
5
|
|
|
6
|
+
from ._group import AliasGroup
|
|
7
|
+
|
|
6
8
|
from . import __version__
|
|
7
9
|
from .output import print_error
|
|
8
10
|
from .commands import (
|
|
@@ -32,6 +34,7 @@ app = typer.Typer(
|
|
|
32
34
|
),
|
|
33
35
|
no_args_is_help=True,
|
|
34
36
|
add_completion=False,
|
|
37
|
+
cls=AliasGroup,
|
|
35
38
|
)
|
|
36
39
|
|
|
37
40
|
|
|
@@ -3,13 +3,15 @@ from typing import Annotated, Optional
|
|
|
3
3
|
|
|
4
4
|
import typer
|
|
5
5
|
|
|
6
|
+
from .._group import AliasGroup
|
|
7
|
+
|
|
6
8
|
from .._opts import ApiUrlOpt, JsonOpt, ProfileOpt
|
|
7
9
|
from ..api import ApiClient
|
|
8
10
|
from ..output import print_json, print_table
|
|
9
11
|
from ..sessions import resolve_session_id
|
|
10
12
|
from ..util import q
|
|
11
13
|
|
|
12
|
-
app = typer.Typer(help="Manage annotations")
|
|
14
|
+
app = typer.Typer(help="Manage annotations", cls=AliasGroup, no_args_is_help=True)
|
|
13
15
|
|
|
14
16
|
SessionOpt = Annotated[Optional[str], typer.Option("--session", help="Target a specific review session (advanced)")]
|
|
15
17
|
|
|
@@ -7,6 +7,8 @@ from typing import Annotated, Optional
|
|
|
7
7
|
import httpx
|
|
8
8
|
import typer
|
|
9
9
|
|
|
10
|
+
from .._group import AliasGroup
|
|
11
|
+
|
|
10
12
|
from .._opts import ApiUrlOpt, JsonOpt, ProfileOpt
|
|
11
13
|
from ..api import ApiClient
|
|
12
14
|
from ..config import get_api_url, read_config, validate_api_url, write_config
|
|
@@ -148,7 +150,7 @@ def whoami(
|
|
|
148
150
|
)
|
|
149
151
|
|
|
150
152
|
|
|
151
|
-
auth_app = typer.Typer(help="Authentication commands")
|
|
153
|
+
auth_app = typer.Typer(help="Authentication commands", cls=AliasGroup, no_args_is_help=True)
|
|
152
154
|
auth_app.command("login")(login)
|
|
153
155
|
auth_app.command("logout")(logout)
|
|
154
156
|
auth_app.command("whoami")(whoami)
|
|
@@ -4,12 +4,14 @@ from typing import Annotated, Optional
|
|
|
4
4
|
|
|
5
5
|
import typer
|
|
6
6
|
|
|
7
|
+
from .._group import AliasGroup
|
|
8
|
+
|
|
7
9
|
from .._opts import ApiUrlOpt, JsonOpt, ProfileOpt
|
|
8
10
|
from ..api import ApiClient
|
|
9
11
|
from ..output import print_json, print_table
|
|
10
12
|
from ..util import q
|
|
11
13
|
|
|
12
|
-
app = typer.Typer(help="Manage S3 and Hugging Face buckets")
|
|
14
|
+
app = typer.Typer(help="Manage S3 and Hugging Face buckets", cls=AliasGroup, no_args_is_help=True)
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
@app.command("list")
|
|
@@ -6,12 +6,14 @@ from typing import Annotated, Optional
|
|
|
6
6
|
|
|
7
7
|
import typer
|
|
8
8
|
|
|
9
|
+
from .._group import AliasGroup
|
|
10
|
+
|
|
9
11
|
from .._opts import ApiUrlOpt, JsonOpt, ProfileOpt
|
|
10
12
|
from ..api import ApiClient
|
|
11
13
|
from ..output import print_error, print_json, print_table
|
|
12
14
|
from ..util import q
|
|
13
15
|
|
|
14
|
-
app = typer.Typer(help="Manage datasets")
|
|
16
|
+
app = typer.Typer(help="Manage datasets", cls=AliasGroup, no_args_is_help=True)
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
def _truncate(v: object, n: int = 80) -> str:
|
|
@@ -22,6 +24,10 @@ def _truncate(v: object, n: int = 80) -> str:
|
|
|
22
24
|
@app.command("list")
|
|
23
25
|
def list_datasets(
|
|
24
26
|
workspace: Annotated[Optional[str], typer.Option("--workspace", help="Filter by workspace ID")] = None,
|
|
27
|
+
search: Annotated[
|
|
28
|
+
Optional[str],
|
|
29
|
+
typer.Option("--search", "-s", help="Filter by case-insensitive substring of name / HF repo"),
|
|
30
|
+
] = None,
|
|
25
31
|
json_out: JsonOpt = False,
|
|
26
32
|
profile: ProfileOpt = None,
|
|
27
33
|
api_url: ApiUrlOpt = None,
|
|
@@ -32,6 +38,15 @@ def list_datasets(
|
|
|
32
38
|
if workspace:
|
|
33
39
|
params["workspace_id"] = workspace
|
|
34
40
|
items = client.get("/v1/datasets", params=params).json()
|
|
41
|
+
if search:
|
|
42
|
+
s = search.lower()
|
|
43
|
+
items = [
|
|
44
|
+
d
|
|
45
|
+
for d in items
|
|
46
|
+
if s in (d.get("display_name") or "").lower()
|
|
47
|
+
or s in (d.get("name") or "").lower()
|
|
48
|
+
or s in (d.get("hf_repo_id") or "").lower()
|
|
49
|
+
]
|
|
35
50
|
print_table(
|
|
36
51
|
["ID", "Name", "Workspace", "Rows"],
|
|
37
52
|
[
|
|
@@ -4,12 +4,14 @@ from typing import Annotated, Optional
|
|
|
4
4
|
|
|
5
5
|
import typer
|
|
6
6
|
|
|
7
|
+
from .._group import AliasGroup
|
|
8
|
+
|
|
7
9
|
from .._opts import ApiUrlOpt, JsonOpt, ProfileOpt
|
|
8
10
|
from ..api import ApiClient
|
|
9
11
|
from ..output import print_error, print_json, print_table
|
|
10
12
|
from ..util import q
|
|
11
13
|
|
|
12
|
-
app = typer.Typer(help="Manage row edits")
|
|
14
|
+
app = typer.Typer(help="Manage row edits", cls=AliasGroup, no_args_is_help=True)
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
@app.command("list")
|
|
@@ -6,12 +6,14 @@ from typing import Annotated, List, Optional
|
|
|
6
6
|
|
|
7
7
|
import typer
|
|
8
8
|
|
|
9
|
+
from .._group import AliasGroup
|
|
10
|
+
|
|
9
11
|
from .._opts import ApiUrlOpt, JsonOpt, ProfileOpt
|
|
10
12
|
from ..api import ApiClient
|
|
11
13
|
from ..output import print_error, print_json, print_table
|
|
12
14
|
from ..util import q
|
|
13
15
|
|
|
14
|
-
app = typer.Typer(help="Inspect and analyze eval datasets (accuracy, failure modes, samples)")
|
|
16
|
+
app = typer.Typer(help="Inspect and analyze eval datasets (accuracy, failure modes, samples)", cls=AliasGroup, no_args_is_help=True)
|
|
15
17
|
|
|
16
18
|
# Mirrors front/src/lib/eval-dataset.ts so `eval samples --search` searches the
|
|
17
19
|
# same prompt/response columns the eval views do.
|
|
@@ -3,13 +3,15 @@ from typing import Annotated, Optional
|
|
|
3
3
|
|
|
4
4
|
import typer
|
|
5
5
|
|
|
6
|
+
from .._group import AliasGroup
|
|
7
|
+
|
|
6
8
|
from .._opts import ApiUrlOpt, JsonOpt, ProfileOpt
|
|
7
9
|
from ..api import ApiClient
|
|
8
10
|
from ..output import print_error, print_json, print_table
|
|
9
11
|
from ..sessions import resolve_session_id
|
|
10
12
|
from ..util import q
|
|
11
13
|
|
|
12
|
-
app = typer.Typer(help="Manage highlights")
|
|
14
|
+
app = typer.Typer(help="Manage highlights", cls=AliasGroup, no_args_is_help=True)
|
|
13
15
|
|
|
14
16
|
SessionOpt = Annotated[Optional[str], typer.Option("--session", help="Target a specific review session (advanced)")]
|
|
15
17
|
|
|
@@ -8,6 +8,15 @@ INSTRUCTIONS = r"""
|
|
|
8
8
|
CLI for the DataViewer platform. Gives agents and humans complete scriptable
|
|
9
9
|
control over workspaces, datasets, spec docs, annotations, and S3.
|
|
10
10
|
|
|
11
|
+
Running a group with no subcommand (e.g. `lql datasets`) lists its subcommands.
|
|
12
|
+
|
|
13
|
+
Shortcuts (for humans typing): group aliases (`ds`=datasets, `ws`=workspaces,
|
|
14
|
+
`ev`=eval, `ann`=annotations, `hl`=highlights, `rep`=reports, `bkt`=buckets,
|
|
15
|
+
`iss`=issues), verb aliases (`ls`=list, `rm`/`del`=delete, `new`/`mk`=create,
|
|
16
|
+
`info`=show), and unique prefixes (`lql datasets l` → list) all resolve.
|
|
17
|
+
AGENTS: use the full canonical names shown throughout this reference — they are
|
|
18
|
+
the stable contract; the aliases are conveniences layered on top.
|
|
19
|
+
|
|
11
20
|
## Authentication
|
|
12
21
|
|
|
13
22
|
lql login # Open browser → click Authorize → token stored automatically
|
|
@@ -43,7 +52,7 @@ Pagination: --limit N --offset N on list commands.
|
|
|
43
52
|
|
|
44
53
|
A workspace is the top-level container for datasets, spec docs, and members.
|
|
45
54
|
|
|
46
|
-
lql workspaces list
|
|
55
|
+
lql workspaces list [--search <text>] # --search filters by name / slug substring
|
|
47
56
|
lql workspaces create <name>
|
|
48
57
|
lql workspaces show <id>
|
|
49
58
|
lql workspaces update <id> --name <new-name>
|
|
@@ -54,7 +63,7 @@ A workspace is the top-level container for datasets, spec docs, and members.
|
|
|
54
63
|
|
|
55
64
|
## Datasets
|
|
56
65
|
|
|
57
|
-
lql datasets list [--workspace <id>]
|
|
66
|
+
lql datasets list [--workspace <id>] [--search <text>] # --search filters by name / HF repo substring
|
|
58
67
|
lql datasets show <id>
|
|
59
68
|
lql datasets create --workspace <id> --hf-repo <org/repo> [--name <display>] [--split <split>]
|
|
60
69
|
lql datasets create --workspace <id> --hf-bucket <org/bucket> --key <path-or-glob> [--name <display>]
|
|
@@ -83,16 +92,26 @@ Non-conversation fields render as labeled metadata.
|
|
|
83
92
|
|
|
84
93
|
lql preview <file.jsonl|file.json> # local file: each line/object is a row
|
|
85
94
|
lql preview <dataset-id> # platform dataset, fetched & paged lazily
|
|
95
|
+
lql preview <org/name> --hf # HuggingFace repo: sync to DataViewer, then view
|
|
86
96
|
lql preview data.jsonl -c messages # force field(s) as conversations
|
|
87
97
|
|
|
98
|
+
With --hf, SOURCE is a HuggingFace repo (org/name): it's synced into a
|
|
99
|
+
DataViewer workspace (you pick one interactively, or pass --workspace <id>;
|
|
100
|
+
--split defaults to train) and reused on later previews (dedup by repo+split).
|
|
101
|
+
|
|
88
102
|
Options: -c/--column (field(s) to treat as conversations; default auto-detect,
|
|
89
103
|
repeatable), -n/--limit (page size when paging a platform dataset), --offset
|
|
90
|
-
(start row index), --title, --profile, --api-url.
|
|
104
|
+
(start row index), --title, --hf, --split, --workspace, --profile, --api-url.
|
|
91
105
|
|
|
92
106
|
Navigation: two modes toggled with m/Tab — pager (one sample at a time; ←/→ or
|
|
93
107
|
n/b switch samples, ↑/↓/j/k scroll) and scroll (all samples; n/b jump between
|
|
94
108
|
them). q quits. Works over plain SSH with no browser or port-forward.
|
|
95
109
|
|
|
110
|
+
Media: images render inline in image-capable terminals (Kitty/Ghostty, iTerm2,
|
|
111
|
+
Sixel; placeholder otherwise) for both multimodal image segments and image-mode
|
|
112
|
+
columns; audio shows a ♪ line and `p` plays the current sample's clip via the
|
|
113
|
+
system player (afplay/open).
|
|
114
|
+
|
|
96
115
|
## Evals
|
|
97
116
|
|
|
98
117
|
Eval datasets (evaluation-run output: each row a sample with a model 'response'
|
|
@@ -215,7 +234,9 @@ never goes stale.
|
|
|
215
234
|
|
|
216
235
|
### Discover workspaces and datasets
|
|
217
236
|
lql workspaces list --json
|
|
237
|
+
lql workspaces list --search <name> --json # find a workspace by name
|
|
218
238
|
lql datasets list --workspace <id> --json
|
|
239
|
+
lql datasets list --search <name> --json # find a dataset by name / HF repo
|
|
219
240
|
|
|
220
241
|
### Read dataset contents
|
|
221
242
|
lql datasets schema <id> --json
|
|
@@ -3,12 +3,14 @@ from typing import Annotated, Optional
|
|
|
3
3
|
|
|
4
4
|
import typer
|
|
5
5
|
|
|
6
|
+
from .._group import AliasGroup
|
|
7
|
+
|
|
6
8
|
from .._opts import ApiUrlOpt, JsonOpt, ProfileOpt
|
|
7
9
|
from ..api import ApiClient
|
|
8
10
|
from ..output import print_json, print_table
|
|
9
11
|
from ..util import q
|
|
10
12
|
|
|
11
|
-
app = typer.Typer(help="Manage issues")
|
|
13
|
+
app = typer.Typer(help="Manage issues", cls=AliasGroup, no_args_is_help=True)
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
@app.command("list")
|