Skip to content

lerobot

One adapter for every architecture lerobot ships: ACT, Diffusion, SmolVLA, pi0 / pi05, GR00T N1.7, xVLA and the rest. No per-model file in this tree.

python3 -m pip install "strands-robots[sim,lerobot]"
from strands_robots import Robot, make_policy

robot = Robot("aloha", mode="sim")
joints = list(robot.joint_names)
policy = make_policy("lerobot/act_aloha_sim_transfer_cube_human",   # hub id or a local checkpoint dir
                     state_keys=joints, action_keys=joints)          # the checkpoint's 14 state keys -> the arm's joints
robot.preflight(policy)   # refuses INVALID_ACTION naming the camera `top` the checkpoint needs and this observation lacks

The refusal is the contract: a checkpoint runs only when every state key and camera it was trained on is present in observe(). Camera frames in Observation.images are not wired in this build (FINDINGS F25), so PolicyRunner with a vision checkpoint waits on that; the runner itself is exercised in first robot with mock:

import asyncio
from strands_robots import PolicyRunner, Robot, make_policy

robot = Robot("so101", mode="sim")
policy = make_policy("mock", dof=6)
robot.preflight(policy)
report = asyncio.run(PolicyRunner(control_hz=30).run(robot, policy, "wave", max_steps=60))
print(report.stop_reason, report.steps, report.clamped_steps)
robot.close()
fact value
provider lerobot_local
frame read from the checkpoint's meta/stats; refused if absent
model extras a VLM policy needs lerobot's own extra too, e.g. pip install "lerobot[smolvla]"; the refusal names it
inputs state keys and camera names mapped by EmbodimentMap; preflight names a missing key
chunks actions_per_step > 1 engages RTC in the runner
warm handle a checkpoint loads once per process

Training and async inference belong to lerobot: strands_robots.policies.train_spec builds the lerobot-train argv from a TrainSpec, nothing more.