VLA Embodiment Profile
The robot's contract, written before the robot does anything
- embodiment
- profile_json
- state_dim
- action_dim
Vision-language-action (VLA) models turn an image plus a task into robot actions. Before any of that makes sense, you need to agree on what the robot is: how many joints, what the actions look like, what bounds they're allowed to hit, which cameras exist. That's exactly the job of VLA Embodiment Profile. It creates an explicit state/action/camera contract - a VLA_EMBODIMENT - that every other robotics node in the pack (Observation Builder, the safety gate, the policy clients) uses to stay consistent.
The smart part is that it's template-first. Instead of typing out a 7-dimensional state spec by hand, you pick a preset:
- Generic 7-DoF joint + gripper - the sensible default
- Generic EEF delta + gripper - end-effector movement instead of raw joints
- LeRobot SO-100 / SO-101 template - for the cheap hobby arms everyone actually trains on
- LIBERO Panda simulation template - for the LIBERO benchmark sim
- ALOHA bimanual template - two arms, one contract
A preset gives you sane names, dimensions, and bounds, but the README's framing is worth taking seriously: presets are templates, and you override the bounds with controller-approved limits. The JSON override fields are where that happens - state_names_json, action_names_json, action_min_json, action_max_json, max_delta_json, and camera_names_json all accept small JSON arrays that replace or refine the preset's values. control_hz sets the loop rate (0 = leave it to the preset), and action_mode_override lets you force an action mode.
Outputs: embodiment (the VLA_EMBODIMENT handle you wire into Observation Builder and the safety gate), profile_json (the full contract as text - great for versioning and diffing), state_dim and action_dim (plain INTs so you can see at a glance whether your override broke the dimensions).
Installing it
This node needs nothing beyond the pack itself - no extra pip package, no runtime sidecar. Install via ComfyUI Manager (search "ComfyUI VLM nodes") or:
cd ComfyUI/custom_nodes
git clone https://github.com/gokayfem/ComfyUI_VLM_nodes
python -m pip install -r ComfyUI/custom_nodes/ComfyUI_VLM_nodes/requirements.txt
Only the openpi WebSocket and GR00T ZMQ policy clients need the extra requirements-robotics-client.txt; the profile, observation, and safety nodes run with zero robotics SDKs installed. That's the whole design: ComfyUI holds the contracts, the heavy policy runtimes live in their own LeRobot/openpi/GR00T environment.
Common issues
- Dimension mismatch downstream → if your state array has 7 values but the profile says state_dim 8, every policy call will fail validation. The fix is the
state_names_jsonoverride - name exactly as many entries as you'll actually send. - Safety gate rejects everything → check
action_max_json/max_delta_jsonagainst what the policy actually emits. Over-tight bounds are the most common self-inflicted injury. - "This doesn't match my robot" → presets are starting points, not gospel. Use them to get the shape right, then override the numbers with your controller's real limits. Nobody at the pack can know your arm's torque limits.
A good rule of thumb: this node should be the very first thing in any robotics graph, and its profile_json output deserves to be saved somewhere - when your workflow mysteriously starts failing after a refactor, the profile is the contract you diff against.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| preset | COMBO | Generic 7-DoF joint + gripper | 5 options: Generic 7-DoF joint + gripper, Generic EEF delta + gripper, LeRobot SO-100 / SO-101 template, LIBERO Panda simulation template, ALOHA bimanual template |
| control_hz | FLOAT | 00–10000 | — |
| state_names_json | STRING | — | |
| action_names_json | STRING | — | |
| action_min_json | STRING | — | |
| action_max_json | STRING | — | |
| max_delta_json | STRING | — | |
| camera_names_json | STRING | — | |
| action_mode_override | STRING | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| embodiment | VLA_EMBODIMENT | — |
| profile_json | STRING | — |
| state_dim | INT | — |
| action_dim | INT | — |