Adding a Robot¶
Robots are added through XPolicyLab. The benchmark's own evaluation client keeps the simulator, the observation and the verdict; PyRUA-Lean answers it as a policy, through the adapter that every benchmark XPolicyLab integrates already talks to. RoboDojo is the reference implementation.
How an episode runs¶
- The client sends an observation (
update_obs). On the first one of a trial, the adapter starts a PyRUA-Lean episode: the agent loop, the sandboxed cells and the robotrobo. - A cell calls a primitive; the primitive turns what it was asked into native actions, computed from the observation.
- The client asks for an action (
get_action) and gets the next one. While the model is still thinking, the answer is "wait" and the adapter asks again, so the client's request never times out. - The client steps the simulator and sends the observation that followed, which the primitive reads to report what happened.
- When the episode is over (the task solved, the action budget spent, or the program finished), the client
reports the verdict (
trial_end).
pyrualean.hosts.xpolicylab_bridge turns XPolicyLab's two calls into an environment a primitive can step; it is
the same for every robot.
What a robot needs¶
| Piece | File | RoboDojo |
|---|---|---|
| Robot class: the API the agent writes against, one method per primitive with typed results; its docstrings are the API reference in the prompt | src/pyrualean/<robot>.py |
robodojo.py (RobodojoRobot), specialised by robodojo_xpl_rgb.py |
| Primitives: motion, gripper and perception of this library's own, computed from the observation | src/pyrualean/hosts/<robot>_tools.py and helpers |
robodojo_tools.py, robodojo_kinematics.py, robodojo_sight.py |
| Toolkit: the primitives over an environment that has only an observation and an action, with each step's images and state recorded | src/pyrualean/hosts/<robot>_native.py |
robodojo_native.py |
Host: builds the toolkit over the bridge and writes the task card; for pyrualean play on one machine it also starts the benchmark's client |
src/pyrualean/hosts/xpolicylab_<benchmark>.py |
xpolicylab_robodojo.py, xpolicylab_robodojo_rgb.py |
| Knowledge: one text for every task | src/pyrualean/knowledge/<robot>.md, <robot>-novla.md |
robodojo_xpl_rgb.md, robodojo_xpl_rgb-novla.md |
| Adapter: XPolicyLab's policy directory | integrations/xpolicylab/PyRUA_Lean/ |
the same directory |
Shared, and not changed by a new robot: the bridge, the agent runtimes (Agent Configuration), the cells and their sandbox, and the prompt with its API reference generated from the robot class.
The robot class¶
- Every public method and property is rendered into the API reference from its signature and docstring, so write
them for the model; everything host-facing starts with
_. - Results, not exceptions: what a primitive measured (
reached,found, how wide the gripper is) is a field of a frozen result dataclass.ValueErrorfor bad arguments,ToolErrorwhen a tool fails,EpisodeFinishedonce the episode is over. - A member the benchmark cannot support goes into
ABSENT_MEMBERSinstead of answering with a constant: RoboDojo judges only the final scene, so its robot has nodone. - Only what a program cannot compose from other primitives is a primitive; the knowledge text says how to compose
the rest (on RoboDojo a twist is a
move_towith anotherroll, a button press amove_topast the surface). - Nothing privileged: the primitives read the observation the client sends, and constants of the embodiment and the default scene taken from the benchmark's public configuration.
- The class subclasses
RobotBase(src/pyrualean/_robot.py): it declaresCAMERAS,IMAGE_ARTIFACTS,ON_MOTION_IMAGES,STATEFUL_TOOLS,RESULT_TYPESandVLA_PRIMITIVES, implements_state_from_envelopeand_summary_dict, and sends every primitive through_readonlyor_stateful. - The module ends with its registration,
ADAPTER = RobotAdapter(name=..., robot_cls=..., host=..., knowledge=..., blurb=...), with the XPolicyLab host ashost, and the robot's name goes intoROBOTSinsrc/pyrualean/robots.py:get_adapterrefuses any other name.
The adapter¶
integrations/xpolicylab/PyRUA_Lean/ is one directory for every benchmark, as XPolicyLab keeps one per policy.
| File | Role |
|---|---|
deploy.yml |
The robot, the primitive set, the runtime, the model, the budgets, when the model sees images and what a tool call returns. |
model.py |
XPolicyLab's model: starts one PyRUA-Lean episode per trial on the first observation and serves it through the bridge. It knows RoboDojo today; a new benchmark adds its robot and host here, chosen by bench_name. |
deploy.py |
XPolicyLab's evaluation loop with three changes for a policy that thinks between actions: ask again on "wait", end the episode on an empty answer, and pass the step count and limit with every observation. It reports the verdict back through trial_end. |
eval.sh, setup_eval_policy_server.sh, setup_eval_env_client.sh |
XPolicyLab's entry scripts. |
install.sh, download_assets.sh |
The policy environment and SAM3's checkpoint. |
README.md |
XPolicyLab's policy README: installation, evaluation, configuration and notes. |
The knowledge text¶
knowledge/<robot>.md (and <robot>-novla.md without the VLA primitives) is the same for every task: frames and
units, how each primitive behaves, how to judge progress from the images, and the benchmark's success rules that
an instruction does not spell out (RoboDojo, for most tasks: both arms back at their start pose, the grippers open). No task
recipes.
Checking a new robot¶
- Unit tests against a scripted environment, for every primitive and the API reference (
tests/test_robodojo*.py). - XPolicyLab's debug client, which exercises the loop, the action keys and their dimensions without a simulator
or a model:
EVAL_ENV_TYPE=debug bash eval.sh <bench_name> <task> .... - One episode with
pyrualean play --robot <robot>, which starts the benchmark's client itself (for RoboDojo it needsROBODOJO_SOURCE_ROOTand one environment with both sides). - A few episodes with a model through the benchmark's official entry (RoboDojo:
scripts/robodojo.sh eval), then the full task set.