diff --git a/.github/workflows/benchmark_tests.yml b/.github/workflows/benchmark_tests.yml
index 79d5614b2..46ad4d5ed 100644
--- a/.github/workflows/benchmark_tests.yml
+++ b/.github/workflows/benchmark_tests.yml
@@ -310,3 +310,101 @@ jobs:
name: metaworld-metrics
path: /tmp/metaworld-artifacts/metrics.json
if-no-files-found: warn
+
+ # ── LIBERO-plus ───────────────────────────────────────────────────────────
+ # Isolated image: lerobot[libero_plus] only (LIBERO-plus from GitHub, mujoco)
+ libero-plus-integration-test:
+ name: LIBERO-plus — build image + 1-episode eval
+ runs-on:
+ group: aws-g6-4xlarge-plus
+ env:
+ HF_USER_TOKEN: ${{ secrets.LEROBOT_HF_USER }}
+
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ persist-credentials: false
+ lfs: true
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3 # zizmor: ignore[unpinned-uses]
+ with:
+ cache-binary: false
+
+ - name: Build LIBERO-plus benchmark image
+ uses: docker/build-push-action@v6 # zizmor: ignore[unpinned-uses]
+ with:
+ context: .
+ file: docker/Dockerfile.benchmark.libero_plus
+ push: false
+ load: true
+ tags: lerobot-benchmark-libero-plus:ci
+ cache-from: type=local,src=/tmp/.buildx-cache-libero-plus
+ cache-to: type=local,dest=/tmp/.buildx-cache-libero-plus,mode=max
+
+ - name: Login to Hugging Face
+ if: env.HF_USER_TOKEN != ''
+ run: |
+ docker run --rm \
+ -e HF_HOME=/tmp/hf \
+ lerobot-benchmark-libero-plus:ci \
+ bash -c "hf auth login --token '$HF_USER_TOKEN' --add-to-git-credential && hf auth whoami"
+
+ - name: Run LIBERO-plus smoke eval (1 episode)
+ run: |
+ docker run --name libero-plus-eval --gpus all \
+ --shm-size=4g \
+ -e HF_HOME=/tmp/hf \
+ -e HF_USER_TOKEN="${HF_USER_TOKEN}" \
+ -e HF_HUB_DOWNLOAD_TIMEOUT=300 \
+ lerobot-benchmark-libero-plus:ci \
+ bash -c "
+ hf auth login --token \"\$HF_USER_TOKEN\" --add-to-git-credential 2>/dev/null || true
+ lerobot-eval \
+ --policy.path=pepijn223/smolvla_libero_plus \
+ --env.type=libero_plus \
+ --env.task=libero_spatial \
+ '--env.task_ids=[0,100,260,500,1000,1500,2000,2400]' \
+ --eval.batch_size=1 \
+ --eval.n_episodes=1 \
+ --eval.use_async_envs=false \
+ --policy.device=cuda \
+ '--env.camera_name_mapping={\"agentview_image\": \"camera1\", \"robot0_eye_in_hand_image\": \"camera2\"}' \
+ --policy.empty_cameras=1 \
+ --output_dir=/tmp/eval-artifacts
+ python scripts/ci/extract_task_descriptions.py \
+ --env libero --task libero_spatial \
+ --output /tmp/eval-artifacts/task_descriptions.json
+ "
+
+ - name: Copy LIBERO-plus artifacts from container
+ if: always()
+ run: |
+ mkdir -p /tmp/libero-plus-artifacts
+ docker cp libero-plus-eval:/tmp/eval-artifacts/. /tmp/libero-plus-artifacts/ 2>/dev/null || true
+ docker rm -f libero-plus-eval || true
+
+ - name: Parse LIBERO-plus eval metrics
+ if: always()
+ run: |
+ python3 scripts/ci/parse_eval_metrics.py \
+ --artifacts-dir /tmp/libero-plus-artifacts \
+ --env libero_plus \
+ --task libero_spatial \
+ --policy pepijn223/smolvla_libero_plus
+
+ - name: Upload LIBERO-plus rollout video
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: libero-plus-rollout-video
+ path: /tmp/libero-plus-artifacts/videos/
+ if-no-files-found: warn
+
+ - name: Upload LIBERO-plus eval metrics
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: libero-plus-metrics
+ path: /tmp/libero-plus-artifacts/metrics.json
+ if-no-files-found: warn
diff --git a/docker/Dockerfile.benchmark.libero_plus b/docker/Dockerfile.benchmark.libero_plus
new file mode 100644
index 000000000..12af9a7bc
--- /dev/null
+++ b/docker/Dockerfile.benchmark.libero_plus
@@ -0,0 +1,119 @@
+# Copyright 2025 The HuggingFace Inc. team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Isolated benchmark image for LIBERO-plus integration tests.
+# Installs only lerobot[libero_plus] (LIBERO-plus from GitHub, dm-control, mujoco).
+#
+# Build: docker build -f docker/Dockerfile.benchmark.libero_plus -t lerobot-benchmark-libero-plus .
+# Run: docker run --gpus all --rm lerobot-benchmark-libero-plus lerobot-eval ...
+
+ARG CUDA_VERSION=12.4.1
+ARG OS_VERSION=22.04
+FROM nvidia/cuda:${CUDA_VERSION}-base-ubuntu${OS_VERSION}
+
+ARG PYTHON_VERSION=3.12
+
+ENV DEBIAN_FRONTEND=noninteractive \
+ MUJOCO_GL=egl \
+ PATH=/lerobot/.venv/bin:$PATH \
+ CUDA_VISIBLE_DEVICES=0 \
+ DEVICE=cuda
+
+# System deps — same set as Dockerfile.internal plus LIBERO-plus extras
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ software-properties-common build-essential git curl \
+ libglib2.0-0 libgl1-mesa-glx libegl1-mesa ffmpeg \
+ libusb-1.0-0-dev speech-dispatcher libgeos-dev portaudio19-dev \
+ cmake pkg-config ninja-build \
+ libexpat1 libfontconfig1-dev libmagickwand-dev \
+ && add-apt-repository -y ppa:deadsnakes/ppa \
+ && apt-get update \
+ && apt-get install -y --no-install-recommends \
+ python${PYTHON_VERSION} \
+ python${PYTHON_VERSION}-venv \
+ python${PYTHON_VERSION}-dev \
+ && curl -LsSf https://astral.sh/uv/0.8.0/install.sh | sh \
+ && mv /root/.local/bin/uv /usr/local/bin/uv \
+ && useradd --create-home --shell /bin/bash user_lerobot \
+ && usermod -aG sudo user_lerobot \
+ && apt-get clean && rm -rf /var/lib/apt/lists/*
+
+WORKDIR /lerobot
+RUN chown -R user_lerobot:user_lerobot /lerobot
+USER user_lerobot
+
+ENV HOME=/home/user_lerobot \
+ HF_HOME=/home/user_lerobot/.cache/huggingface \
+ HF_LEROBOT_HOME=/home/user_lerobot/.cache/huggingface/lerobot \
+ TORCH_HOME=/home/user_lerobot/.cache/torch \
+ TRITON_CACHE_DIR=/home/user_lerobot/.cache/triton
+
+RUN uv venv --python python${PYTHON_VERSION}
+
+# Install only lerobot[libero_plus] — isolated from hf-libero and metaworld dep trees
+COPY --chown=user_lerobot:user_lerobot setup.py pyproject.toml uv.lock README.md MANIFEST.in ./
+COPY --chown=user_lerobot:user_lerobot src/ src/
+
+# Use uv pip install (not uv sync) — uv sync resolves all extras across all
+# Python versions, hitting cross-extra numpy conflicts. pip-style install
+# only resolves the requested extras for the current platform.
+# Install lerobot with libero_plus and smolvla extras.
+# The libero git dep sometimes gets silently skipped by uv pip install
+# when embedded in self-referential extras, so install it explicitly too.
+# Step 1: install lerobot with extras (libero git dep may be silently skipped)
+RUN uv pip install --no-cache -e ".[libero_plus,smolvla]"
+# Step 2: LIBERO-plus has a nested libero/libero/ structure that neither uv pip
+# install from git nor editable installs handle correctly (metadata-only install).
+# Clone and add to PYTHONPATH as the only reliable way to make it importable.
+RUN git clone --depth=1 https://github.com/sylvestf/LIBERO-plus.git /home/user_lerobot/libero-plus \
+ && mkdir -p /home/user_lerobot/.libero \
+ && echo 'assets: /tmp' > /home/user_lerobot/.libero/config.yaml
+# Install LIBERO-plus deps (robosuite, bddl, easydict, mujoco, etc.) from setup.py.
+# Pin robosuite==1.4.1 (fork uses single_arm_env removed in v1.5+), then install
+# the remaining deps from the clone. --no-build-isolation avoids rebuilding lerobot.
+RUN uv pip install --no-cache "robosuite==1.4.1" bddl easydict mujoco matplotlib wand scikit-image gym \
+ && cd /home/user_lerobot/libero-plus && uv pip install --no-cache --no-deps -e "."
+ENV PYTHONPATH="/home/user_lerobot/libero-plus:${PYTHONPATH}"
+
+# Pre-download libero assets so nothing is fetched at runtime (CI timeout risk).
+# libero/libero/__init__.py prompts with input() when ~/.libero/config.yaml is
+# missing; write the config first so any import is non-interactive.
+# LIBERO-plus installs with a nested package structure, so find_spec('libero')
+# may return a namespace package without .origin. Use glob to locate bddl_files.
+ENV LIBERO_PLUS_ROOT=/home/user_lerobot/libero-plus/libero/libero
+# Find hf-libero's init_files in site-packages (shallow clone doesn't have them).
+# Copy them into the PYTHONPATH clone so both bddl_files (from clone) and
+# init_files (from pip) are in the same tree.
+RUN uv pip install --no-cache --no-deps "hf-libero>=0.1.3,<0.2.0"
+RUN HF_LIBERO=$(uv pip show hf-libero 2>/dev/null | grep Location | awk '{print $2}') && \
+ if [ -d "${HF_LIBERO}/libero/libero/init_files" ]; then \
+ cp -r "${HF_LIBERO}/libero/libero/init_files" ${LIBERO_PLUS_ROOT}/init_files; \
+ fi && \
+ # Uninstall hf-libero so that Python imports LIBERO-plus (from PYTHONPATH)
+ # instead of vanilla hf-libero — LIBERO-plus has 2400+ perturbation tasks per
+ # suite, vanilla has only 10.
+ uv pip uninstall hf-libero 2>/dev/null || true
+RUN mkdir -p /home/user_lerobot/.libero && \
+ python${PYTHON_VERSION} -c "\
+from huggingface_hub import snapshot_download; \
+snapshot_download(repo_id='lerobot/libero-assets', repo_type='dataset', \
+ local_dir='/home/user_lerobot/.libero/assets')" && \
+ printf "assets: /home/user_lerobot/.libero/assets\nbddl_files: ${LIBERO_PLUS_ROOT}/bddl_files\ndatasets: ${LIBERO_PLUS_ROOT}/../datasets\ninit_states: ${LIBERO_PLUS_ROOT}/init_files\n" \
+ > /home/user_lerobot/.libero/config.yaml
+
+RUN chmod +x /lerobot/.venv/lib/python${PYTHON_VERSION}/site-packages/triton/backends/nvidia/bin/ptxas
+
+COPY --chown=user_lerobot:user_lerobot . .
+
+CMD ["/bin/bash"]
diff --git a/docs/source/libero_plus.mdx b/docs/source/libero_plus.mdx
new file mode 100644
index 000000000..7873fb251
--- /dev/null
+++ b/docs/source/libero_plus.mdx
@@ -0,0 +1,171 @@
+# LIBERO-plus
+
+LIBERO-plus is a **robustness benchmark** for Vision-Language-Action (VLA) models built on top of [LIBERO](./libero). It systematically stress-tests policies by applying **seven independent perturbation dimensions** to the original LIBERO task set, exposing failure modes that standard benchmarks miss.
+
+- Paper: [LIBERO-plus: A Robustness Benchmark for VLA Models](https://github.com/sylvestf/LIBERO-plus)
+- GitHub: [sylvestf/LIBERO-plus](https://github.com/sylvestf/LIBERO-plus)
+- Dataset: [pepijn223/libero_plus_lerobot](https://huggingface.co/datasets/pepijn223/libero_plus_lerobot)
+
+## Perturbation dimensions
+
+LIBERO-plus creates ~10 000 task variants by perturbing each original LIBERO task along these axes:
+
+| Dimension | What changes |
+| --------------------- | ----------------------------------------------------- |
+| Objects layout | Target position, presence of confounding objects |
+| Camera viewpoints | Camera position, orientation, field-of-view |
+| Robot initial states | Manipulator start pose |
+| Language instructions | LLM-rewritten task description (paraphrase / synonym) |
+| Light conditions | Intensity, direction, color, shadow |
+| Background textures | Scene surface and object appearance |
+| Sensor noise | Photometric distortions and image degradation |
+
+## Available task suites
+
+LIBERO-plus covers the same five suites as LIBERO:
+
+| Suite | CLI name | Tasks | Max steps |
+| -------------- | ---------------- | ----- | --------- |
+| LIBERO-Spatial | `libero_spatial` | 10 | 280 |
+| LIBERO-Object | `libero_object` | 10 | 280 |
+| LIBERO-Goal | `libero_goal` | 10 | 300 |
+| LIBERO-90 | `libero_90` | 90 | 400 |
+| LIBERO-Long | `libero_10` | 10 | 520 |
+
+## Installation
+
+### System dependencies (Linux only)
+
+```bash
+sudo apt install libexpat1 libfontconfig1-dev libmagickwand-dev
+```
+
+### Python package
+
+```bash
+pip install -e ".[libero_plus]"
+```
+
+This installs LIBERO-plus directly from its GitHub repository. Because MuJoCo is required, only Linux is supported.
+
+
+Set the MuJoCo rendering backend before running evaluation:
+
+```bash
+export MUJOCO_GL=egl # headless / HPC / cloud
+```
+
+
+
+### Download LIBERO-plus assets
+
+LIBERO-plus ships its extended asset pack separately. Download `assets.zip` from the [Hugging Face dataset](https://huggingface.co/datasets/Sylvest/LIBERO-plus/tree/main) and extract it into the LIBERO-plus package directory:
+
+```bash
+# After installing the package, find where it was installed:
+python -c "import libero; print(libero.__file__)"
+# Then extract assets.zip into /libero/assets/
+```
+
+## Evaluation
+
+### Minimal smoke-test (1 episode, no async)
+
+```bash
+lerobot-eval \
+ --policy.path=pepijn223/smolvla_libero_plus \
+ --env.type=libero_plus \
+ --env.task=libero_spatial \
+ --eval.batch_size=1 \
+ --eval.n_episodes=1 \
+ --eval.use_async_envs=false \
+ --policy.device=cuda \
+ --env.camera_name_mapping='{"agentview_image": "camera1", "robot0_eye_in_hand_image": "camera2"}' \
+ --policy.empty_cameras=1
+```
+
+### Full robustness benchmark (recommended)
+
+```bash
+lerobot-eval \
+ --policy.path= \
+ --env.type=libero_plus \
+ --env.task=libero_spatial,libero_object,libero_goal,libero_10 \
+ --eval.batch_size=1 \
+ --eval.n_episodes=10 \
+ --env.max_parallel_tasks=1
+```
+
+### Key CLI flags
+
+| Flag | Description |
+| --------------------------- | ---------------------------------------------------------------- |
+| `--env.type=libero_plus` | Selects LIBERO-plus environment (same gym interface as `libero`) |
+| `--env.task` | Suite name(s), comma-separated |
+| `--env.task_ids` | Restrict to specific task indices, e.g. `[0,1,2]` |
+| `--env.camera_name_mapping` | JSON dict remapping raw camera names to policy input keys |
+| `--env.control_mode` | `relative` (default) or `absolute` |
+| `--eval.use_async_envs` | `true` for parallel rollouts (default), `false` for debugging |
+| `--policy.empty_cameras` | Number of camera slots without observations (policy-specific) |
+
+### Camera name mapping
+
+By default, LIBERO cameras are mapped as:
+
+| Raw camera name | LeRobot key |
+| -------------------------- | --------------------------- |
+| `agentview_image` | `observation.images.image` |
+| `robot0_eye_in_hand_image` | `observation.images.image2` |
+
+If your policy was trained with different key names, pass a JSON remapping:
+
+```bash
+--env.camera_name_mapping='{"agentview_image": "camera1", "robot0_eye_in_hand_image": "camera2"}'
+```
+
+## Policy inputs and outputs
+
+**Observations (after `LiberoProcessorStep`):**
+
+- `observation.state` — 8-dim proprioceptive vector: `[eef_pos(3), eef_axis_angle(3), gripper_qpos(2)]`
+- `observation.images.` — camera image(s), flipped 180° to match VLA convention
+
+**Actions:**
+
+- `Box(-1, 1, shape=(7,))` — 6D end-effector delta + 1D gripper
+
+## Dataset
+
+A LeRobot-format training dataset for LIBERO-plus is available at:
+
+- [pepijn223/libero_plus_lerobot](https://huggingface.co/datasets/pepijn223/libero_plus_lerobot)
+
+### Example training command
+
+```bash
+lerobot-train \
+ --policy.type=smolvla \
+ --policy.repo_id=${HF_USER}/smolvla_libero_plus \
+ --policy.load_vlm_weights=true \
+ --dataset.repo_id=pepijn223/libero_plus_lerobot \
+ --env.type=libero_plus \
+ --env.task=libero_spatial \
+ --output_dir=./outputs/ \
+ --steps=100000 \
+ --batch_size=4 \
+ --eval.batch_size=1 \
+ --eval.n_episodes=1 \
+ --eval_freq=1000
+```
+
+## Relationship to LIBERO
+
+LIBERO-plus is a drop-in extension of LIBERO:
+
+- Same Python gym interface (`LiberoEnv`, `LiberoProcessorStep`)
+- Same camera names and observation/action format
+- Same task suite names
+- Installs under the same `libero` Python package name (different GitHub repo)
+- The only code difference in LeRobot is a try/except import fallback in `libero.py` that handles the slightly different package nesting in LIBERO-plus
+
+To use the original LIBERO benchmark, see [LIBERO](./libero) and use `--env.type=libero`.
diff --git a/pyproject.toml b/pyproject.toml
index 2f12840e7..0e9fba586 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -205,6 +205,12 @@ video_benchmark = ["scikit-image>=0.23.2,<0.26.0", "pandas>=2.2.2,<2.4.0"]
aloha = ["lerobot[dataset]", "gym-aloha>=0.1.2,<0.2.0", "lerobot[scipy-dep]"]
pusht = ["lerobot[dataset]", "gym-pusht>=0.1.5,<0.2.0", "pymunk>=6.6.0,<7.0.0"] # TODO: Fix pymunk version in gym-pusht instead
libero = ["lerobot[dataset]", "lerobot[transformers-dep]", "hf-libero>=0.1.3,<0.2.0; sys_platform == 'linux'", "lerobot[scipy-dep]"]
+libero_plus = [
+ "lerobot[dataset]",
+ "lerobot[transformers-dep]",
+ "libero @ git+https://github.com/sylvestf/LIBERO-plus.git@main ; sys_platform == 'linux'",
+ "lerobot[scipy-dep]",
+]
metaworld = ["lerobot[dataset]", "metaworld==3.0.0", "lerobot[scipy-dep]"]
# All
diff --git a/src/lerobot/envs/configs.py b/src/lerobot/envs/configs.py
index 2a7c52d45..1b53a13d5 100644
--- a/src/lerobot/envs/configs.py
+++ b/src/lerobot/envs/configs.py
@@ -574,3 +574,26 @@ class IsaaclabArenaEnv(HubEnvConfig):
),
PolicyProcessorPipeline(steps=[]),
)
+
+
+@EnvConfig.register_subclass("libero_plus")
+@dataclass
+class LiberoPlusEnv(LiberoEnv):
+ """Config for LIBERO-plus robustness benchmark evaluation.
+
+ LIBERO-plus extends LIBERO with 7 perturbation dimensions (camera viewpoints,
+ object layouts, robot initial states, language instructions, lighting, background
+ textures, sensor noise) producing ~10k task variants.
+
+ The gym interface is identical to LIBERO so this class reuses ``LiberoEnv``
+ entirely — only the registered name and default task suite differ.
+
+ Install::
+
+ pip install -e ".[libero_plus]"
+
+ See Also:
+ https://github.com/sylvestf/LIBERO-plus
+ """
+
+ task: str = "libero_spatial"
diff --git a/uv.lock b/uv.lock
index a66f044ff..44b5b42fb 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1,5 +1,5 @@
version = 1
-revision = 2
+revision = 3
requires-python = ">=3.12"
resolution-markers = [
"python_full_version >= '3.14' and platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'",
@@ -829,7 +829,7 @@ name = "cuda-bindings"
version = "12.9.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "cuda-pathfinder", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" },
+ { name = "cuda-pathfinder", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/a9/c1/dabe88f52c3e3760d861401bb994df08f672ec893b8f7592dc91626adcf3/cuda_bindings-12.9.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fda147a344e8eaeca0c6ff113d2851ffca8f7dfc0a6c932374ee5c47caa649c8", size = 12151019, upload-time = "2025-10-21T14:51:43.167Z" },
@@ -916,7 +916,7 @@ name = "decord"
version = "0.6.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "numpy", marker = "(platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l') or sys_platform != 'linux'" },
+ { name = "numpy", marker = "(platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x') or (platform_machine != 's390x' and sys_platform != 'linux')" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/11/79/936af42edf90a7bd4e41a6cac89c913d4b47fa48a26b042d5129a9242ee3/decord-0.6.0-py3-none-manylinux2010_x86_64.whl", hash = "sha256:51997f20be8958e23b7c4061ba45d0efcd86bffd5fe81c695d0befee0d442976", size = 13602299, upload-time = "2021-06-14T21:30:55.486Z" },
@@ -2415,6 +2415,17 @@ libero = [
{ name = "torchcodec", marker = "(platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux') or (platform_machine != 'x86_64' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" },
{ name = "transformers" },
]
+libero-plus = [
+ { name = "av" },
+ { name = "datasets" },
+ { name = "jsonlines" },
+ { name = "libero", marker = "sys_platform == 'linux'" },
+ { name = "pandas" },
+ { name = "pyarrow" },
+ { name = "scipy" },
+ { name = "torchcodec", marker = "(platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux') or (platform_machine != 'x86_64' and sys_platform == 'darwin') or (sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32')" },
+ { name = "transformers" },
+]
matplotlib-dep = [
{ name = "contourpy" },
{ name = "matplotlib" },
@@ -2584,6 +2595,7 @@ requires-dist = [
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'core-scripts'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'dataset-viz'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'libero'" },
+ { name = "lerobot", extras = ["dataset"], marker = "extra == 'libero-plus'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'metaworld'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'pusht'" },
{ name = "lerobot", extras = ["dataset"], marker = "extra == 'training'" },
@@ -2633,6 +2645,7 @@ requires-dist = [
{ name = "lerobot", extras = ["sarm"], marker = "extra == 'all'" },
{ name = "lerobot", extras = ["scipy-dep"], marker = "extra == 'aloha'" },
{ name = "lerobot", extras = ["scipy-dep"], marker = "extra == 'libero'" },
+ { name = "lerobot", extras = ["scipy-dep"], marker = "extra == 'libero-plus'" },
{ name = "lerobot", extras = ["scipy-dep"], marker = "extra == 'metaworld'" },
{ name = "lerobot", extras = ["scipy-dep"], marker = "extra == 'phone'" },
{ name = "lerobot", extras = ["scipy-dep"], marker = "extra == 'pi'" },
@@ -2643,6 +2656,7 @@ requires-dist = [
{ name = "lerobot", extras = ["transformers-dep"], marker = "extra == 'groot'" },
{ name = "lerobot", extras = ["transformers-dep"], marker = "extra == 'hilserl'" },
{ name = "lerobot", extras = ["transformers-dep"], marker = "extra == 'libero'" },
+ { name = "lerobot", extras = ["transformers-dep"], marker = "extra == 'libero-plus'" },
{ name = "lerobot", extras = ["transformers-dep"], marker = "extra == 'multi-task-dit'" },
{ name = "lerobot", extras = ["transformers-dep"], marker = "extra == 'peft'" },
{ name = "lerobot", extras = ["transformers-dep"], marker = "extra == 'pi'" },
@@ -2656,6 +2670,7 @@ requires-dist = [
{ name = "lerobot", extras = ["viz"], marker = "extra == 'dataset-viz'" },
{ name = "lerobot", extras = ["wallx"], marker = "extra == 'all'" },
{ name = "lerobot", extras = ["xvla"], marker = "extra == 'all'" },
+ { name = "libero", marker = "sys_platform == 'linux' and extra == 'libero-plus'", git = "https://github.com/sylvestf/LIBERO-plus.git?rev=main" },
{ name = "matplotlib", marker = "extra == 'matplotlib-dep'", specifier = ">=3.10.3,<4.0.0" },
{ name = "meshcat", marker = "extra == 'unitree-g1'", specifier = ">=0.3.0,<0.4.0" },
{ name = "metaworld", marker = "extra == 'metaworld'", specifier = "==3.0.0" },
@@ -2710,7 +2725,12 @@ requires-dist = [
{ name = "transformers", marker = "extra == 'transformers-dep'", specifier = "==5.3.0" },
{ name = "wandb", marker = "extra == 'training'", specifier = ">=0.24.0,<0.25.0" },
]
-provides-extras = ["dataset", "training", "hardware", "viz", "core-scripts", "evaluation", "dataset-viz", "av-dep", "pygame-dep", "placo-dep", "transformers-dep", "grpcio-dep", "can-dep", "peft-dep", "scipy-dep", "diffusers-dep", "qwen-vl-utils-dep", "matplotlib-dep", "feetech", "dynamixel", "damiao", "robstride", "openarms", "gamepad", "hopejr", "lekiwi", "unitree-g1", "reachy2", "kinematics", "intelrealsense", "phone", "diffusion", "wallx", "pi", "smolvla", "multi-task-dit", "groot", "sarm", "xvla", "hilserl", "async", "peft", "dev", "test", "video-benchmark", "aloha", "pusht", "libero", "metaworld", "all"]
+provides-extras = ["dataset", "training", "hardware", "viz", "core-scripts", "evaluation", "dataset-viz", "av-dep", "pygame-dep", "placo-dep", "transformers-dep", "grpcio-dep", "can-dep", "peft-dep", "scipy-dep", "diffusers-dep", "qwen-vl-utils-dep", "matplotlib-dep", "feetech", "dynamixel", "damiao", "robstride", "openarms", "gamepad", "hopejr", "lekiwi", "unitree-g1", "reachy2", "kinematics", "intelrealsense", "phone", "diffusion", "wallx", "pi", "smolvla", "multi-task-dit", "groot", "sarm", "xvla", "hilserl", "async", "peft", "dev", "test", "video-benchmark", "aloha", "pusht", "libero", "libero-plus", "metaworld", "all"]
+
+[[package]]
+name = "libero"
+version = "0.1.0"
+source = { git = "https://github.com/sylvestf/LIBERO-plus.git?rev=main#4976dc30028e805ff8094b55501d532c48fec182" }
[[package]]
name = "librt"
@@ -3495,7 +3515,7 @@ name = "nvidia-cudnn-cu12"
version = "9.10.2.21"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" },
+ { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" },
@@ -3506,7 +3526,7 @@ name = "nvidia-cufft-cu12"
version = "11.3.3.83"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" },
+ { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" },
@@ -3533,9 +3553,9 @@ name = "nvidia-cusolver-cu12"
version = "11.7.3.90"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" },
- { name = "nvidia-cusparse-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" },
- { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" },
+ { name = "nvidia-cublas-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" },
+ { name = "nvidia-cusparse-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" },
+ { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" },
@@ -3546,7 +3566,7 @@ name = "nvidia-cusparse-cu12"
version = "12.5.8.93"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and sys_platform == 'linux'" },
+ { name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'aarch64' and platform_machine != 'arm64' and platform_machine != 'armv7l' and platform_machine != 's390x' and sys_platform == 'linux'" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" },
@@ -4367,10 +4387,10 @@ name = "pyobjc-framework-applicationservices"
version = "12.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "pyobjc-core", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" },
- { name = "pyobjc-framework-cocoa", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" },
- { name = "pyobjc-framework-coretext", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" },
- { name = "pyobjc-framework-quartz", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" },
+ { name = "pyobjc-core", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" },
+ { name = "pyobjc-framework-cocoa", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" },
+ { name = "pyobjc-framework-coretext", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" },
+ { name = "pyobjc-framework-quartz", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" },
]
sdist = { url = "https://files.pythonhosted.org/packages/be/6a/d4e613c8e926a5744fc47a9e9fea08384a510dc4f27d844f7ad7a2d793bd/pyobjc_framework_applicationservices-12.1.tar.gz", hash = "sha256:c06abb74f119bc27aeb41bf1aef8102c0ae1288aec1ac8665ea186a067a8945b", size = 103247, upload-time = "2025-11-14T10:08:52.18Z" }
wheels = [
@@ -4386,7 +4406,7 @@ name = "pyobjc-framework-cocoa"
version = "12.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "pyobjc-core", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" },
+ { name = "pyobjc-core", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" },
]
sdist = { url = "https://files.pythonhosted.org/packages/02/a3/16ca9a15e77c061a9250afbae2eae26f2e1579eb8ca9462ae2d2c71e1169/pyobjc_framework_cocoa-12.1.tar.gz", hash = "sha256:5556c87db95711b985d5efdaaf01c917ddd41d148b1e52a0c66b1a2e2c5c1640", size = 2772191, upload-time = "2025-11-14T10:13:02.069Z" }
wheels = [
@@ -4402,9 +4422,9 @@ name = "pyobjc-framework-coretext"
version = "12.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "pyobjc-core", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" },
- { name = "pyobjc-framework-cocoa", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" },
- { name = "pyobjc-framework-quartz", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" },
+ { name = "pyobjc-core", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" },
+ { name = "pyobjc-framework-cocoa", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" },
+ { name = "pyobjc-framework-quartz", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" },
]
sdist = { url = "https://files.pythonhosted.org/packages/29/da/682c9c92a39f713bd3c56e7375fa8f1b10ad558ecb075258ab6f1cdd4a6d/pyobjc_framework_coretext-12.1.tar.gz", hash = "sha256:e0adb717738fae395dc645c9e8a10bb5f6a4277e73cba8fa2a57f3b518e71da5", size = 90124, upload-time = "2025-11-14T10:14:38.596Z" }
wheels = [
@@ -4420,8 +4440,8 @@ name = "pyobjc-framework-quartz"
version = "12.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "pyobjc-core", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" },
- { name = "pyobjc-framework-cocoa", marker = "sys_platform != 'emscripten' and sys_platform != 'linux'" },
+ { name = "pyobjc-core", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" },
+ { name = "pyobjc-framework-cocoa", marker = "(platform_machine != 's390x' and sys_platform == 'win32') or (sys_platform != 'emscripten' and sys_platform != 'linux' and sys_platform != 'win32')" },
]
sdist = { url = "https://files.pythonhosted.org/packages/94/18/cc59f3d4355c9456fc945eae7fe8797003c4da99212dd531ad1b0de8a0c6/pyobjc_framework_quartz-12.1.tar.gz", hash = "sha256:27f782f3513ac88ec9b6c82d9767eef95a5cf4175ce88a1e5a65875fee799608", size = 3159099, upload-time = "2025-11-14T10:21:24.31Z" }
wheels = [