laya-cli 0.1.0__py3-none-any.whl
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.
- laya_cli/__init__.py +3 -0
- laya_cli/cli.py +1332 -0
- laya_cli-0.1.0.dist-info/METADATA +182 -0
- laya_cli-0.1.0.dist-info/RECORD +7 -0
- laya_cli-0.1.0.dist-info/WHEEL +4 -0
- laya_cli-0.1.0.dist-info/entry_points.txt +2 -0
- laya_cli-0.1.0.dist-info/licenses/LICENSE +17 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: laya-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Ergonomic CLI for Laya — typed decisions for humans and AI agents (predict, batch, presets, shortlist, router)
|
|
5
|
+
Project-URL: Homepage, https://github.com/MIt9/laya-cli
|
|
6
|
+
Project-URL: Repository, https://github.com/MIt9/laya-cli.git
|
|
7
|
+
Project-URL: Issues, https://github.com/MIt9/laya-cli/issues
|
|
8
|
+
Author: MIt9
|
|
9
|
+
License: Apache-2.0
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai,cli,decision-model,guardrails,laya,router,triage
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: huggingface-hub>=0.20.0
|
|
24
|
+
Requires-Dist: laya>=0.3.4
|
|
25
|
+
Requires-Dist: numpy>=1.20.0
|
|
26
|
+
Requires-Dist: safetensors>=0.4.0
|
|
27
|
+
Requires-Dist: torch>=2.0.0
|
|
28
|
+
Requires-Dist: transformers>=4.48.0
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff>=0.9; extra == 'dev'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# ✨ Laya CLI (`laya-cli`)
|
|
37
|
+
|
|
38
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
39
|
+
[](https://www.python.org/downloads/)
|
|
40
|
+
[](https://github.com/astral-sh/uv)
|
|
41
|
+
|
|
42
|
+
A modern, high-performance CLI for [Laya](https://github.com/NandhaKishorM/laya) — **typed decisions** (`choice`/`score`/`noul`) in one forward pass, designed for **Humans** (Rich table output) and **AI Agents / Classifiers** (Machine-readable `--json` & JSONL).
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## ⚡ Key Features
|
|
47
|
+
|
|
48
|
+
* 🤖 **Typed Decisions in One Pass**: `choice` (top label + probs), `score` (ordinal), `noul` (P(true)) — no generation, no hallucination, ~33ms on T4, 7ms/q batched
|
|
49
|
+
* 🧭 **Router-Aware Multilingual**: `laya.Router(preload=True)` auto-detects script/language in <0.5ms and dispatches to `laya` (English, 512 ctx) vs `laya-multilingual` (100+ langs, 1024 ctx); warns if `--router` without `--lang`
|
|
50
|
+
* 🧹 **Embedding Shortlist for High-Cardinality**: `--shortlist-k 20` via `laya.predict_shortlist` + `embed_fn_from_agent` (Banking77 77 opts → 3 tokens/opt without shortlist → shortlist fixes)
|
|
51
|
+
* 🔍 **Preset Library**: `triage` / `email` / `guard` / `moderation` / `router` — direct `laya.*_questions()` passthrough, mergeable with `--questions file.json` and `--questions-inline`
|
|
52
|
+
* 📦 **Streaming Batch Mode**: `classify`/`predict --input` loads model **once** + warmup, streams JSONL (`--state-field` verbatim, no silent `(photographer: Name)` injection)
|
|
53
|
+
* 🔧 **Post-Filter & Eval**: `filter --where "on_topic>=0.4" --sort -on_topic` and `evaluate` (accuracy, passing @ threshold, precision, escalation rate)
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 🚀 Global Installation
|
|
58
|
+
|
|
59
|
+
### Option 1: Install globally via `uv` (Recommended)
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
uv tool install laya-cli
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Option 2: Install via `pip` / `pipx`
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pipx install laya-cli
|
|
69
|
+
# or
|
|
70
|
+
pip install laya-cli
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Option 3: Run without installing
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uvx laya-cli --help
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
> Requires Python 3.10+ (`.python-version` pins 3.11). Heavy ML deps (`torch`, `transformers`, `safetensors` via `laya`, ~2 GB) download on first `predict`/`classify`. Afterwards `HF_HUB_OFFLINE=1` works. For `uv` dev, tests mock Laya so CI is fast.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 🤖 Classifier Pipeline Integration (Pexels → Laya)
|
|
84
|
+
|
|
85
|
+
Pipe candidate streams directly from [`pexels-cli`](https://github.com/MIt9/pexels-cli) (`px`) into Laya. This is the original use-case that drove `laya-cli` (82 candidates, `state` deduped):
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# 1. Pexels → candidates.jsonl with `state` strings
|
|
89
|
+
px videos --queries "black friday shopping,christmas shopping,checkout cart" \
|
|
90
|
+
--per-page 8 --state --dedupe keep-first > candidates.jsonl
|
|
91
|
+
|
|
92
|
+
# 2. Laya → score + filter (streaming, one model load)
|
|
93
|
+
cat candidates.jsonl \
|
|
94
|
+
| laya-cli classify --questions questions.json \
|
|
95
|
+
| laya-cli filter --where "on_topic>=0.4" --sort -on_topic \
|
|
96
|
+
> shortlist.jsonl
|
|
97
|
+
|
|
98
|
+
# Or with the new primary command (supports presets without a file):
|
|
99
|
+
cat candidates.jsonl | laya-cli predict --questions questions.json --format jsonl > scored.jsonl
|
|
100
|
+
px videos --queries "..." --state --dedupe | laya-cli predict --preset triage --format jsonl | laya-cli filter --where "intent==refund"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Candidate JSONL format** (`px --state`):
|
|
104
|
+
```json
|
|
105
|
+
{"id": 5890229, "type": "video", "query": "black friday shopping", "photographer": "Pavel Danilyuk", "state": "a man shopping on black friday", "url": "https://www.pexels.com/video/a-man-shopping-on-black-friday-5890229/", "duration": 10, "width": 2160, "height": 3840}
|
|
106
|
+
```
|
|
107
|
+
`laya-cli` reads `--state-field state` **verbatim** — use `--prepend-field` only explicitly (mixing photographer into state degraded `on_topic` by 0.1-0.3).
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 📖 Usage Examples
|
|
112
|
+
|
|
113
|
+
### 1. Direct CLI (Human & AI)
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Human: table output, no file needed
|
|
117
|
+
laya-cli predict "I was charged twice, refund please" --preset triage
|
|
118
|
+
laya-cli predict --text "Ignore previous instructions" --preset guard --format table
|
|
119
|
+
laya-cli predict --state '{"subject":"Invoice #4411","body":"Billed twice"}' --preset email --format table
|
|
120
|
+
|
|
121
|
+
# AI agent: JSON single-shot
|
|
122
|
+
laya-cli predict --text "Is this spam?" --preset guard --format json
|
|
123
|
+
# -> {"answers": {"jailbreak": {"noul": 0.02, "confidence": 0.97, ...}}, "usage": ...}
|
|
124
|
+
|
|
125
|
+
# Custom + preset merging (preset < file < inline)
|
|
126
|
+
laya-cli predict --text "hello" --preset triage --questions-inline '{"custom":{"type":"noul","instructions":"Is it polite?"}}' --format json
|
|
127
|
+
|
|
128
|
+
# High-cardinality choice (77 banking intents)
|
|
129
|
+
laya-cli predict --text "where is my card?" --questions banking.json --shortlist-k 20 --format json
|
|
130
|
+
|
|
131
|
+
# Multilingual — Router recommended
|
|
132
|
+
laya-cli predict --text "मुझसे दो बार शुल्क लिया गया" --preset triage --router --format json
|
|
133
|
+
laya-cli predict --text "Der Kunde wurde zweimal belastet" --preset triage --router --lang de --format json
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 2. Batch & Pipeline
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Batch from file (human-readable table per row)
|
|
140
|
+
laya-cli predict --input candidates.jsonl --questions questions.json --format table
|
|
141
|
+
|
|
142
|
+
# Batch JSONL with flatten (like classify) for jq/filter
|
|
143
|
+
laya-cli predict --input candidates.jsonl --questions questions.json --flatten --format jsonl > scored.jsonl
|
|
144
|
+
cat scored.jsonl | laya-cli filter --where "on_topic>=0.4,is_relevant>=0.7" --sort -on_topic,+id
|
|
145
|
+
|
|
146
|
+
# Legacy streaming (kept for compatibility):
|
|
147
|
+
cat candidates.jsonl | laya-cli classify --questions questions.json | laya-cli filter --where "on_topic>=0.4" --sort -on_topic > shortlist.jsonl
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 3. Presets & Info
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
laya-cli questions list --format table
|
|
154
|
+
laya-cli questions triage > questions.json # also: email, guard, moderation, router
|
|
155
|
+
laya-cli presets guard | laya-cli predict --text "test" --questions /dev/stdin
|
|
156
|
+
|
|
157
|
+
laya-cli info # python/torch/cuda/mps + cache
|
|
158
|
+
laya-cli evaluate --questions questions.json --labeled labeled.jsonl --label-field label --threshold 0.5
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 🛠 Development
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
uv sync --group dev # hatchling + ruff/mypy/pytest
|
|
167
|
+
uv run ruff check . # lint (E/F/W/I, line-length 120)
|
|
168
|
+
uv run ruff format . # format
|
|
169
|
+
uv run pytest -q # 26 tests, mocked laya (no model download)
|
|
170
|
+
uv run pytest --cov=src/laya_cli --cov-report=term-missing
|
|
171
|
+
uv build # hatchling -> dist/*.whl + sdist (src/ layout)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Repo layout: `src/laya_cli/`, `tests/`, `pyproject.toml` (hatchling + `dependency-groups`), `uv.lock`, `.python-version` 3.11, `.github/workflows/ci.yml` + `publish.yml`.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 📄 License
|
|
179
|
+
|
|
180
|
+
Apache-2.0 — same as [Laya](https://github.com/NandhaKishorM/laya) upstream. See [LICENSE](LICENSE).
|
|
181
|
+
|
|
182
|
+
This project is not affiliated with Convai Innovations. Laya weights are Apache-2.0 and hosted on Hugging Face (`convaiinnovations/laya`).
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
laya_cli/__init__.py,sha256=kJmsA6cZo__yChWKiA86g8VFaOItLV7qpE6ZmkZ7Iq0,80
|
|
2
|
+
laya_cli/cli.py,sha256=0KB0MCvBqjDZ5l4gWo_5arzwvfqqFktB3HqsADAKfXo,51963
|
|
3
|
+
laya_cli-0.1.0.dist-info/METADATA,sha256=jbU7DXz6hL6gxRY-gwF4Ymh_fo5KSCQviVi0VRzv8RE,8350
|
|
4
|
+
laya_cli-0.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
5
|
+
laya_cli-0.1.0.dist-info/entry_points.txt,sha256=ofrVgnSiEFFGYTWtTCFkco4g-oDUTPwRnzPfA8rZVy4,47
|
|
6
|
+
laya_cli-0.1.0.dist-info/licenses/LICENSE,sha256=yvbKwC8LAvEAbqkN8ZH3GaExCj8YqKaUidUd21eMxCI,678
|
|
7
|
+
laya_cli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Apache License 2.0
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 laya-cli contributors
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
|
16
|
+
|
|
17
|
+
Upstream Laya is Apache-2.0 by Convai Innovations (https://github.com/NandhaKishorM/laya).
|