Skip to content

early review: feat: MuJoCo Simulation Backend + Build System Modernization#80

Closed
cagataycali wants to merge 2 commits into
strands-labs:mainfrom
cagataycali:feat/mujoco-simulation
Closed

early review: feat: MuJoCo Simulation Backend + Build System Modernization#80
cagataycali wants to merge 2 commits into
strands-labs:mainfrom
cagataycali:feat/mujoco-simulation

Conversation

@cagataycali

@cagataycali cagataycali commented Mar 31, 2026

Copy link
Copy Markdown
Member

⚠️ This PR has been decomposed into 6 smaller PRs

This was the original monolithic PR (~4,200 lines). It has been split into a reviewable chain:

Merge Order (sequential — each depends on the previous)

# PR Size What Status
1 #82 XS 🐛 LeRobot state dim fix — standalone bugfix In review
2 #83 S 🔧 Build system — uv lockfile, Python ≥3.12, [sim] extra In review
3 #84 L 📐 Simulation foundation — data models, ABC, factory, model registry, URDF assets In review
4 #85 XL 🎮 MuJoCo backend — Simulation AgentTool with 35 actions, 47 tests In review
5 #86 M 🏭 Robot() factory — auto-detect sim/real, list_robots(), lazy imports In review
6 #87 M 📖 Docs & examples — README rewrite, AGENTS.md update, 8 examples In review

How to review

  1. Start with fix: auto-adapt LeRobot state dimension instead of raising ValueError #82 — it's a standalone bugfix (4 lines changed)
  2. Then chore: modernize build system — uv lockfile, Python >=3.12 #83 — build system changes only, no library code
  3. feat: simulation foundation — models, ABC, factory, model registry, assets #84 and feat: MuJoCo simulation backend - AgentTool with 50+ actions #85 are the core simulation work
  4. feat: Robot() factory + top-level lazy imports #86 and docs: rewrite README, update AGENTS.md, add 8 examples #87 are the user-facing API and docs

Each PR has its own test suite and passes lint independently.

After all 6 are merged

Close this PR — it will be fully superseded.


Original description preserved below for reference.


Original: MuJoCo Simulation Backend + Build System Modernization

Adds MuJoCo-based simulation with 35 agent tool actions, Robot() factory with auto-detect, comprehensive test suite (357 tests), build system modernization, and full documentation rewrite.

cagataycali pushed a commit to cagataycali/robots that referenced this pull request Mar 31, 2026
…trands-labs#56

Distilled @awsarron's recurring review feedback and applied to PR strands-labs#80:

1. Narrow except Exception blocks (13 instances fixed):
   - simulation.py: object/camera injection now raises RuntimeError
     instead of silently falling back to 'metadata only'
   - simulation.py: auto-download failure returns error instead of warning
   - scene_ops.py: narrowed to ValueError/KeyError/RuntimeError
   - mjcf_builder.py: narrowed to FileNotFoundError/OSError
   - rendering.py: narrowed camera render failure + added explanatory comment
   - base.py: narrowed __del__ cleanup to specific types

2. Use require_optional() for MuJoCo lazy import (backend.py):
   - Consistent with package-wide pattern from strands_robots/utils.py
   - Same error messages, same caching behavior

3. Dependency upper bounds (pyproject.toml):
   - robot_descriptions>=1.0.0,<2.0.0 (was missing upper bound)

4. Added REVIEW_TASKS.md tracking all issues from PR review distillation

Conventions enforced per AGENTS.md:
- Raise on fatal errors, never warn-and-continue
- No silent defaults on error
- Use require_optional() for optional deps
@cagataycali
cagataycali force-pushed the feat/mujoco-simulation branch 2 times, most recently from be04ab2 to 298dbfe Compare March 31, 2026 11:41
Add a complete MuJoCo-based simulation backend that enables agent-driven
robot simulation via natural language. 35 simulation actions exposed as a
single AgentTool, supporting physics stepping, rendering, policy inference,
dataset recording, domain randomization, and scene manipulation.

## New Modules

### strands_robots/simulation/
- base.py: SimulationBackend ABC defining the interface all backends implement
- factory.py: create_simulation() dispatch — currently MuJoCo, extensible
- models.py: SimWorld, SimRobot, SimObject, SimCamera, TrajectoryStep dataclasses
- model_registry.py: URDF/MJCF path resolution via robot_descriptions + registry

### strands_robots/simulation/mujoco/
- simulation.py: Simulation(AgentTool) — 35 actions callable by NL agents
- physics.py: PhysicsMixin — step, reset, joint control, contact detection
- rendering.py: RenderingMixin — RGB + depth offscreen rendering
- recording.py: RecordingMixin — start/stop recording → LeRobot v3 datasets
- policy_runner.py: PolicyRunnerMixin — run_policy, eval_policy, replay_episode
- randomization.py: RandomizationMixin — domain randomization (colors, physics)
- scene_ops.py: Inject/eject objects & cameras into live MuJoCo scenes
- mjcf_builder.py: Procedural MJCF XML generation with URDF conversion
- backend.py: Lazy MuJoCo import with GL auto-detection + headless support
- tool_spec.json: AgentTool JSON schema (35 actions)

### strands_robots/
- factory.py: Robot() factory — resolves name → sim or hardware dispatch
- _async_utils.py: Coroutine resolution helpers
- assets/: Robot asset manager with auto-download from MuJoCo Menagerie
- dataset_recorder.py: DatasetRecorder → LeRobot v3 parquet + video format

## Build System
- Migrated from hatch to uv (pyproject.toml + uv.lock)
- .python-version pinned to 3.12
- CI workflow uses uv for install + test + lint
- OSMesa installed in CI for headless MuJoCo rendering

## Testing (34 tests)
- test_factory.py: 22 tests — Robot factory, registry, mode detection, aliases
- test_mujoco_e2e.py: 12 tests — physics, rendering, mock policy loop,
  domain randomization, shared dataclass contracts
- @requires_gl skip marker for tests needing OpenGL context

## Error Handling (review pattern compliance)
- Narrowed 13 broad except-Exception blocks to specific types
  (ValueError, RuntimeError, FileNotFoundError, OSError, KeyError)
- Object/camera injection raises RuntimeError on failure instead of
  silently falling back to metadata-only tracking
- Auto-download failures return explicit error dicts
- Uses require_optional() from strands_robots/utils.py for MuJoCo lazy import
- Dependency upper bounds: robot_descriptions>=1.0.0,<2.0.0

## Headless Rendering
- _can_render() probe in backend.py tests OpenGL once, caches result
- render()/render_depth() return clear error when GL unavailable
- _get_sim_observation() skips cameras gracefully, still returns joint state
- Policy runner silently skips video frames when rendering unavailable
- Physics/stepping/joints work without any GL context
@cagataycali
cagataycali force-pushed the feat/mujoco-simulation branch from 298dbfe to f2a6b52 Compare March 31, 2026 11:42
- Remove test.py (used pre-factory Robot API)
- Add 6 examples covering sim + real factory workflows:
  01_sim_quickstart: 5-line sim quickstart
  02_sim_agent: Agent + Robot tool (NL control)
  03_sim_recording: Mock policy → LeRobot dataset
  04_real_hardware: Real robot with cameras
  05_real_groot_policy: GR00T on real SO-101
  06_list_robots: Registry discovery
@cagataycali cagataycali moved this from Backlog to In review in Strands Labs - Robots Mar 31, 2026
@cagataycali
cagataycali requested a review from awsarron March 31, 2026 23:23
@cagataycali cagataycali changed the title WIP: feat: MuJoCo Simulation Backend + Build System Modernization Review: feat: MuJoCo Simulation Backend + Build System Modernization Mar 31, 2026
@cagataycali cagataycali changed the title Review: feat: MuJoCo Simulation Backend + Build System Modernization early review: feat: MuJoCo Simulation Backend + Build System Modernization Mar 31, 2026
@cagataycali

cagataycali commented Apr 1, 2026

Copy link
Copy Markdown
Member Author

📦 PR Decomposition Complete

This monolithic PR has been split into 6 sequential PRs for easier review:

Merge order

#82 (bugfix, 4 lines) → #83 (build, no lib code) → #84 (sim foundation) → #85 (MuJoCo backend) → #86 (Robot factory) → #87 (docs/examples)
PR Lines Tests Description
#82 +18 / -4 266 ✅ Bug fix: auto-adapt LeRobot state dimensions
#83 +596 / -8 266 ✅ Build: uv lockfile, Python ≥3.12, [sim] extra
#84 +1,060 / -5 288 ✅ (+22 new) Simulation data models, ABC, factory, registry, URDF
#85 +2,268 / -3 335 ✅ (+47 new) MuJoCo Simulation AgentTool — 35 actions
#86 +385 / -7 357 ✅ (+22 new) Robot() factory, list_robots(), lazy imports
#87 +864 / -384 357 ✅ README rewrite, 8 examples, AGENTS.md update

How to proceed

  1. Review and merge fix: auto-adapt LeRobot state dimension instead of raising ValueError #82 first — standalone bugfix, no dependencies
  2. Then chore: modernize build system — uv lockfile, Python >=3.12 #83 — build system only, zero library code changes
  3. feat: simulation foundation — models, ABC, factory, model registry, assets #84feat: MuJoCo simulation backend - AgentTool with 50+ actions #85 are the core simulation — review as a pair
  4. feat: Robot() factory + top-level lazy imports #86docs: rewrite README, update AGENTS.md, add 8 examples #87 are user-facing API + docs
  5. After all 6 merge, close this PR

All PRs are on the project board with Status=In review, Priority=P1.

cc @awsarron

@max-rattray-aws

Copy link
Copy Markdown
Contributor

No concerns from me

@github-project-automation github-project-automation Bot moved this from In review to Done in Strands Labs - Robots Apr 2, 2026
@cagataycali cagataycali moved this from Done to In review in Strands Labs - Robots Apr 3, 2026
@cagataycali cagataycali closed this Apr 5, 2026
@github-project-automation github-project-automation Bot moved this from In review to Done in Strands Labs - Robots Apr 5, 2026
@cagataycali

Copy link
Copy Markdown
Member Author

Closing — superseded by the decomposed PR stack: #83 (build system) → #84 (sim foundation) → #85 (MuJoCo backend). This monolithic PR was split for smaller, reviewable chunks.


🤖 AI agent response. Strands Agents. Feedback welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants