Skip to content

Enable SimReady search API in agentic env gen - #982

Merged
xyao-nv merged 31 commits into
mainfrom
xyao/feature/sim_ready_search
Aug 3, 2026
Merged

Enable SimReady search API in agentic env gen #982
xyao-nv merged 31 commits into
mainfrom
xyao/feature/sim_ready_search

Conversation

@xyao-nv

@xyao-nv xyao-nv commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

Enable SimReady search API in agentic env gen

Detailed description

  • Remove NormalizeSpec from Add SimReady search to agentic environment generation. #964. Instead it sticks to SpecInference. And objects the catalog cannot cover now carry thesimready_usd_object` registry name and are searched in the SimReady library after spec inference
  • Matching is on whole words, and the phrase's last word — the object itself — must appear in the asset path. To avoid substring matching, e.g. "bin" turns into cabinet USD.
  • Each candidate is read before it is accepted, and only assets with exactly one rigid body are kept; multi-part props are turned down with the reason recorded in the traces.
  • When nothing usable is found, the object ids are named back to the model for one further inference pass; an id already searched for is not searched again. If the replacement still cannot be spawned, the runner names the unavailable objects and shows the traces to users.
  • Opt-in, off by default: --enable_simready_search on the environment generation runner, or the "SimReady search" expander in the review GUI.

simready_droid_pick_place_cans_hammer_maple_table.yaml
image
Screenshot from 2026-07-30 22-36-30
Screenshot from 2026-07-30 22-34-57

Other examples
image
image

When Simready ones are not valid, fall back to the closest from Simready / Arena registry.

[runner] generation traces:
  simready search found no usable asset for 'pancake'
  no SimReady asset for object 'pancake'; it cannot be spawned
  asking for a replacement of: pancake

=== ArenaEnvGraphSpec (env_name='droid_pick_bagel_into_grey_bin') ===

assets:
  droid                    role=embodiment         registry_name=droid_abs_joint_pos
  maple_table              role=background         registry_name=maple_table_robolab
  bagel                    role=object             registry_name=bagel_00_objaverse_robolab
  grey_bin                 role=object             registry_name=grey_bin_robolab

[runner] generation traces:
  simready search found no usable asset for 'disinfectant spray'
  no SimReady asset for object 'disinfectant_spray'; it cannot be spawned
  asking for a replacement of: disinfectant_spray

=== ArenaEnvGraphSpec (env_name='droid_pick_soft_scrub_into_grey_bin') ===

assets:
  droid                    role=embodiment         registry_name=droid_abs_joint_pos
  maple_table              role=background         registry_name=maple_table_robolab
  soft_scrub               role=object             registry_name=soft_scrub_ycb_robolab
  grey_bin                 role=object             registry_name=grey_bin_robolab

relations:
  is_anchor        subject=maple_table
  on               subject=soft_scrub  reference=maple_table
  on               subject=grey_bin  reference=maple_table

task: composition=TaskCompositionType.ATOMIC
  description: Pick up a soft scrub cleaner from the maple table and place it into a grey bin on the table.
  [0] kind=PickAndPlaceTask

@xyao-nv
xyao-nv marked this pull request as ready for review July 31, 2026 05:01
@greptile-apps

greptile-apps Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds opt-in SimReady asset discovery to agentic environment generation.

  • Searches and ranks whole-word asset matches, rejecting assets that do not contain exactly one rigid body.
  • Adds fallback inference for unavailable objects and reports generation traces in the CLI and review GUI.
  • Registers a dynamic SimReady USD object with Physics variant-aware type and contact-sensor handling.
  • Adds the optional search dependency and coverage for search, generation, USD helpers, asset construction, and GUI behavior.

Confidence Score: 4/5

The packaging incompatibility must be fixed before merging because no supported runtime can currently use the advertised SimReady search feature.

Native uv rejects the new extra alongside either IsaacLab group due to the declared dependency conflicts, and the Docker image does not install the extra, so enabled searches return no candidates in every supported installation path.

Files Needing Attention: pyproject.toml and docker/Dockerfile.isaaclab_arena

Important Files Changed

Filename Overview
isaaclab_arena/agentic_environment_generation/environment_generation_agent.py Orchestrates SimReady resolution and one replacement-inference pass for assets that cannot be found.
isaaclab_arena/agentic_environment_generation/simready_asset_search.py Implements backend configuration, whole-word ranking, rigid-body validation, and synchronous search integration.
isaaclab_arena/assets/simready_object_library.py Registers a dynamic USD-backed object and applies the SimReady Physics variant during construction.
isaaclab_arena/utils/usd/rigid_bodies.py Adds variant-aware rigid-body inspection and caching for local or remote USD assets.
isaaclab_arena_examples/agentic_environment_generation/review_gui/generation_panel.py Adds SimReady configuration controls, configuration-sensitive agent caching, and explicit warning feedback.
pyproject.toml Adds the SimReady dependency but leaves it incompatible with both supported native simulator groups and absent from Docker.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[User prompt] --> B[Spec inference]
  B --> C{Catalog asset?}
  C -->|Yes| D[Validated Arena asset]
  C -->|No| E[SimReady search]
  E --> F{One rigid body?}
  F -->|Yes| G[Attach USD path and Physics variant]
  F -->|No| H[Name unavailable object]
  H --> I[One replacement inference pass]
  I --> B
  D --> J[Generated environment spec]
  G --> J
Loading

Reviews (1): Last reviewed commit: "fix test and uv test" | Re-trigger Greptile

Comment thread pyproject.toml Outdated
Comment thread isaaclab_arena/agentic_environment_generation/simready_asset_search.py Outdated
@arena-review-bot

Copy link
Copy Markdown
Contributor

🤖 Isaac Lab-Arena Review Bot

Summary

This PR adds an opt-in SimReady asset search to agentic environment generation: objects the Arena catalog can't cover are left to SimReady, searched by phrase after spec inference, filtered to whole-word matches on the object noun, and accepted only if the USD holds exactly one rigid body. It's cleanly off-by-default (CLI flag + GUI expander), keeps SimReady names/URLs out of the asset classes to avoid a pre-sim pxr import, and is well tested. Boundaries and placement look sound; my only notes are about a redundant config flag and a loose return type.

Findings

🟡 simready_asset_search.py:44SimReadySearchConfig.enabled is set in three places (constructor default, simready_search_config_from_cli, and forced via replace(..., enabled=True)) but never read. The search never checks it and the agent gates on its own enable_simready_search, so two flags encode one decision and can silently diverge. Suggest dropping the field and keeping the agent flag as the single gate.

🔵 generation_panel.py:61_simready_config_from_session returns tuple[bool, object]; callers then reach into .source, .s3_url, etc. with no type-checker help. Return tuple[bool, SimReadySearchConfig] instead.

Test Coverage

Strong. New unit tests cover word-splitting/ranking, rigid-body rejection, the search fall-through, the retry/unavailable-object flow in the agent, the registered SimReadyUsdObject, the variant-aware rigid-body helpers, and the GUI severity path. The pure-USD tests build local tmp_path stages and defer pxr into the test bodies, consistent with keeping module import safe before sim init.

Verdict

Ship it (minor cleanups optional).

@qianl-nv qianl-nv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for jumping on this!

have one large size comment about how the inference calls are structured. happy to discuss in more detail.

did a quick pass on the rest. will do a more detailed review after we resolve the large refactor comment.

Comment thread isaaclab_arena/agentic_environment_generation/environment_generation_agent.py Outdated
Comment thread isaaclab_arena/agentic_environment_generation/simready_asset_search.py Outdated
Comment thread isaaclab_arena/agentic_environment_generation/simready_asset_search.py Outdated
Comment thread isaaclab_arena/assets/simready_constants.py Outdated
Comment thread isaaclab_arena/agentic_environment_generation/spec_inference.py Outdated
Comment thread isaaclab_arena/agentic_environment_generation/spec_inference.py
Comment thread isaaclab_arena/assets/simready_object_library.py Outdated
Comment thread isaaclab_arena/utils/usd/rigid_bodies.py

@qianl-nv qianl-nv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for restructuring it! Add some nits. In particular, suggests clean up the EnvironmentGenerationAgent.traces usage hygiene to separate error vs info logs into separate dict entry/list under trances, then can clean up some of the ac-hoc logic in UI for trace display.

Approved, feel free to merge after address the comments.

Comment thread isaaclab_arena/agentic_environment_generation/environment_generation_agent.py Outdated
Comment thread isaaclab_arena/agentic_environment_generation/environment_generation_agent.py Outdated
Comment thread isaaclab_arena/agentic_environment_generation/environment_generation_agent.py Outdated
Comment thread isaaclab_arena/agentic_environment_generation/environment_generation_agent.py Outdated
Comment thread isaaclab_arena/agentic_environment_generation/simready_asset_search.py Outdated
Comment thread isaaclab_arena/agentic_environment_generation/simready_asset_search.py Outdated
Comment thread isaaclab_arena/agentic_environment_generation/simready_asset_search.py Outdated
Comment thread isaaclab_arena/tests/test_missing_object_inference.py
Comment thread isaaclab_arena/utils/usd/rigid_bodies.py Outdated
Comment thread isaaclab_arena/utils/usd/rigid_bodies.py
xyao-nv added a commit that referenced this pull request Aug 3, 2026
## Summary
Add the simready-search dependency, to unblock
#982 testing.

## Detailed description
- Override boto3, botocore, requests and s3transfer to the versions
isaacsim-kernel pins. simready-search asks for boto3==1.42.58,
requests>=2.32.5 and s3transfer 0.16.x, all over-strict; without the
overrides it does not resolve alongside either sim-stack flavor.

---------

Signed-off-by: Xinjie Yao <xyao@nvidia.com>
@xyao-nv
xyao-nv force-pushed the xyao/feature/sim_ready_search branch from 57ed713 to fe4179c Compare August 3, 2026 05:43
xyao-nv and others added 5 commits August 3, 2026 09:23
…parts

SimReady props give each part its own rigid body and hold the parts
together with fixed joints, so a spray bottle reports two bodies. Isaac
Lab expects one rigid body per rigid object and refuses to spawn them.

- Add get_physics_structure() to group rigid bodies by fixed joints.
- Use it in detect_object_type() so held-together bodies are RIGID and
  anything that can still move is ARTICULATION.
- Add weld_usd_rigid_bodies() to write a cached asset that puts the
  rigid body on a parent prim and switches off the redundant joints.
- Add apply_usd_variant_selections(), needed because SimReady props have
  no physics until the Physics variant is selected.

Signed-off-by: Xinjie Yao <xyao@nvidia.com>
The parts of a SimReady prop state their mass twice, once on the part and again on
each of its collision shapes, and the two do not always agree. Merging the parts
made PhysX read the shape figures instead of the part figures, which moved the
disinfectant bottle's centre of mass from 0.052 m to 0.082 m.

Add up the part figures during the merge and write them on the merged body, so the
prop keeps the mass, centre of mass, and inertia it had before.

Signed-off-by: Xinjie Yao <xyao@nvidia.com>
Normalize prompts before spec inference, optionally query Isaac Sim GA
SimReady props, and emit simready_usd_object candidates so generated YAML
carries concrete USD paths without per-asset registry classes.

Signed-off-by: Qian Lin <qianl@nvidia.com>
Keep prompts like "maple table" as background-only so the resting surface is the background asset itself rather than inventing an in-scene object_reference.

Signed-off-by: Qian Lin <qianl@nvidia.com>
Select the authored Physics variant when spawning SimReady USD objects and when locating rigid bodies for contact sensors, preferring body prims when multiple rigid bodies share a depth.

Signed-off-by: Qian Lin <qianl@nvidia.com>
qianl-nv and others added 18 commits August 3, 2026 09:23
OR path-token filters so phrases like "disinfectant bottle" still match assets whose USD paths contain only one of the words.

Signed-off-by: Qian Lin <qianl@nvidia.com>
Searching for a "grey bin" returned a kitchen cabinet, because
SearchFilterPathContains matches any substring and "bin" appears inside
"Cabinets". The GA library has no bin at all, so the right answer is no
result, which lets the generator fall back to the asset registry.

- Keep only results that share a whole word with the search phrase, and
  order them by how many words match.
- Split camelCase when reading a path, so sm_trashCan matches "can".
- Merge multi-part SimReady props into one rigid body when spawning, and
  detect the object type with the Physics variant selected.

Signed-off-by: Xinjie Yao <xyao@nvidia.com>
A search for a "grey bin" came back with a kitchen cabinet, which carries a
rigid body per door and cannot be picked up at all. An asset that is not one
rigid body has no business in the objects of a generated environment.

- Reject a search hit unless its USD holds exactly one RigidBodyAPI, and try
  the next hit in its place.
- Match on the last word of the search phrase, which names the object itself,
  so a grey cabinet is no longer an answer for a grey bin.
- Name the objects nothing was found for in the prompt and in the traces, so
  the agent falls back to the Arena asset registry and the user is told.
- Drop the generated droid_disinfectant_into_grey_bin environment, whose bin
  was that cabinet.

Signed-off-by: Xinjie Yao <xyao@nvidia.com>
The SimReady search now turns down any asset with more than one rigid body,
so nothing is left to merge. Remove the weld, the mass and inertia combining
it needed, the joint-based classification that decided what to merge, and the
tie-breaking that let contact sensors pick a body out of a multi-body prop.

detect_object_type goes back to raising on several rigid bodies at the same
depth, keeping only the variant selection SimReady props need.

Signed-off-by: Xinjie Yao <xyao@nvidia.com>
functools.cache cannot key on a dict of variants, which is the only reason the
read was split in two. Keep the answers in a dict of its own instead, so the
public function is the whole thing.

Signed-off-by: Xinjie Yao <xyao@nvidia.com>
The registry name is the asset library's own name, and the bucket and service
URLs say where its assets come from, so the search module is not their home.
It imports them instead, which also drops the deferred variants import.

Signed-off-by: Xinjie Yao <xyao@nvidia.com>
Importing pxr before SimulationApp starts makes Kit warn that the USD
modules might not be loaded correctly. The SimReady search test imports
simready_asset_search at module scope, which reaches rigid_bodies, so a
module-scope pxr import there loads the whole USD stack during pytest
collection.

Signed-off-by: Xinjie Yao <xyao@nvidia.com>
@xyao-nv
xyao-nv force-pushed the xyao/feature/sim_ready_search branch from fe4179c to 62cec7b Compare August 3, 2026 16:36
@xyao-nv
xyao-nv enabled auto-merge (squash) August 3, 2026 19:19
@xyao-nv
xyao-nv merged commit d98f2e3 into main Aug 3, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants