lql-cli 0.2.1__tar.gz → 0.4.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.
Files changed (34) hide show
  1. {lql_cli-0.2.1 → lql_cli-0.4.0}/.gitignore +2 -0
  2. {lql_cli-0.2.1 → lql_cli-0.4.0}/PKG-INFO +56 -2
  3. {lql_cli-0.2.1 → lql_cli-0.4.0}/README.md +54 -1
  4. lql_cli-0.4.0/examples/agent-traces.jsonl +20 -0
  5. lql_cli-0.4.0/package-lock.json +6 -0
  6. {lql_cli-0.2.1 → lql_cli-0.4.0}/pyproject.toml +2 -1
  7. lql_cli-0.4.0/src/lql/__init__.py +1 -0
  8. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/cli.py +4 -11
  9. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/instructions.py +27 -0
  10. lql_cli-0.4.0/src/lql/commands/preview.py +812 -0
  11. lql_cli-0.4.0/src/lql/commands/tui.py +552 -0
  12. lql_cli-0.4.0/src/lql/commands/update.py +82 -0
  13. {lql_cli-0.2.1 → lql_cli-0.4.0}/uv.lock +141 -1
  14. lql_cli-0.2.1/src/lql/__init__.py +0 -1
  15. {lql_cli-0.2.1 → lql_cli-0.4.0}/.claude/settings.local.json +0 -0
  16. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/_opts.py +0 -0
  17. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/api.py +0 -0
  18. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/__init__.py +0 -0
  19. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/annotations.py +0 -0
  20. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/auth.py +0 -0
  21. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/buckets.py +0 -0
  22. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/datasets.py +0 -0
  23. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/edits.py +0 -0
  24. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/evals.py +0 -0
  25. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/highlights.py +0 -0
  26. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/issues.py +0 -0
  27. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/reports.py +0 -0
  28. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/skills.py +0 -0
  29. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/spec.py +0 -0
  30. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/commands/workspaces.py +0 -0
  31. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/config.py +0 -0
  32. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/output.py +0 -0
  33. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/sessions.py +0 -0
  34. {lql_cli-0.2.1 → lql_cli-0.4.0}/src/lql/util.py +0 -0
@@ -13,3 +13,5 @@ venv/
13
13
 
14
14
  # local config
15
15
  ~/.lql/
16
+
17
+ .env
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lql-cli
3
- Version: 0.2.1
3
+ Version: 0.4.0
4
4
  Summary: lql — CLI for the Liquid DataViewer platform
5
5
  Project-URL: Homepage, https://github.com/Liquid4All/lql
6
6
  Author: Liquid AI
@@ -9,6 +9,7 @@ Requires-Python: >=3.9
9
9
  Requires-Dist: httpx>=0.27
10
10
  Requires-Dist: huggingface-hub>=0.24
11
11
  Requires-Dist: rich>=13.0
12
+ Requires-Dist: textual>=0.50
12
13
  Requires-Dist: typer>=0.12
13
14
  Description-Content-Type: text/markdown
14
15
 
@@ -58,7 +59,9 @@ cd lql
58
59
  uv tool install . # or: pip install -e .
59
60
  ```
60
61
 
61
- Update to the latest version with `uv tool upgrade lql-cli` (or `pipx upgrade lql-cli` / `pip install -U lql-cli`).
62
+ Update to the latest version with `lql update --run`, which detects how lql was
63
+ installed (uv tool / pipx / pip) and runs the matching upgrade. Run `lql update`
64
+ (no flag) to just print the command without executing it.
62
65
 
63
66
  ## Authentication
64
67
 
@@ -137,6 +140,50 @@ lql datasets upload <file> --workspace <id> --name <repo-name> [--split <s>]
137
140
 
138
141
  `datasets upload` requires `LQL_HF_TOKEN`.
139
142
 
143
+ ### Preview
144
+
145
+ View dataset samples in the terminal — a Textual TUI with a chat-style layout
146
+ (user turns on the right, system/assistant/tool on the left). It renders the
147
+ same formats as the DataViewer web UI: OpenAI `{role, content}`, structured/
148
+ multimodal content (text/image/audio), ShareGPT `{from, value}`, native OpenAI
149
+ `tool_calls`, plus `<think>` reasoning blocks, `<|tool_call_start|>…<|tool_call_end|>`
150
+ / Python / XML / JSON tool calls, tool results, tool-definition tables, and code.
151
+
152
+ Works on a local `.jsonl`/`.json` file, a platform dataset ID, or — with `--hf`
153
+ — a HuggingFace repo. No browser, and nothing to forward over SSH — it's just
154
+ the terminal.
155
+
156
+ ```
157
+ lql preview <file.jsonl|file.json> Local file: each line/object is a row
158
+ lql preview <dataset-id> Platform dataset (fetched & paged lazily)
159
+ lql preview <org/name> --hf HuggingFace repo: sync to DataViewer, then view
160
+ lql preview <src> -c <field> Force field(s) as conversations (repeatable)
161
+ lql preview <src> -n <N> Page size when paging a platform dataset
162
+ lql preview <src> --offset N Start at row index N
163
+ lql preview <src> --title "<title>" Title shown in the viewer header
164
+ ```
165
+
166
+ **HuggingFace datasets (`--hf`).** `lql preview org/name --hf` syncs the repo
167
+ into a DataViewer workspace, then opens it. You pick the target workspace from
168
+ an interactive list (or pass `--workspace <id>`; `--split` defaults to `train`).
169
+ Already-synced repos are reused — no duplicate, instant re-open.
170
+
171
+ ```
172
+ lql preview tatsu-lab/alpaca --hf
173
+ lql preview org/name --hf --split validation --workspace <id>
174
+ ```
175
+
176
+ **Navigation** — two modes, toggle with `m` / `Tab`:
177
+
178
+ - **pager** (default): one sample at a time · `←/→` or `n`/`b` switch samples · `↑/↓`/`j`/`k`/PgUp-Dn scroll
179
+ - **scroll**: all samples in one buffer · `n`/`b` jump between samples · arrows scroll
180
+ - `q` quits
181
+
182
+ ```
183
+ lql preview examples/agent-traces.jsonl # 20-sample file of agent-trace/tool-use formats
184
+ lql preview <dataset-id> # browse a platform dataset, paged on demand
185
+ ```
186
+
140
187
  ### Evals (dataset analysis)
141
188
 
142
189
  Eval datasets are evaluation-run output — each row a sample with a model
@@ -284,6 +331,13 @@ lql instructions Print the full agent reference
284
331
  flags, examples, and workflows) in one read
285
332
  ```
286
333
 
334
+ ### Update
335
+
336
+ ```
337
+ lql update Detect install method (uv/pipx/pip), print upgrade cmd
338
+ lql update --run Detect and run the upgrade in place
339
+ ```
340
+
287
341
  ## Global flags
288
342
 
289
343
  All commands accept:
@@ -44,7 +44,9 @@ cd lql
44
44
  uv tool install . # or: pip install -e .
45
45
  ```
46
46
 
47
- Update to the latest version with `uv tool upgrade lql-cli` (or `pipx upgrade lql-cli` / `pip install -U lql-cli`).
47
+ Update to the latest version with `lql update --run`, which detects how lql was
48
+ installed (uv tool / pipx / pip) and runs the matching upgrade. Run `lql update`
49
+ (no flag) to just print the command without executing it.
48
50
 
49
51
  ## Authentication
50
52
 
@@ -123,6 +125,50 @@ lql datasets upload <file> --workspace <id> --name <repo-name> [--split <s>]
123
125
 
124
126
  `datasets upload` requires `LQL_HF_TOKEN`.
125
127
 
128
+ ### Preview
129
+
130
+ View dataset samples in the terminal — a Textual TUI with a chat-style layout
131
+ (user turns on the right, system/assistant/tool on the left). It renders the
132
+ same formats as the DataViewer web UI: OpenAI `{role, content}`, structured/
133
+ multimodal content (text/image/audio), ShareGPT `{from, value}`, native OpenAI
134
+ `tool_calls`, plus `<think>` reasoning blocks, `<|tool_call_start|>…<|tool_call_end|>`
135
+ / Python / XML / JSON tool calls, tool results, tool-definition tables, and code.
136
+
137
+ Works on a local `.jsonl`/`.json` file, a platform dataset ID, or — with `--hf`
138
+ — a HuggingFace repo. No browser, and nothing to forward over SSH — it's just
139
+ the terminal.
140
+
141
+ ```
142
+ lql preview <file.jsonl|file.json> Local file: each line/object is a row
143
+ lql preview <dataset-id> Platform dataset (fetched & paged lazily)
144
+ lql preview <org/name> --hf HuggingFace repo: sync to DataViewer, then view
145
+ lql preview <src> -c <field> Force field(s) as conversations (repeatable)
146
+ lql preview <src> -n <N> Page size when paging a platform dataset
147
+ lql preview <src> --offset N Start at row index N
148
+ lql preview <src> --title "<title>" Title shown in the viewer header
149
+ ```
150
+
151
+ **HuggingFace datasets (`--hf`).** `lql preview org/name --hf` syncs the repo
152
+ into a DataViewer workspace, then opens it. You pick the target workspace from
153
+ an interactive list (or pass `--workspace <id>`; `--split` defaults to `train`).
154
+ Already-synced repos are reused — no duplicate, instant re-open.
155
+
156
+ ```
157
+ lql preview tatsu-lab/alpaca --hf
158
+ lql preview org/name --hf --split validation --workspace <id>
159
+ ```
160
+
161
+ **Navigation** — two modes, toggle with `m` / `Tab`:
162
+
163
+ - **pager** (default): one sample at a time · `←/→` or `n`/`b` switch samples · `↑/↓`/`j`/`k`/PgUp-Dn scroll
164
+ - **scroll**: all samples in one buffer · `n`/`b` jump between samples · arrows scroll
165
+ - `q` quits
166
+
167
+ ```
168
+ lql preview examples/agent-traces.jsonl # 20-sample file of agent-trace/tool-use formats
169
+ lql preview <dataset-id> # browse a platform dataset, paged on demand
170
+ ```
171
+
126
172
  ### Evals (dataset analysis)
127
173
 
128
174
  Eval datasets are evaluation-run output — each row a sample with a model
@@ -270,6 +316,13 @@ lql instructions Print the full agent reference
270
316
  flags, examples, and workflows) in one read
271
317
  ```
272
318
 
319
+ ### Update
320
+
321
+ ```
322
+ lql update Detect install method (uv/pipx/pip), print upgrade cmd
323
+ lql update --run Detect and run the upgrade in place
324
+ ```
325
+
273
326
  ## Global flags
274
327
 
275
328
  All commands accept:
@@ -0,0 +1,20 @@
1
+ {"id": "chat-001", "source": "openai-chat", "messages": [{"role": "system", "content": "You are a concise assistant."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "The capital of France is **Paris**."}], "score": 1.0}
2
+ {"id": "bfcl-002", "tool_format": "Python", "messages": [{"role": "system", "content": "You are an expert function-calling assistant. Here is a list of functions in JSON format that you can invoke:\n[{\"name\": \"get_weather\", \"description\": \"Get current weather for a city.\", \"parameters\": {\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\",\"description\":\"City name\"},\"unit\":{\"type\":\"string\",\"description\":\"celsius or fahrenheit\"}},\"required\":[\"city\"]}}]"}, {"role": "user", "content": "What's the weather in Tokyo right now?"}, {"role": "assistant", "content": "<think>\nThe user wants current weather in Tokyo. I'll call get_weather with city=Tokyo.\n</think>\n<|tool_call_start|>[get_weather(city='Tokyo', unit='celsius')]<|tool_call_end|>"}, {"role": "tool", "content": "[{\"name\": \"get_weather\", \"result\": {\"city\": \"Tokyo\", \"temp_c\": 22, \"condition\": \"Partly cloudy\"}}]"}, {"role": "assistant", "content": "It's currently **22\u00b0C** and partly cloudy in Tokyo."}]}
3
+ {"id": "sharegpt-003", "conversations": [{"from": "system", "value": "You are a helpful coding tutor."}, {"from": "human", "value": "How do I reverse a list in Python?"}, {"from": "gpt", "value": "Use slicing: `my_list[::-1]` or `list(reversed(my_list))`."}]}
4
+ {"id": "reason-004", "messages": [{"role": "user", "content": "If a train travels 60 km in 45 minutes, what is its speed in km/h?"}, {"role": "assistant", "content": "<think>\n45 minutes = 0.75 hours. Speed = distance / time = 60 / 0.75 = 80.\n</think>\nThe train's speed is **80 km/h**."}]}
5
+ {"id": "openai-native-005", "messages": [{"role": "user", "content": "Book a table for 2 at 7pm."}, {"role": "assistant", "content": null, "tool_calls": [{"id": "call_1", "type": "function", "function": {"name": "book_table", "arguments": "{\"party_size\": 2, \"time\": \"19:00\"}"}}]}, {"role": "tool", "tool_call_id": "call_1", "name": "book_table", "content": "{\"status\": \"confirmed\", \"reservation_id\": \"R-8842\"}"}, {"role": "assistant", "content": "Done! Your table for 2 at 7:00pm is confirmed (reservation R-8842)."}]}
6
+ {"id": "parallel-006", "messages": [{"role": "user", "content": "Compare the weather in Paris and Berlin."}, {"role": "assistant", "content": "<|tool_call_start|>[get_weather(city='Paris'), get_weather(city='Berlin')]<|tool_call_end|>"}, {"role": "tool", "content": "[{\"name\": \"get_weather\", \"result\": {\"city\": \"Paris\", \"temp_c\": 18}}, {\"name\": \"get_weather\", \"result\": {\"city\": \"Berlin\", \"temp_c\": 15}}]"}, {"role": "assistant", "content": "Paris is 18\u00b0C and Berlin is 15\u00b0C \u2014 Paris is 3 degrees warmer."}]}
7
+ {"id": "toolresult-007", "messages": [{"role": "user", "content": "Search for papers on RLHF."}, {"role": "assistant", "content": "<|tool_call_start|>[search(query='RLHF papers', limit=2)]<|tool_call_end|>"}, {"role": "tool", "content": "[{\"name\": \"search\", \"result\": [{\"title\": \"Deep RL from Human Preferences\", \"year\": 2017}, {\"title\": \"InstructGPT\", \"year\": 2022}]}]"}]}
8
+ {"id": "xml-008", "messages": [{"role": "user", "content": "Convert 100 USD to EUR."}, {"role": "assistant", "content": "Let me convert that.\n<|tool_call_start|><function_call><name>convert_currency</name><arguments><amount>100</amount><from>USD</from><to>EUR</to></arguments></function_call><|tool_call_end|>"}, {"role": "tool", "content": "[{\"name\": \"convert_currency\", \"result\": {\"converted\": 92.4, \"rate\": 0.924}}]"}]}
9
+ {"id": "multimodal-009", "messages": [{"role": "user", "content": [{"type": "text", "text": "What's in this image?"}, {"type": "image_url", "image_url": {"url": "https://example.com/cat.jpg"}}]}, {"role": "assistant", "content": "It appears to be a cat sitting on a windowsill."}]}
10
+ {"id": "agenttrove-010", "agent": "terminus", "model": "gpt-4", "conversations": [{"role": "user", "content": "Solve the task. Respond as JSON with analysis, plan, commands."}, {"role": "assistant", "content": "{\n \"analysis\": \"Need to create a script that checks balanced parentheses.\",\n \"plan\": \"Write a Python script then test it.\",\n \"commands\": [{\"keystrokes\": \"python3 solve.py\\n\", \"duration\": 0.5}]\n}"}]}
11
+ {"id": "code-011", "messages": [{"role": "user", "content": "Write a Python function to compute factorial."}, {"role": "assistant", "content": "Here's a recursive implementation:\n\n```python\ndef factorial(n):\n if n <= 1:\n return 1\n return n * factorial(n - 1)\n```\n\nIt runs in O(n) time."}]}
12
+ {"id": "policy-012", "domain": "telecom", "messages": [{"role": "system", "content": "<instructions>\nYou are a customer service agent. Follow the policy.\n</instructions>\n<policy>\n# Telecom Policy\n- Verify identity before account changes.\n- Never disclose another customer's data.\n</policy>"}, {"role": "user", "content": "I want to change my plan."}, {"role": "assistant", "content": "I can help with that. First, can you verify your account by confirming your phone number?"}]}
13
+ {"id": "memory-013", "domain": "volunteering", "messages": [{"role": "user", "content": "Remember my shift is Saturday 9am-12pm."}, {"role": "assistant", "content": "<think>\nStore the shift schedule in archival memory.\n</think>\n<|tool_call_start|>[archival_memory_add(key='shift', value='Saturday 09:00-12:00')]<|tool_call_end|>"}, {"role": "tool", "content": "[{\"name\": \"archival_memory_add\", \"result\": {\"status\": \"success\", \"total_entries\": 1}}]"}, {"role": "assistant", "content": "Got it \u2014 I've saved your Saturday 9am-12pm shift."}]}
14
+ {"id": "tau2-014", "reward": 1.0, "domain": "telecom", "messages": [{"role": "assistant", "content": "Hi! How can I help you today?"}, {"role": "user", "content": "My mobile data is really slow."}, {"role": "assistant", "content": "<|tool_call_start|>[transfer_to_human_agents(summary='Customer reports slow mobile data.')]<|tool_call_end|>"}, {"role": "tool", "content": "Transfer successful"}, {"role": "assistant", "content": "I've transferred you to a human agent who can troubleshoot your connection."}]}
15
+ {"id": "websearch-015", "num_hops": 2, "messages": [{"role": "system", "content": "You are an expert at composing function calls to answer multi-hop questions."}, {"role": "user", "content": "What language is spoken in the birthplace of the inventor of the telephone?"}, {"role": "assistant", "content": "<think>\nFirst find the inventor of the telephone, then their birthplace, then the language.\n</think>\n<|tool_call_start|>[search_engine_query(keywords='inventor of the telephone birthplace')]<|tool_call_end|>"}, {"role": "tool", "content": "[{\"name\": \"search_engine_query\", \"result\": [{\"url\": \"https://en.wikipedia.org/wiki/Alexander_Graham_Bell\", \"title\": \"Alexander Graham Bell - born Edinburgh, Scotland\"}]}]"}, {"role": "assistant", "content": "Bell was born in Edinburgh, Scotland, where the primary language is **English** (and Scots/Scottish Gaelic)."}]}
16
+ {"id": "extras-016", "messages": [{"role": "user", "content": "Rate this answer.", "turn": 1}, {"role": "assistant", "content": "I'd rate it 4/5.", "weight": 1, "logprob": -0.21}]}
17
+ {"id": "meta-017", "model": "lfm-8b", "temperature": 0.7, "reward": 0.83, "tags": ["coding", "python"], "messages": [{"role": "user", "content": "Hello"}, {"role": "assistant", "content": "Hi there! How can I help?"}]}
18
+ [{"role": "user", "content": "Bare array conversation \u2014 no wrapper object."}, {"role": "assistant", "content": "Yep, this whole row is just a list of messages."}]
19
+ {"id": "tooldefs-019", "messages": [{"role": "system", "content": "You can use these tools:\n[{\"type\": \"function\", \"function\": {\"name\": \"send_email\", \"description\": \"Send an email to a recipient.\", \"parameters\": {\"type\": \"object\", \"properties\": {\"to\": {\"type\": \"string\", \"description\": \"recipient email\"}, \"subject\": {\"type\": \"string\", \"description\": \"email subject\"}, \"body\": {\"type\": \"string\", \"description\": \"email body\"}}, \"required\": [\"to\", \"body\"]}}}]"}, {"role": "user", "content": "Email alice@example.com saying hi."}, {"role": "assistant", "content": "<|tool_call_start|>[send_email(to='alice@example.com', subject='Hi', body='Hello Alice!')]<|tool_call_end|>"}]}
20
+ {"id": "markdown-020", "messages": [{"role": "user", "content": "Summarize the benefits of unit testing."}, {"role": "assistant", "content": "# Benefits of Unit Testing\n\nUnit testing offers several advantages:\n\n- **Catch bugs early** before they reach production\n- **Refactor safely** with a regression safety net\n- **Document behavior** \u2014 tests show how code is meant to be used\n\nUse `pytest` or `unittest` to get started. *Aim for fast, isolated tests.*"}]}
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "lql",
3
+ "lockfileVersion": 3,
4
+ "requires": true,
5
+ "packages": {}
6
+ }
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "lql-cli"
7
- version = "0.2.1"
7
+ version = "0.4.0"
8
8
  description = "lql — CLI for the Liquid DataViewer platform"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -15,6 +15,7 @@ dependencies = [
15
15
  "httpx>=0.27",
16
16
  "rich>=13.0",
17
17
  "huggingface-hub>=0.24",
18
+ "textual>=0.50",
18
19
  ]
19
20
 
20
21
  [project.scripts]
@@ -0,0 +1 @@
1
+ __version__ = "0.4.0"
@@ -15,7 +15,9 @@ from .commands import (
15
15
  highlights,
16
16
  instructions,
17
17
  issues,
18
+ preview,
18
19
  reports,
20
+ update as update_cmd,
19
21
  skills,
20
22
  spec,
21
23
  workspaces,
@@ -63,21 +65,12 @@ app.add_typer(reports.app, name="reports")
63
65
  app.add_typer(buckets.app, name="buckets")
64
66
 
65
67
  # Single commands
68
+ app.command("preview", help="View dataset samples (local file or dataset ID) in the terminal")(preview.preview)
66
69
  app.command("instructions", help="Print a full reference for agents and humans")(instructions.instructions)
70
+ app.command("update", help="Show how to update lql (or upgrade in place with --run)")(update_cmd.update)
67
71
  app.add_typer(skills.app, name="skills")
68
72
 
69
73
 
70
- @app.command("update")
71
- def update() -> None:
72
- """Show how to update lql to the latest version."""
73
- sys.stdout.write(
74
- "To update lql, use the tool you installed it with:\n"
75
- " uv tool upgrade lql # if installed via `uv tool install`\n"
76
- " pipx upgrade lql # if installed via pipx\n"
77
- " pip install --upgrade lql # if installed via pip\n"
78
- )
79
-
80
-
81
74
  def main() -> None:
82
75
  # Mirror the TS top-level catch: unexpected errors surface as the documented
83
76
  # machine-readable contract, not a traceback. Typer/Click exits (SystemExit)
@@ -71,6 +71,33 @@ A workspace is the top-level container for datasets, spec docs, and members.
71
71
  Upload a local file (uploads to HuggingFace liquid-ai org, then syncs):
72
72
  LQL_HF_TOKEN=<token> lql datasets upload <file.parquet> --workspace <id> --name <repo-name>
73
73
 
74
+ ## Preview
75
+
76
+ View dataset samples in the terminal (a Textual TUI) — no browser. Chat-style
77
+ layout (user right, system/assistant/tool left) with the same parsing as the
78
+ DataViewer web UI: OpenAI {role, content}, structured/multimodal content
79
+ ([{type,text}] / image / audio segments), ShareGPT {from, value}, native OpenAI
80
+ tool_calls, plus <think> reasoning blocks, <|tool_call_start|>…<|tool_call_end|>
81
+ / Python / XML / JSON tool calls, tool results, and tool-definition tables.
82
+ Non-conversation fields render as labeled metadata.
83
+
84
+ lql preview <file.jsonl|file.json> # local file: each line/object is a row
85
+ lql preview <dataset-id> # platform dataset, fetched & paged lazily
86
+ lql preview <org/name> --hf # HuggingFace repo: sync to DataViewer, then view
87
+ lql preview data.jsonl -c messages # force field(s) as conversations
88
+
89
+ With --hf, SOURCE is a HuggingFace repo (org/name): it's synced into a
90
+ DataViewer workspace (you pick one interactively, or pass --workspace <id>;
91
+ --split defaults to train) and reused on later previews (dedup by repo+split).
92
+
93
+ Options: -c/--column (field(s) to treat as conversations; default auto-detect,
94
+ repeatable), -n/--limit (page size when paging a platform dataset), --offset
95
+ (start row index), --title, --hf, --split, --workspace, --profile, --api-url.
96
+
97
+ Navigation: two modes toggled with m/Tab — pager (one sample at a time; ←/→ or
98
+ n/b switch samples, ↑/↓/j/k scroll) and scroll (all samples; n/b jump between
99
+ them). q quits. Works over plain SSH with no browser or port-forward.
100
+
74
101
  ## Evals
75
102
 
76
103
  Eval datasets (evaluation-run output: each row a sample with a model 'response'