LeAgents — agentic orchestration for the LeRobot pipeline: collect -> train -> eval -> improve
Project description
LeAgents
Agentic orchestration for the LeRobot robotics pipeline — an orchestrator drives an automated collect → train → eval → improve loop over LeRobotDataset v3.0, with a deterministic loop controller, a constitution safety gate, verification gates before promotion, and (M2) a dashboard for visualizing the flow.
Architecture, research grounding (verified 2023–2026 papers), and roadmap: DESIGN.md.
Status — v0.0.5
| Milestone | Scope | Status |
|---|---|---|
| M0 | Sim-only loop on LIBERO: seed dataset → SmolVLA fine-tune → lerobot-eval gate → promote/iterate/escalate/rollback |
✅ done — a successful autonomous run climbed 63% → 69% → 72% on LIBERO spatial (see below); PushT/LIBERO smoke configs included |
| M1 | DexFlyWheel-style self-improvement, RoboGene-style task curation, policy escalation, OKF knowledge layer (Karpathy-wiki-style, DESIGN.md §3.6) + provider-agnostic LLM proposer | 🚧 knowledge layer + LLM adapter landed; success-filtered rollout harvest → accumulating mix validated end-to-end in a real run |
| M2 | Flow dashboard (Rerun episode replay, WandB curves, OTel agent traces) | 🚧 flow view v1 landed: runs → cycles → decisions live, eval chart, event log, knowledge browser (leagents dash) |
| M3 | Real robot: teleop collection, HIL-SERL adapter (requires lerobot ≥ 0.6.0, see CVE note in DESIGN.md §6) | planned |
What works today: the full loop state machine with budgets, the constitution gate, SQLite job store, JSONL event log, subprocess wrappers for lerobot-train / lerobot-eval, the OKF knowledge layer (knowledge/ pages with provenance, updated every cycle, linted), the DexFlyWheel data path (success-filtered rollout harvesting → accumulated mix → adaptation training), and a provider-agnostic LLM adapter (llm: gemini:*|anthropic:*|openai:*[@base_url], or none at all — every flow has a deterministic fallback). All covered by tests that run without a GPU or lerobot installed.
A successful autonomous run — the data-growth flywheel (2026-07-05)
Once the data bug below was fixed, one M0 run on a single RTX 5070 Ti (16 GB) climbed monotonically on LIBERO spatial (100 eval episodes/cycle), fully autonomous, 5.9 GPU-hours, one run command:
| Cycle | Data | LIBERO spatial success | Decision |
|---|---|---|---|
| 0 | 200 episodes (20/task) | 63% | promote (baseline) |
| 1 | 320 | 69% | promote — the hardest task (bowl-on-cookie-box) rose most, 20% → 50% |
| 2 | 500 (~50/task) | 72% | iterate — +3% is real but below promote_delta; the 69% checkpoint stays blessed |
More data lifted the number, with the expected diminishing return (+6, then +3). Each promotion also harvested success-filtered rollouts from the freshly-blessed policy and merged them into a growing "self-play" mix (20 → 40 episodes) — the DexFlyWheel data path, running end-to-end without a human in the loop. (Adaptation training on that mix is held back after an over-adaptation regression — see the note in configs/m0_libero_scale.yaml — so this run measures the pure data-growth signal.)
The decision function did its job in both directions: it promoted the genuine gains and, in an earlier run where an aggressive adaptation stage overfit and dropped success to 20%, it rolled back and protected the 63% baseline rather than accepting the regression.
The failure that came first (2026-07-04)
Before any of that worked, three whole runs sat at a flat 0%, and the metrics could not tell us why. One M0 run on the same GPU — 3 cycles, 6.1 GPU-hours, zero human intervention, every decision/event/knowledge-page update logged:
| Cycle | Data | Train | LIBERO spatial eval (100 episodes) | Decision |
|---|---|---|---|---|
| 0 | 40 episodes | 20k steps from smolvla_base (loss → 0.030) |
0% success — arm reaches targets, never completes | promote (baseline) |
| 1 | 80 | 20k steps, continued from the blessed checkpoint | 0% | iterate |
| 2 | 160 | 20k steps | 0% | iterate — the escalate_floor guard correctly refused to escalate a 0%-plateau to a bigger policy |
This run validated the loop — budgets held, weights carried over, and the decision function behaved exactly as specified.
Root-cause correction (same day): the flat 0% was first attributed to the data budget (4→16 episodes per task vs. the verified ~50). Digging into a follow-up run that stayed at 0% with 20 per task exposed the real cause: HuggingFaceVLA/libero is suite-ordered, and the [0..N) episode prefix belongs to other suites (libero_spatial episodes live around indices 1261–1538) — every run had trained on tasks disjoint from the eval. In the metrics this silent failure was indistinguishable from under-training. Fix: episode selection is now task-filtered against the eval suite (leagents.scripts.select_episodes, data.task_filter), balanced per task, and the Data Agent fails loudly if the selection doesn't cover the suite. The table above stands as a record of the failure mode.
Quickstart
— one autonomous cycle (PushT) on a free GPU, ~5 minutes, nothing to install locally.
pip install -e ".[dev]"
pytest
# instant demo — installs a bundled real 3-cycle run (events, decisions,
# eval videos, knowledge pages) so the dashboard is never empty. No GPU.
leagents demo
# dry run — no GPU, no lerobot; synthetic eval scores exercise the decision logic
leagents run -c configs/m0_libero.yaml --dry-run
# real run (Linux; needs a GPU and the LIBERO extras)
pip install -e ".[lerobot]"
leagents run -c configs/m0_libero.yaml
# inspect runs, cycles, decisions, blessed checkpoints
leagents status
# flow dashboard — runs, cycle pipeline, decisions, eval chart, events, knowledge
pip install -e ".[dash]"
leagents dash # → http://127.0.0.1:8321
No root, no Docker? Use pixi
On shared servers the only step that needs sudo is LIBERO's egl-probe build (system EGL headers). pixi supplies Python, the EGL/OpenGL headers, a C++ toolchain, and CMake 3.x from conda-forge instead — zero root required:
pixi run test # loop tests, no GPU needed
pixi -e lerobot run doctor # full environment checks (GPU/EGL/LIBERO)
pixi -e lerobot run smoke-pusht
Docker
The image bakes in everything that takes debugging natively — EGL headers for LIBERO's egl-probe build, CMake < 4, libero's one-time init, headless sim env vars. GPU access needs nvidia-container-toolkit; secrets come from .env at runtime, never the image:
docker compose up dash # flow dashboard → http://localhost:8321
docker compose up loop # the autonomous cycle (GPU)
How the loop decides
Each cycle trains a candidate checkpoint and evaluates it on LIBERO. The decision is a pure function of success-rate deltas vs. the blessed baseline (leagents/orchestrator/decision.py):
- promote — candidate beats baseline by ≥
promote_delta; it becomes the new blessed checkpoint - iterate — small improvement; collect more data on failing task variations
- escalate — plateaued for
plateau_cycles; move up the policy ladder (SmolVLA → π0.5) - rollback — regression; the blessed checkpoint stands
Control flow is deterministic Python persisted to SQLite — LLM agents (task proposal, curation; M1) only make proposals inside the gates, never control-flow decisions.
Layout
leagents/
├── orchestrator/ # loop controller, decision logic, constitution gate, proposer
├── agents/ # data / train / eval / improve agents (LeRobot CLI wrappers)
├── contracts/ # typed records: DatasetRef, CheckpointRecord, EvalReport
├── events/ # JSONL event bus (dashboard reads this in M2)
└── store/ # SQLite job store (runs, cycles, checkpoints)
configs/ # m0_libero.yaml, constitution.yaml
tests/ # loop e2e with fake runners — no GPU needed
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file leagents-0.0.5.tar.gz.
File metadata
- Download URL: leagents-0.0.5.tar.gz
- Upload date:
- Size: 461.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
22076a72824fbd9fda59921bcef52259aa63847685c03428c8e672969a59b905
|
|
| MD5 |
b3d48b2844b14944504da8990499e7d4
|
|
| BLAKE2b-256 |
fda1b945b8cd5a0b69d496ddec2d129336583ee1bcf8b63d652b681997bb402a
|
File details
Details for the file leagents-0.0.5-py3-none-any.whl.
File metadata
- Download URL: leagents-0.0.5-py3-none-any.whl
- Upload date:
- Size: 457.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b3196e29574d0772bad7b4818c2582028c644b33a767e24bab6caf44d5493e4
|
|
| MD5 |
cd599860dc6755549cf70619e3786f69
|
|
| BLAKE2b-256 |
617845bb0357bb5745a893ea633570a0768d3c5dd29a4d836e3143467434595c
|