Skip to content

Commit 9c90e44

Browse files
authored
Merge branch 'main' into add/vulture-workflow
2 parents f530e15 + 03e8548 commit 9c90e44

320 files changed

Lines changed: 5823 additions & 174991 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/transformerlab-cli/SKILL.md

Lines changed: 106 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,7 @@ lab status
3838

3939
`login` validates the key and automatically configures `server`, `team_id`, `user_email`, and `team_name`.
4040

41-
**Getting an API key:** API keys are created in the Transformer Lab web UI under team settings, or via the REST API using a JWT token. If the user gives you email/password credentials, get a JWT token first, then use it to create an API key:
42-
43-
```bash
44-
# Get JWT token from email/password
45-
TOKEN=$(curl -s -X POST https://SERVER/auth/jwt/login \
46-
-H "Content-Type: application/x-www-form-urlencoded" \
47-
-d "username=EMAIL&password=PASSWORD" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
48-
49-
# Use the JWT to find team info
50-
curl -s -H "Authorization: Bearer $TOKEN" https://SERVER/users/me/teams
51-
```
52-
53-
Then ask the user to provide or create an API key from the UI.
41+
**Getting an API key:** If `lab status` fails with auth errors, **stop and ask the user to provide an API key.** Do NOT attempt to create API keys programmatically by logging in with email/password. API keys are created in the Transformer Lab web UI under team settings. The user must provide the key to you.
5442

5543
### Verifying You're Connected to the Right Server
5644

@@ -100,15 +88,115 @@ lab job artifacts JOB_ID
10088
lab job download JOB_ID --file "*.csv" -o ./results
10189
```
10290

91+
## Creating Tasks
92+
93+
### task.yaml Structure
94+
95+
Full docs: https://lab.cloud/for-teams/running-a-task/task-yaml-structure
96+
97+
```yaml
98+
name: my-task # Required — task identifier
99+
resources: # Optional but recommended
100+
cpus: 2 # CPU count (integer or string)
101+
memory: 4 # RAM in GB (integer or string, NOT "4Gi")
102+
disk_space: 100 # Storage in GB
103+
accelerators: "H100:8" # GPU spec as "TYPE:COUNT"
104+
num_nodes: 2 # For distributed training
105+
compute_provider: my-provider # Target provider name
106+
setup: | # Optional — runs before main task
107+
pip install transformerlab
108+
pip install -r requirements.txt
109+
run: python main.py # Required — main entry point
110+
envs: # Optional environment variables
111+
HF_TOKEN: "${HF_TOKEN}"
112+
parameters: # Optional — accessible via lab.get_config()
113+
learning_rate: 0.001
114+
batch_size: 32
115+
sweeps: # Optional — hyperparameter sweep
116+
sweep_config:
117+
learning_rate: ["1e-5", "3e-5"]
118+
sweep_metric: "eval/loss"
119+
lower_is_better: true
120+
minutes_requested: 60 # Optional time limit
121+
github_repo_url: https://... # Optional — clone from git
122+
github_repo_dir: path/in/repo
123+
github_repo_branch: main
124+
```
125+
126+
**Important:** `memory` and `disk_space` are plain numbers in GB (e.g., `4`, `16`), NOT Kubernetes-style strings like `4Gi`. The schema accepts both but the canonical format is plain integers.
127+
128+
### Validation
129+
130+
`lab task add` automatically validates task.yaml against the server schema before uploading. There is no standalone `lab task validate` command yet (TODO: add one).
131+
132+
To validate without creating, use `lab task add ./my-task --dry-run`.
133+
134+
### Lab SDK Quick Reference
135+
136+
Tasks use the Lab SDK (`transformerlab` PyPI package). Import pattern:
137+
138+
```python
139+
from lab import lab
140+
141+
lab.init() # Required — connects to the job
142+
lab.log("message") # Write to job output log
143+
lab.update_progress(50) # Set progress 0-100
144+
config = lab.get_config() # Read parameters from task.yaml
145+
146+
lab.finish(message="Done!") # Mark job as SUCCESS
147+
lab.error(message="Something went wrong") # Mark job as FAILED
148+
```
149+
150+
**Common mistakes:**
151+
- `lab.finish()` has NO `status` parameter — just `message`. For failures, use `lab.error()`.
152+
- Always call `lab.init()` before any other SDK call.
153+
- Always call `lab.finish()` or `lab.error()` at the end — otherwise the job stays in RUNNING state.
154+
155+
### Example: Minimal Hello World Task
156+
157+
**task.yaml:**
158+
```yaml
159+
name: hello-world
160+
setup: pip install transformerlab
161+
run: python main.py
162+
resources:
163+
cpus: 2
164+
memory: 4
165+
```
166+
167+
**main.py:**
168+
```python
169+
import time
170+
from lab import lab
171+
172+
lab.init()
173+
lab.log("Hello from Transformer Lab!")
174+
lab.update_progress(25)
175+
time.sleep(3)
176+
lab.log("Working...")
177+
lab.update_progress(75)
178+
time.sleep(2)
179+
lab.log("Done!")
180+
lab.update_progress(100)
181+
lab.finish(message="Hello world complete!")
182+
```
183+
184+
**Add it:**
185+
```bash
186+
lab task add ./hello-world-task --no-interactive
187+
```
188+
103189
## Agent-Specific Rules
104190

105191
1. **Use `--format json`** when you need to parse output, but be prepared to fall back to pretty output parsing if it doesn't work
106192
2. **Use `--no-interactive`** on `task queue` and `provider add` to avoid blocking prompts
107-
3. **`task add` has no `--yes` flag** — pipe `echo "y"` to confirm: `echo "y" | lab task add ./my-task`
108-
4. **Use `--yes` / `-y`** on destructive commands (`provider delete`) to skip confirmation
193+
3. **`task add`**: Use `--no-interactive` to skip confirmation (e.g., `lab task add ./my-task --no-interactive`). Use `--dry-run` to validate without creating.
194+
4. **Use `--no-interactive`** on destructive commands (`task delete`, `provider delete`) to skip confirmation
109195
5. **Never use `job monitor`** — it launches a TUI that blocks; use `job list` + `job logs` instead
110196
6. **Never use `task interactive`** unless the user specifically requests an interactive session
111197
7. **`job logs --follow`** streams continuously and blocks until the job finishes — use when the user wants real-time monitoring
198+
8. **Never create API keys programmatically** — if auth fails, ask the user to provide an API key from the web UI
199+
9. **task.yaml docs**: Full reference at https://lab.cloud/for-teams/running-a-task/task-yaml-structure
112200

113201
## Debugging Failed Jobs
114202

@@ -221,8 +309,8 @@ The `provider_logs` endpoint is the single best debugging tool — it returns wh
221309
| `lab version` | Show CLI version | No |
222310
| `lab task list` | List tasks in current experiment | Yes |
223311
| `lab task info <id>` | Get task details | Yes |
224-
| `lab task add [dir]` | Add task from directory or `--from-git` URL | Yes |
225-
| `lab task delete <id>` | Delete a task | Yes |
312+
| `lab task add [dir]` | Add task from directory or `--from-git` URL (`--no-interactive`, `--dry-run`) | Yes |
313+
| `lab task delete <id>` | Delete a task (`--no-interactive` to skip confirmation) | Yes |
226314
| `lab task queue <id>` | Queue task on compute provider | Yes |
227315
| `lab task gallery` | Browse/import from task gallery | Yes |
228316
| `lab job list` | List jobs (`--running` for active only) | Yes |
@@ -235,7 +323,7 @@ The `provider_logs` endpoint is the single best debugging tool — it returns wh
235323
| `lab provider info <id>` | Show provider details | No |
236324
| `lab provider add` | Add a new provider | No |
237325
| `lab provider update <id>` | Update provider config | No |
238-
| `lab provider delete <id>` | Delete a provider (`--yes` to skip prompt) | No |
326+
| `lab provider delete <id>` | Delete a provider (`--no-interactive` to skip prompt) | No |
239327
| `lab provider check <id>` | Check provider health | No |
240328
| `lab provider enable <id>` | Enable a provider | No |
241329
| `lab provider disable <id>` | Disable a provider | No |

.github/workflows/pytest-cli-live-server.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,4 @@ jobs:
104104
TLAB_LIVE_SERVER_URL: "http://127.0.0.1:8338"
105105
run: |
106106
cd ../cli
107-
uv run pytest tests/integration/test_live_compute_provider_routes.py -v
107+
uv run pytest tests/integration/test_live_cli_routes.py -v

.github/workflows/python-package-cli.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ jobs:
5555
exit 1
5656
fi
5757
58+
- name: Inject Sentry DSN
59+
if: env.SENTRY_DSN != ''
60+
env:
61+
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
62+
run: |
63+
python3 -c "
64+
import sys, pathlib
65+
p = pathlib.Path('src/transformerlab_cli/util/telemetry.py')
66+
p.write_text(p.read_text().replace('__SENTRY_DSN_PLACEHOLDER__', sys.argv[1]))
67+
" "$SENTRY_DSN"
68+
5869
- name: Build release distributions
5970
run: |
6071
python -m pip install build

api/localprovider_pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ dependencies = [
3232
"soundfile==0.13.1",
3333
"tensorboardX==2.6.2.2",
3434
"timm==1.0.15",
35-
"transformerlab==0.1.19",
35+
"transformerlab==0.1.21",
3636
"transformerlab-inference==0.2.52",
3737
"transformers==4.57.1",
3838
"wandb==0.23.1",

api/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ dependencies = [
2424
"python-dotenv==1.1.0",
2525
"python-multipart==0.0.20",
2626
"sqlalchemy[asyncio]==2.0.40",
27-
"transformerlab==0.1.19",
27+
"transformerlab==0.1.21",
2828
"transformerlab-inference==0.2.52",
2929
"uvicorn==0.35.0",
3030
"watchfiles==1.0.5",

api/scripts/increment_plugin_versions.py

Lines changed: 0 additions & 93 deletions
This file was deleted.

api/test/README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
1-
## Testing
1+
# Testing
22

33
So far we have the following PyTests:
44

55
* `db/*` These are tests for the database layer
6-
* `plugins/*` In here is a test to ensure all plugin `index.json` follow the correct plugin schema
76
* `api/*` here are all the tests for the API. Make sure you activate the conda environment before running these tests.
87

9-
### Running the Tests
8+
## Running the Tests
109

1110
Run these from the root of the project.
1211

1312
To run the faster non-API tests:
14-
```
13+
14+
```bash
1515
uv pip install --system pytest pytest-asyncio jsonschema shellcheck-py
16-
pytest test/db/ test/plugins/
16+
pytest test/db/
1717
```
1818

1919
To run the slower API tests:
20-
```
20+
21+
```bash
2122
uv pip install --system pytest pytest-asyncio jsonschema requests shellcheck-py
2223
pytest test/api/
23-
```
24+
```

0 commit comments

Comments
 (0)