Inspect Robots adapters for I2RT YAM bimanual arms driven by MolmoAct2.
Project description
Note: This project is in early development. The API may change between releases, so pin a version before depending on it.
Inspect Robots has two swappable inputs: a Policy (the VLA brain) and an
Embodiment (the robot body + world). This package provides both for the
YAM + MolmoAct2 stack, so any embodiment-agnostic Inspect Robots task (e.g. all of
KitchenBench) runs on real arms:
molmoact2policy: a thin client for MolmoAct2's first-party bimanual-YAM/actserver (the model owns the GPU + weights in its own process).yam_armsembodiment: the I2RT joint-position driver, with a hard safety clamp, operator-in-the-loop success, and self-paced control.
Both declare the same 14-D joint-position contract (2 arms × [6 joints +
gripper], cameras top/left/right, packed joint_pos state), so Inspect Robots's
compatibility check passes with zero errors and zero warnings. This is
verifiable before any motion.
inspect-robots run --task kitchenbench/pour_pasta --policy molmoact2 --embodiment yam_arms
Note: the CLI forwards scalar
key=valueknobs only. It cannot inject acamera_reader, which hardware runs require. Launch from Python (see Run on hardware) or register your own entry-point factory that bundles the cameras; otherwiseyam_armsfails fast with aConfigErroratreset(), before any driver connect or motion.
Install (on the robot/GPU machine)
uv pip install "inspect-robots-yam[client]"
# The i2rt driver is GitHub-only (not on PyPI), so the [yam] hardware extra
# can't resolve from PyPI — install the driver directly instead:
uv pip install "i2rt @ git+https://github.com/i2rt-robotics/i2rt"
client→requests+json-numpy(the/acttransport).i2rt→ the I2RT YAM arm driver, required for real hardware (the[yam]extra declares it, but only resolves in a git/dev install where[tool.uv.sources]applies: from PyPI, install it directly as above).
Then download the model weights (needs a Hugging Face token) and start the server, from the MolmoAct2 repo:
huggingface-cli download allenai/MolmoAct2-BimanualYAM
python examples/yam/host_server_yam.py # serves /act on :8202
Preflight: prove compatibility before any motion
inspect-robots-yam-preflight # dims/semantics/cameras/state
inspect-robots-yam-preflight --task kitchenbench/pour_pasta # + scene realizability
inspect-robots-yam-preflight --dry-run # affirm no motion
A green preflight means action dim (14), control mode (joint_pos), cameras, and
state keys all line up. It does not prove the joint values are interpreted the
same way. See Safety below.
Run on hardware
You must provide a camera_reader (there is no universal camera API) returning
{"top_cam", "left_cam", "right_cam": HxWx3 uint8}. From Python:
from inspect_robots import eval
from inspect_robots.approver import ClampApprover
from inspect_robots_yam import MolmoAct2Policy, YAMEmbodiment, YamConfig
emb = YAMEmbodiment(YamConfig(left_channel="can0", right_channel="can1"),
camera_reader=my_camera_reader)
pol = MolmoAct2Policy(server_url="http://127.0.0.1:8202")
(log,) = eval("kitchenbench/pour_pasta", pol, emb,
approver=ClampApprover(emb.info.action_space)) # defense in depth
print(log.status, log.results.metrics)
At each episode end the embodiment asks the operator (y/N); a yes records
termination_reason="success", which KitchenBench's task_success scorer reads.
The operator prompts need an interactive terminal: a dead stdin raises
EmbodimentFault (the framework's always-halt path). For runs with no operator,
set YamConfig(unattended=True) (CLI: -E unattended=true): all operator
prompts are skipped and every episode runs to max_steps, scoring as a failure.
Safety
- Hard clamp backstop. Every command is clipped to
YamConfig.joint_low/highinsidestep(), independent of any Inspect RobotsApprover: unclamped model outputs can never reach the motors. Set the arm slots to your real YAM joint limits (the defaults are conservative placeholders: joints ±π, gripper 0–1). But note the limits are in policy units per the table below: gripper slots 6 and 13 stay normalized 0–1, only slots 0–5 and 7–12 are radians. - Use
ClampApproveron hardware for a second layer. - Zero-gravity handoff jump. The arms connect in zero-gravity mode by default
(
YamConfig(zero_gravity_mode=True), passed through to the i2rt driver), so the first stiff PD command (homing or the first action) can jump from wherever the arm was idling. Nothing bounds the per-step joint delta yet (tracked as a known issue); stand clear atreset()and prefer ahome_posenear the resting pose. - Absolute vs. delta joints: verify first. MolmoAct2's YAM
actionsare treated as absolute joint targets by default. If your checkpoint emits deltas, setYamConfig(joints_are_delta=True)(the embodiment converts to absolute internally so the declaredjoint_posstays honest). Inspect Robots's compat check cannot tell these apart: confirm with--dry-runand a single slow jog before running a task. - Gripper polarity/trim. The i2rt driver already exposes the YAM gripper as
normalized 0–1 in both directions, so the defaults (
gripper_open=0.0,gripper_closed=1.0) are an identity map and correct for standard grippers.YamConfig(gripper_open=..., gripper_closed=...)is a polarity/trim remap over that already-normalized range. Its main use is a gripper wired with inverted polarity (gripper_open=1.0, gripper_closed=0.0). The remap is a bijection: commands are de-normalized on the way out and observations are re-normalized on the way back, so the model always sees 0–1. Warning: values outside [0, 1] are forwarded on a path i2rt does not clip. Avoid them unless you have verified your firmware's behavior.
Configuration
Units: every 14-D vector uses the same layout
joint_low/joint_high, home_pose, actions, and the observed joint_pos
state all use policy units:
| Slots | Meaning | Unit |
|---|---|---|
| 0–5, 7–12 | left / right arm revolute joints | radians |
| 6, 13 | left / right gripper | normalized 0–1 (0 = open, 1 = closed) |
Hardware gripper units (via gripper_open/gripper_closed) exist only at the
driver boundary; nothing you configure here is in hardware gripper units.
YamConfig: left_channel, right_channel, gripper_type (i2rt GripperType
enum name, e.g. LINEAR_4310; grippers only: NO_GRIPPER/YAM_TEACHING_HANDLE
would break the 14-D packing and are rejected), control_hz, cam_height/width,
joint_low/high, home_pose, gripper_open/closed, joints_are_delta,
zero_gravity_mode (default True; see Safety), unattended (default False;
skip operator prompts).
MolmoActConfig: server_url, endpoint, num_steps, timeout_s,
camera_order, state_key, cam_height/width.
Scalar knobs are settable from the CLI:
inspect-robots run -P server_url=http://gpu:8202 -E left_channel=can0 ....
Development
Dependency changes: after editing dependencies in
pyproject.toml, runuv lockand commit the updated lockfile. CI installs withuv sync --lockedand fails with "the lockfile needs to be updated" if you forget. Day-to-day conventions (PR-onlymain, the requiredci-okcheck, one-click releases) are documented inCLAUDE.md.
uv venv && uv pip install -e ".[dev]" # inspect_robots + kitchenbench from PyPI
uv run pre-commit install
uv run pytest --cov # 100% coverage required
uv run ruff check . && uv run mypy
The whole suite runs with no hardware, no server, and no stdin: the i2rt
driver, cameras, the /act transport, the clock, and operator I/O are all
injected. The default hardware seams are excluded from coverage (# pragma: no cover).
Citation
If you use Inspect Robots YAM in your research, please cite it:
@software{inspect-robots-yam,
author = {Robocurve},
title = {Inspect Robots YAM: Adapters for I2RT YAM bimanual arms},
year = {2026},
url = {https://github.com/robocurve/inspect-robots-yam},
version = {0.3.0},
license = {MIT}
}
License
Project details
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 inspect_robots_yam-0.4.0.tar.gz.
File metadata
- Download URL: inspect_robots_yam-0.4.0.tar.gz
- Upload date:
- Size: 209.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f8c0eab0b4439cc8fcb92c23cebafa0236e1d11bee4a7902e6ee139923f7421
|
|
| MD5 |
c91a96c5f4191d33bb49c697f2394e46
|
|
| BLAKE2b-256 |
7ce9b86c0e369739bf5e68b58da3dc098eb7c9947dd5381d147767e67622946a
|
Provenance
The following attestation bundles were made for inspect_robots_yam-0.4.0.tar.gz:
Publisher:
release.yml on robocurve/inspect-robots-yam
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
inspect_robots_yam-0.4.0.tar.gz -
Subject digest:
2f8c0eab0b4439cc8fcb92c23cebafa0236e1d11bee4a7902e6ee139923f7421 - Sigstore transparency entry: 2134679929
- Sigstore integration time:
-
Permalink:
robocurve/inspect-robots-yam@c859e695681f558dd4932ebf7002782227632b21 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/robocurve
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c859e695681f558dd4932ebf7002782227632b21 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file inspect_robots_yam-0.4.0-py3-none-any.whl.
File metadata
- Download URL: inspect_robots_yam-0.4.0-py3-none-any.whl
- Upload date:
- Size: 23.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8698cb637b4d68debbd9f039dfb15e970c3c4b4feb26cc945c4e9e188fb8a54c
|
|
| MD5 |
c31b32aa109f69c39acc69e9a19da4e7
|
|
| BLAKE2b-256 |
ca415bd937dfe3e5eb5ec5c7efd4b7a373bff6647b4090c7e15ab3555302c516
|
Provenance
The following attestation bundles were made for inspect_robots_yam-0.4.0-py3-none-any.whl:
Publisher:
release.yml on robocurve/inspect-robots-yam
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
inspect_robots_yam-0.4.0-py3-none-any.whl -
Subject digest:
8698cb637b4d68debbd9f039dfb15e970c3c4b4feb26cc945c4e9e188fb8a54c - Sigstore transparency entry: 2134680061
- Sigstore integration time:
-
Permalink:
robocurve/inspect-robots-yam@c859e695681f558dd4932ebf7002782227632b21 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/robocurve
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c859e695681f558dd4932ebf7002782227632b21 -
Trigger Event:
workflow_dispatch
-
Statement type: