Skip to main content

OpenRUA

Let Your Claude Code or Codex Control Any Robot, Real or Simulated

Through the standard ROS 2 CLI and client library, without relying on any VLA model.

CI Python ROS 2 License
Stars Forks Watchers

https://github.com/user-attachments/assets/3b134c51-a949-44dd-9474-5249c3879aa0

Codex (GPT-6 Astra) on LIBERO-10, "put the yellow and white mug on the left plate and put the white mug on the right plate": the commands it typed on the left, the robot's cameras on the right, task success. More in docs/demos.md.

OpenRUA connects off-the-shelf coding agents to robots through their native ROS 2 interfaces. The agent works in a workspace containing robot documentation and starter tools, writes perception and control programs, and uses execution feedback to continue the task.

You can chat with the agent through OpenRUA's terminal UI or browser, use its original terminal, or run recorded benchmark experiments. Shared chat lets you send follow-up instructions, inspect tool activity, manage the queue, and revisit saved observations without starting a new robot each turn.

Quick start

Use a Linux host with Docker or supported Podman setup. The terminal UI is included in the default installation. Automatic session IDs and history selection are available from version 0.3.0:

pip install -U 'openrua>=0.3.0'
openrua

Each ordinary launch creates a new session with an automatic ID; no name is required. The TUI guides you through selecting a robot, simulator, optional benchmark, and coding agent. Names support completion; you can also enter paths to your own profiles. Save & check writes your choices to ~/.openrua/config.yaml and shows the preparation still needed. It does not build images or log in automatically. Follow the commands shown by the check and the installation guide, then choose Save & start.

OpenRUA starts the existing session service in the background and opens chat. Type an instruction and press Ctrl+S, for example:

Inspect the workspace documentation and describe the scene without moving the robot.

Ctrl+Q leaves the interface while the session keeps running. Use /resume in the startup form or chat to search previous conversations by title or ID. You can also run openrua --resume, or openrua --gui --resume ID to open a running conversation and its saved workspace images in the browser. To edit defaults later, use openrua --setup, openrua config set, or edit the same config.yaml; changes apply to new sessions, not the one already running.

Choose End session when finished. Records and workspace files are retained; run openrua again for a new session. Ended or unavailable conversations open read-only from history; selecting them never restarts robot execution. The full walkthrough gives a concrete simulated Panda example with image preparation, queue operations, SSH access, and shutdown.

Shared chat remains experimental. Codex has live shared-session checks; successful Claude Code turns through the shared adapter still need validation. See validation scope.

Choose your interface

Interface Entry When you leave
OpenRUA TUI openrua --name chat-demo Ctrl+Q detaches; the shared session continues
Browser openrua --gui --name chat-demo Closing the page leaves the shared session running
Plain CLI openrua --cli --name chat-demo Leaving the client keeps the shared session running
Native agent terminal openrua run panda --sim robosuite --bench capbench --agent codex --name native-demo Exiting the agent stops the resources owned by run

The first three use one shared queue per session. These examples explicitly name a session; omitting --name creates a new one with an automatic ID. To reconnect to a running session, pass only its name and interface choice; startup options cannot change an active conversation. Existing chat and session commands remain available for explicit client operations. Native run starts a separate session using the agent's original TUI; it cannot yet take over that shared conversation. For a native terminal with a robot that stays up between agent visits, use up, agent, and down as described in First task in simulation.

In shared chat, new instructions queue behind the active turn. Interrupting pauses the queue for review; Resume continues it. Ending the session stops its resources while preserving files; deleting them is a separate operation. For development, openrua serve still runs the service in the foreground. Stopping that process ends its session, unlike closing one of its clients.

For an optional keyboard-first Pi terminal, install pip install -U 'openrua[pi]>=0.4.0' and run openrua --tui pi. It provides keyboard configuration, /resume, queue management, and tool expansion on the same shared sessions, with no separate Node install. See the Pi guide for controls and current limits.

How it works

OpenRUA TUI / browser / plain CLI
                |
       shared session service
       queue, events, resource ownership
                |
       native coding agent in a workspace
       ROS 2 docs, starter tools, saved files
                |
         ros2 commands / rclpy programs
                |
       robot's native ROS 2 interfaces
       sensors, trajectories, gripper, velocities

The service coordinates user messages and resources. The coding agent decides when to observe, what programs to write, and how to complete the robot task. Native-terminal and benchmark entry points reuse the robot, workspace, and agent adapters without going through the shared chat queue.

  • The robot provides the control interface. The agent reads machine.yaml and workspace documentation, acquires sensor data, and sends ROS 2 requests.
  • The workspace is the harness. A ROS 2 sandbox contains the agent CLI, documentation, and readable starter-tool source. The agent can inspect, adapt, or replace the tools and save observations and programs for later use.
  • Extensions have their own boundaries. Agent manifests and hooks own agent integration; robot profiles own hardware facts; simulator engines and benchmark loaders own their environments. Frontends use the common session API.
  • Experiments retain their own protocol. openrua bench creates fresh trials, checks workspace interfaces, and records scoring and provenance separately from interactive conversations.

See Architecture for the module boundaries and contracts.

Choosing what to run

  • Robot and scene. --sim selects the simulator; --bench, --task-suite, and --task-id select a benchmark scene. Without a benchmark selection or saved benchmark default, robosuite uses its native Lift scene.
  • Agent and model. Choose --agent and optionally --model when starting the session. Switching them inside a running conversation is not implemented.
  • Defaults. Save common choices with openrua config set; explicit command arguments override them. Configuration documents the fields.
  • Available extensions. openrua robots, openrua simulators, openrua benchmarks, and openrua agents list the bundled and local choices. openrua benchmarks libero_pro lists its suites and tasks.

Supported robots

A robot is what is true of it wherever it runs: joints, limits, frames, gripper, ports, planner. Which simulator embodies it, and what surrounds it, come from the other two kinds of file.

Robot Model Embodied by
panda Franka Emika Panda robosuite, maniskill, calvin, vlabench
panda-omron Panda on an Omron mobile base robosuite through robocasa / robocasa365's assets
widowx Trossen WidowX 250S maniskill (the Bridge dataset's arm, through simpler)
aloha-agilex AgileX Cobot Magic with two ARX X5 arms robotwin
your robot any ROS 2 arm or mobile manipulator, real its own file; see docs/your-own-robot.md

openrua robots prints this list from the files on disk, yours included.

Supported simulators

Simulator Engine Robots Native scene
robosuite robosuite 1.5 on MuJoCo panda Lift: a table and a cube
maniskill ManiSkill 3 on SAPIEN 3 (PhysX, CPU) panda, widowx PickCube-v1: a table, a cube and a goal marker
robotwin RoboTwin 2.0's harness on SAPIEN 3 (PhysX, CPU) aloha-agilex none: name a benchmark
calvin calvin_env on PyBullet (TinyRenderer, CPU) panda none: name the benchmark
vlabench VLABench's dm_control environments on MuJoCo 3.2 panda none: name the benchmark

A simulator file knows the engine and how it drives each robot it embodies; it knows no benchmark. Its install, and the benchmarks' own over it, is what openrua build renders into one image per declaration (openrua-sim-<name>: ROS 2, the checkouts, the assets, the Python environment); docs/simulation.md describes them.

Supported benchmarks

Benchmark Robot Simulator Brings
LIBERO (libero) panda robosuite the four standard suites and LIBERO-90, on LIBERO's robosuite 1.4 fork, ROS 2 Jazzy
LIBERO-PRO (libero_pro) panda robosuite LIBERO's scenes under five perturbation axes, same fork as libero
LIBERO-Plus (libero_plus) panda robosuite ~10,000 perturbed variants of the four suites, its own fork and assets, ROS 2 Jazzy
LIBERO-Mem (libero_mem) panda robosuite ten non-Markovian tasks with subgoal sequences, its own fork, ROS 2 Jazzy
RoboCerebra (robocerebra) panda robosuite long-horizon tabletop cases on its LIBERO fork, the Ideal protocol, ROS 2 Jazzy
CaP-Bench (capbench) panda robosuite CaP-X's tabletop scenes on robosuite 1.5, ROS 2 Humble
RoboCasa (robocasa) panda-omron robosuite the original release's 24 atomic kitchen tasks (v0.2 on robosuite 1.5.0), ROS 2 Humble
RoboCasa365 (robocasa365) panda-omron robosuite the 365-task release's kitchens and the Panda-Omron body, ROS 2 Humble
ManiSkill (maniskill) panda maniskill the eleven table-top Panda tasks that ship with ManiSkill 3, seeded resets, ROS 2 Jazzy
SimplerEnv (simpler) widowx maniskill the four WidowX Bridge tasks as their authors ported them to ManiSkill 3 (the SAPIEN 2 original needs a GPU; its Google Robot tasks are not ported), the visual-matching placement grid, ROS 2 Jazzy
MIKASA-Robo (mikasa) panda maniskill the 90 language-conditioned memory tasks (remember, shell game, intercept, ...), its own image on ManiSkill 3.0.1, ROS 2 Jazzy
RoboTwin 2.0 (robotwin) aloha-agilex robotwin the fifty dual-arm tasks under the Easy protocol (demo_clean); the Hard protocol needs its 11 GB textures and is not declared; ROS 2 Jazzy
CALVIN (calvin) panda calvin the 1000 five-subtask chains of the long-horizon evaluation on play table D, each with its fixed initial condition and the benchmark's task oracle, ROS 2 Humble
VLABench (vlabench) panda vlabench every task registered in the pinned checkout (5 GB of objects and scenes), seeded resets, the task's own termination as success, ROS 2 Humble

A benchmark names its robot and simulator and brings its own world: install: (its image contents and ROS distro) and scenes: (scene cameras, and robot embodiments its assets add). openrua benchmarks prints this list; openrua bench --config <name> runs one.

Supported agents

Agent Status
Claude Code supported (--agent claude-code)
Codex supported (--agent codex)

Bring your own agent. An agent is a manifest (how to install its CLI in the sandbox, which hosts it talks to, how it logs in) and a small hooks class (how to launch it); everything else is optional. Pass yours as a path (--agent ./my-agent.yaml) or send a pull request; openrua agents lists what is available and what each can do. See docs/agents.md.

Results

Detailed results will be released with the paper.

Benchmark Agent Model (reasoning effort) Success
CaP-Bench Claude Code Claude Opus 5 (high) 99.0%
LIBERO-PRO Claude Code Claude Opus 5 (high) 87.0%
LIBERO-10 (LIBERO-PRO) Claude Code Claude Opus 5 (high) 72.5%
LIBERO-10 (LIBERO-PRO) Codex GPT-6 Astra (medium) 62.5%

Use your own robot

Draft a profile from the robot's live graph, finish the TODO lines, and pass it to run:

openrua probe --host > my-ur5.yaml   # joints, limits, frames, ports, cameras from the graph
openrua run ./my-ur5.yaml "..."      # or: openrua config set --robot ./my-ur5.yaml

The profile's machine: section is what the agent's machine.yaml is generated from: model, joint names and limits, frames, gripper, and the ports (trajectory, gripper, twist, wrench) the robot serves. Details in docs/your-own-robot.md.

Simulation and benchmarks

The simulated robots run the community benchmark scenes unchanged; their original success predicates score the trial in place.

openrua bench --config libero_pro --run-id demo \
            --task-suite libero_goal_task --task-ids 0,1 --seeds 0 --operator agent

Every trial writes result.json (verdict, preflight, termination, token accounting), provenance.json (code and simulator commits, image digests, config and prompt hashes), the agent's full transcript, and the workspace it left behind; the run directory keeps a SUMMARY.md regenerated from those files after every trial. Building the simulator checkouts: docs/simulation.md.

A trial replays from its own commands.sh, and a replay with --record renders as a video, terminal on the left, cameras on the right (openrua demo <trial>; see running-experiments.md).

Architecture

The implementation separates robot resources, native agent adapters, shared conversations, and presentation. runner/ composes resources; sessions/ coordinates messages and events; tui/ and web/ provide client interfaces. Robot, sandbox, proxy, and agent knowledge stay in their respective modules. Benchmark execution and recorded demos have separate entry points.

Import-linter and architecture tests enforce these boundaries. See the module map, agent extension guide, and contribution guide.

Documentation

page read when
docs/install.md setting a machine up: images, logins, doctor
examples/first-task.md your first task on the simulated Panda in the original agent terminal
examples/shared-session.md TUI, browser and CLI chat, queue checks, reconnection, saved images and shutdown
docs/terminal.md TUI shortcuts, expandable panels, and current limitations
docs/sessions.md shared-session operations, API, architecture and validation scope
docs/your-own-robot.md describing your robot in one profile
examples/real-robot.md the same flow on a real ROS 2 arm
docs/simulation.md the simulator checkouts and GPU rendering
docs/podman.md machines without Docker
docs/demos.md recorded trials rendered as videos, one per task type
docs/running-experiments.md openrua bench, the runs/ layout, every record field, replays and demo videos
docs/cli.md every verb and flag, exit codes (generated)
docs/config.md every config key (generated)
docs/agents.md adding a coding agent
docs/architecture.md the units and the layering contract
CONTRIBUTING.md conventions for code, names and docs
CHANGELOG.md release changes and upgrade notes

Citation

The paper will be released soon; until then, cite the software:

@software{openrua,
  author  = {{Terminal World Labs}},
  title   = {OpenRUA},
  year    = {2026},
  url     = {https://github.com/terminalworld/OpenRUA},
  license = {Apache-2.0}
}

License

Apache-2.0

Metadata

Release files for openrua 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openrua 0.4.0
File Size Uploaded
openrua-0.4.0.tar.gz 1.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for openrua 0.4.0
File Interpreter ABI Platform
openrua-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 3.1 MB

Release files / openrua-0.4.0.tar.gz

Download URL openrua-0.4.0.tar.gz
Size 1.6 MB
Tags Source
SHA-256 checksum
How to use checksums
2284cbec0167153480610be8233fc1a8bf07429b719baa71be9e055c0b1cb551
BLAKE2b-256 checksum
How to use checksums
4be9be7708717ceee4eeb1e7bef718f89ead3064dd8ed04d51310fe3cb7ee876
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / openrua-0.4.0-py3-none-any.whl

Download URL openrua-0.4.0-py3-none-any.whl
Size 1.5 MB
Tags Python 3
SHA-256 checksum
How to use checksums
b4867963adb378b19d46aa454c0f141617db976db8e2ba454e4050713c4456f2
BLAKE2b-256 checksum
How to use checksums
cc7785a5a67ab3dcb4c28eb888dba00d7831c4b5cb1830195cab153c4d1cea03
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

0.4.1

2 release files

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

0.0.8

2 release files

0.0.7

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page