Skip to content

Allow accepting the CloudXR EULA non-interactively - #7380

Open
2047767028-lang wants to merge 5 commits into
isaac-sim:developfrom
2047767028-lang:fix/cloudxr-eula-noninteractive
Open

Allow accepting the CloudXR EULA non-interactively#7380
2047767028-lang wants to merge 5 commits into
isaac-sim:developfrom
2047767028-lang:fix/cloudxr-eula-noninteractive

Conversation

@2047767028-lang

@2047767028-lang 2047767028-lang commented Aug 27, 2026

Copy link
Copy Markdown

Description

The NVIDIA CloudXR license is separate from the Omniverse one, and
TeleopSessionLifecycle._ensure_cloudxr_runtime hardcodes accept_eula=False when it
constructs the CloudXRLauncher. With no acceptance marker present the launcher then prompts
on stdin, so any run without a terminal attached — setsid nohup, a container, CI — aborts:

NVIDIA CloudXR EULA must be accepted to run. View: <...>
Accept NVIDIA CloudXR EULA? [y/N]: EULA not accepted. Exiting.
RuntimeError: CloudXR EULA was not accepted; cannot start the runtime

isaacteleop already supports accepting it up front — CloudXRLauncher takes an
accept_eula argument and even registers an --accept-eula flag whose help text reads
"Accept the NVIDIA CloudXR EULA non-interactively (e.g. for CI or containers)". Isaac Lab
simply never surfaced it, so there is no way to reach it from isaaclab teleop run,
teleop_se3_agent.py or record_demos.py.

This reads ISAACLAB_CXR_ACCEPT_EULA=1 and passes it through. The env-var form matches the
ISAACLAB_CXR_SKIP_AUTOLAUNCH escape hatch a few lines above in the same method, and mirrors
OMNI_KIT_ACCEPT_EULA for the Omniverse license. Unset — or any other value — keeps today's
interactive prompt, so existing behaviour is unchanged and the license is still an explicit
opt-in.

Both places that launch the runtime share one cloudxr_eula_accepted() helper — the session
lifecycle and the process-scoped launcher in teleop_replay_agent.py, which owns its own
CloudXRLauncher — so the variable means the same thing whichever script starts CloudXR.

Validation. On a headless workstation, with the acceptance marker at
~/.cloudxr/run/eula_accepted deleted first so the prompt path is actually exercised: a
setsid nohup teleop run previously died with the RuntimeError above; with
ISAACLAB_CXR_ACCEPT_EULA=1 it starts the runtime, logs CloudXR runtime auto-launched,
recreates the marker, and reaches waiting for XR session.

source/isaaclab_teleop/test/test_cloudxr_lifecycle.py gains TestCloudXREulaAcceptance
(exact 1, whitespace-padded 1, six non-accepting values, unset, and independence from
ISAACLAB_CXR_SKIP_AUTOLAUNCH), and test_launches_with_correct_args now clears both CloudXR
variables so the suite no longer depends on the ambient environment. 33 pass with the variable
unset and with each of 1, 1, 0, yes exported.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Release backport

  • Backport this pull request to the active release branch after it merges into develop

Screenshots

Not applicable — terminal-only behaviour.

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have added a changelog fragment under source/<pkg>/changelog.d/ for every touched package (do not edit CHANGELOG.rst or bump extension.toml — CI handles that)
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

Note on the unchecked box: I have left CONTRIBUTORS.md alone; let me know if you would
like me to add an entry.

@2047767028-lang
2047767028-lang requested a review from a team August 27, 2026 08:13
@github-actions github-actions Bot added bug Something isn't working isaac-lab Related to Isaac Lab team labels Aug 27, 2026

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Isaac Lab Review Bot

The change adds the opt-in ISAACLAB_CXR_ACCEPT_EULA=1 environment variable and forwards its parsed value to the existing CloudXRLauncher(accept_eula=...) parameter, with a corresponding package changelog fragment.

  • Design and architecture: The behavior is localized to the existing CloudXR launcher construction path and follows the adjacent environment-variable escape-hatch pattern. Launcher lifecycle, shutdown ownership, and auto-launch precedence remain unchanged. The environment-only control is a reasonable narrow scope for non-interactive deployments.
  • API: No public Python symbols, signatures, defaults, or return types change. Unset values and values other than 1 continue to pass False, preserving the existing interactive EULA flow. The new user-visible environment variable is documented in the method and changelog.
  • Implementation: The exact strip() == "1" parsing is deterministic and consistent with the sibling ISAACLAB_CXR_SKIP_AUTOLAUNCH handling. Existing early returns remain ahead of launcher construction, and the already-imported os module is reused without adding dependencies. The principal residual risk is the absence of automated regression coverage for the launcher path, but the implementation is sufficiently direct that this does not establish a pre-merge defect.

No blocking issues. No inline issue met the actionable-evidence threshold; the assessment above records the review feedback.

Automated review; human maintainers own approval decisions.

@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds an opt-in environment variable that passes non-interactive NVIDIA CloudXR EULA acceptance to the teleoperation session lifecycle and documents it in a changelog fragment.

  • Reads ISAACLAB_CXR_ACCEPT_EULA, accepting only the trimmed value 1.
  • Passes the resulting boolean to CloudXRLauncher.
  • Leaves the separate replay-agent CloudXR auto-launch path outside the new behavior.

Confidence Score: 4/5

The PR should not merge until the replay workflow’s independent CloudXR launcher also honors the new EULA acceptance setting.

Headless replay runs bypass the changed lifecycle method and continue passing accept_eula=False, so the newly documented setting does not prevent their EULA prompt and startup failure.

Files Needing Attention: source/isaaclab_teleop/isaaclab_teleop/session_lifecycle.py and scripts/environments/teleoperation/teleop_replay_agent.py

Important Files Changed

Filename Overview
source/isaaclab_teleop/isaaclab_teleop/session_lifecycle.py Adds environment-controlled EULA acceptance to lifecycle-managed CloudXR launches, but the behavior does not cover the separate replay launcher.
source/isaaclab_teleop/changelog.d/pk-cloudxr-eula-noninteractive.rst Documents non-interactive EULA acceptance broadly for teleop scripts, although one CloudXR auto-launch workflow remains unsupported.

Reviews (1): Last reviewed commit: "Allow accepting the CloudXR EULA non-int..." | Re-trigger Greptile

install_dir=str(Path.home() / ".cloudxr"),
env_config=self._cloudxr_env_file,
accept_eula=False,
accept_eula=os.environ.get(_CXR_ACCEPT_EULA_ENV, "").strip() == "1",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Replay bypasses EULA acceptance

When a headless replay run enables CloudXR auto-launch with ISAACLAB_CXR_ACCEPT_EULA=1, the replay agent uses its separate launcher with accept_eula=False and disables this lifecycle-managed path, causing the EULA prompt and RuntimeError that this setting is intended to prevent.

Knowledge Base Used: XR teleoperation

The NVIDIA CloudXR license is separate from the Omniverse one, and
`_ensure_cloudxr_runtime` hardcoded `accept_eula=False` when constructing the
`CloudXRLauncher`. With no acceptance marker present the launcher then prompts
on stdin, so any run without a terminal attached -- `nohup`, a container, CI --
dies with:

    Accept NVIDIA CloudXR EULA? [y/N]: EULA not accepted. Exiting.
    RuntimeError: CloudXR EULA was not accepted; cannot start the runtime

`isaacteleop` already supports accepting it up front: `CloudXRLauncher` takes an
`accept_eula` argument and registers an `--accept-eula` flag for exactly this
case. Isaac Lab simply never surfaced it.

Read `ISAACLAB_CXR_ACCEPT_EULA=1` and pass it through. The env-var form matches
the `ISAACLAB_CXR_SKIP_AUTOLAUNCH` escape hatch a few lines above, and mirrors
`OMNI_KIT_ACCEPT_EULA` for the Omniverse license. Unset or any other value keeps
the current interactive prompt, so existing behaviour is unchanged.

Verified on a headless multi-GPU workstation: with the acceptance marker at
`~/.cloudxr/run/eula_accepted` deleted, a `setsid nohup` teleop run now starts
the runtime and recreates the marker instead of aborting.

Signed-off-by: 2047767028-lang <2047767028@qq.com>
@AntoineRichard

Copy link
Copy Markdown
Collaborator

AI review comment

Generated by Codex (AI).

@rwiltz Could you please confirm the intended CloudXR behavior for XR replay?

Greptile correctly identified a real gap. teleop_replay_agent.py deliberately owns a separate, process-scoped CloudXRLauncher and disables the lifecycle-managed launcher, but that separate path still passes accept_eula=False. Consequently, ISAACLAB_CXR_ACCEPT_EULA=1 does not prevent the EULA prompt and RuntimeError for headless XR replay, despite the changelog saying the variable applies when teleop scripts auto-launch CloudXR.

I recommend addressing this before merge by making _maybe_launch_cloudxr() honor the same environment variable, ideally through shared parsing logic. If replay is intentionally out of scope, the changelog should explicitly limit the promise to lifecycle-backed scripts.

There is also an existing unit-test harness in source/isaaclab_teleop/test/test_cloudxr_lifecycle.py. At the exact PR head:

  • With the variable unset: 22 tests passed.
  • With ISAACLAB_CXR_ACCEPT_EULA=1: 1 failed, 21 passed because test_launches_with_correct_args does not isolate the new variable and still expects accept_eula=False.

Please add focused cases for 1, whitespace-padded 1, unset, and non-1 values, while isolating both CloudXR environment variables. The new variable should also be documented alongside ISAACLAB_CXR_SKIP_AUTOLAUNCH in docs/source/features/isaac_teleop.rst.

Review feedback from @AntoineRichard on three counts.

**Replay was not covered.** `teleop_replay_agent._maybe_launch_cloudxr` owns a
second, process-scoped `CloudXRLauncher` and passed `accept_eula=False` of its
own, so `ISAACLAB_CXR_ACCEPT_EULA=1` did not prevent the prompt for headless XR
replay even though its docstring states it mirrors the lifecycle gating. Both
call sites now go through one `cloudxr_eula_accepted()` helper, exported from
`isaaclab_teleop`, so the variable means the same thing wherever the runtime is
started.

**The existing suite was not isolated from the new variable.** With
`ISAACLAB_CXR_ACCEPT_EULA=1` exported, `test_launches_with_correct_args` failed:
it popped only `ISAACLAB_CXR_SKIP_AUTOLAUNCH` while still asserting
`accept_eula=False`. It now clears both CloudXR variables.

**Added focused coverage** in `TestCloudXREulaAcceptance`: an exact `1`, `1`
padded with spaces and with tabs/newlines, six non-accepting values including
the empty string and `1 1`, the unset case, and one asserting the two CloudXR
variables do not read each other. Each case checks both the helper and the
`accept_eula` value that reaches the launcher.

Verified in the Isaac Lab conda environment: 33 passed with the variable unset
and with each of `1`, ` 1 `, `0` and `yes` exported, so the suite no longer
depends on the ambient environment.

Also documents the variable in `docs/source/features/isaac_teleop.rst` next to
`ISAACLAB_CXR_SKIP_AUTOLAUNCH`, including that acceptance is recorded in
`~/.cloudxr/run/eula_accepted` and that it applies to the replay launcher too.

Signed-off-by: 2047767028-lang <2047767028@qq.com>
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Aug 29, 2026
@2047767028-lang

Copy link
Copy Markdown
Author

Thanks @AntoineRichard — all three points were real, and the replay gap in particular was a
hole in the promise the changelog was making. Addressed in 7c48a40.

Replay now shares the parsing. _maybe_launch_cloudxr owned a second, process-scoped
launcher passing its own accept_eula=False, so the variable genuinely did nothing for
headless XR replay — while its docstring claimed parity with the lifecycle gating. Both call
sites now go through one helper:

def cloudxr_eula_accepted() -> bool:
    return os.environ.get(_CXR_ACCEPT_EULA_ENV, "").strip() == "1"

exported from isaaclab_teleop and added to __init__.pyi. I kept it in
session_lifecycle.py next to the sibling ISAACLAB_CXR_SKIP_AUTOLAUNCH handling rather than
introducing a new module, but happy to move it if you would prefer it elsewhere.

The test isolation bug is fixed. You are right that test_launches_with_correct_args
popped only ISAACLAB_CXR_SKIP_AUTOLAUNCH while still asserting accept_eula=False; it now
clears both CloudXR variables.

Added TestCloudXREulaAcceptance with the cases you asked for — exact 1, 1 padded with
spaces and with tabs/newlines, six non-accepting values (0, yes, true, empty, 11,
1 1), the unset case, and one asserting the two variables do not read each other. Each case
checks both the helper and the accept_eula value that actually reaches the launcher.

Run in the Isaac Lab conda environment, varying only the ambient variable:

ISAACLAB_CXR_ACCEPT_EULA Result
unset 33 passed
1 33 passed
1 33 passed
0 33 passed
yes 33 passed

(22 pre-existing plus 11 new parametrised cases; previously 1 produced 1 failed / 21 passed.)

Documented in docs/source/features/isaac_teleop.rst alongside
ISAACLAB_CXR_SKIP_AUTOLAUNCH, including that only an exact 1 accepts, that acceptance is
recorded in ~/.cloudxr/run/eula_accepted so later runs stop prompting, and that the variable
covers the replay launcher. The changelog fragment now states the same scope instead of
implying lifecycle-only coverage.

isaac-sim#7381 added _env_file_pins_gpu_index/_renderer_cuda_index at the same spot in
session_lifecycle.py where this branch adds cloudxr_eula_accepted. Both blocks are
pure additions and are kept; nothing else conflicted. No behaviour change:
test_cloudxr_lifecycle.py passes (33 tests) with ISAACLAB_CXR_ACCEPT_EULA unset, 1 and 0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019SsU8ziGULaEBbtmvJSQZW
@2047767028-lang

Copy link
Copy Markdown
Author

Merged develop into this branch in c471112 to clear the conflict with #7381. Both PRs add module-level helpers at the same spot in session_lifecycle.py; the resolution keeps both blocks (the EULA helper here, the GPU-pinning helpers from #7381) and touches nothing else. Merge rather than rebase so the review history above stays intact. No behaviour change.

Re-ran on the merged tree, varying only the ambient variable:

ISAACLAB_CXR_ACCEPT_EULA test_cloudxr_lifecycle.py
unset 33 passed
1 33 passed
0 33 passed

The other Kit-free suites in source/isaaclab_teleop/test/ (test_control_events, test_hand_debug_viz, test_session_step_failure, test_xr_camera_feed) pass with the same counts as on develop. ruff check, ruff format --check and codespell are clean on the resolved file.

@2047767028-lang

Copy link
Copy Markdown
Author

@AntoineRichard @rwiltz — this one is ready whenever you have a moment.

The three review points from 8/28 are addressed in 7c48a40 (replay now shares the same parsing helper, the test isolation bug is fixed, and the variable is documented in isaac_teleop.rst), and the conflict that appeared after #7381 merged is resolved in c471112 by merging develop — both PRs add module-level helpers at the same spot in session_lifecycle.py, so the resolution keeps both blocks and touches nothing else. test_cloudxr_lifecycle.py passes 33/33 with ISAACLAB_CXR_ACCEPT_EULA unset, 1 and 0.

One note on the red check: Check for Broken Links is unrelated to this PR. All five errors are 403 Forbidden from opensource.org links in README.md and docs/source/refs/license.rst, neither of which this PR touches, and the same check passes on develop.

Happy to adjust anything if it would help.

The docs offered ISAACLAB_CXR_ACCEPT_EULA as working "the same way
OMNI_KIT_ACCEPT_EULA works for the Omniverse license", but the parser only
took an exact 1, while Kit's gate is

    os.environ.get("OMNI_KIT_ACCEPT_EULA", default="N").lower() in ["y", "yes", "1"]

and every use of that variable in this repository spells it Y or yes, never 1.
A user carrying that spelling over got ISAACLAB_CXR_ACCEPT_EULA=yes silently
ignored and the run aborted with the RuntimeError this variable exists to
avoid, with nothing to indicate the variable had been read and rejected.

Accept y, yes and 1 instead, case-insensitively. This matches Kit's set exactly
and also matches the CloudXR prompt itself, which takes y/yes, so the answer a
user would type at the prompt is the answer they can put in the variable.
Surrounding whitespace is still stripped and everything else -- 0, no, true,
unset -- still keeps the interactive prompt, so acceptance remains an explicit
opt-in.

@AntoineRichard AntoineRichard 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.

I pushed a commit to this branch (e916ff0) rather than leaving it as a suggestion, since it touched three files together — see the commit message for the reasoning. Short version: the docs offer ISAACLAB_CXR_ACCEPT_EULA as working "the same way OMNI_KIT_ACCEPT_EULA works", but Kit's gate is

# isaacsim/kit/kit_app.py:19
if os.environ.get("OMNI_KIT_ACCEPT_EULA", default="N").lower() in ["y", "yes", "1"]:

and every use of that variable in this repo spells it Y or yes, never 1 (docs/source/setup/installation/index.rst:478, the LEAPP pages, docs/source/experimental-features/rlinf_vla_posttraining.rst:78). So a user carrying that spelling over got ISAACLAB_CXR_ACCEPT_EULA=yes silently ignored and the run aborted with the exact RuntimeError this PR exists to remove. I ran every plausible value end-to-end through the real isaacteleop.cloudxr.runtime.check_eula and Kit's real check_eula with stdin closed; y/Y/yes/Yes/YES started under Kit and aborted under CloudXR. The commit accepts y, yes and 1 case-insensitively, which matches Kit's set exactly and also matches the CloudXR prompt itself (reply not in ("y", "yes")), so the answer a user would type at the prompt is the answer they can put in the variable. true/0/no/unset still keep the prompt. 39 tests pass.

Two smaller things left for you below. Nice fix overall — the isaacteleop side supports this cleanly and the gap was real.

@@ -0,0 +1,10 @@
Added

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.

This should be pk-cloudxr-eula-noninteractive.minor.rst.

An unsuffixed <slug>.rst is a patch bump, but this PR adds cloudxr_eula_accepted to isaaclab_teleop.__all__, and docs/source/refs/contributing.rst:166 maps "minor bump (new public API)" to the .minor.rst suffix. The fragment's own section being Added points the same way.

Worth flagging that tools/changelog/cli.py check passes either way — it validates the filename pattern and the section headers, not whether the tier matches the change — so this one won't correct itself in CI.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Renamed in 2508e10 — the fragment is now pk-cloudxr-eula-noninteractive.minor.rst.

You're right that the tier was wrong and that CI won't say so: tools/changelog/cli.py check --include-worktree reports ✓ All modified packages have valid changelog fragments. both before and after the rename, because it validates the filename pattern and the section headers, not whether the tier matches the change. The PR does add a name to isaaclab_teleop.__all__, and docs/source/refs/contributing.rst maps <slug>.minor.rst to "minor bump (new public API)", so .minor is the right tier.

XrCameraFeedLayoutCfg,
)
from .isaac_teleop_device import IsaacTeleopDevice, create_isaac_teleop_device
from .session_lifecycle import cloudxr_eula_accepted

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.

This line is load-bearing and nothing tests it. teleop_replay_agent.py imports from isaaclab_teleop import cloudxr_eula_accepted, which only resolves because lazy_export() reads this stub — but test_cloudxr_lifecycle.py imports from isaaclab_teleop.session_lifecycle directly, so it never exercises the package-level name.

I confirmed the gap: deleting this line leaves all tests green while from isaaclab_teleop import cloudxr_eula_accepted raises ImportError: cannot import name 'cloudxr_eula_accepted' from 'isaaclab_teleop'. The replay path would break at runtime with a passing suite.

One assertion in TestCloudXREulaAcceptance closes it:

def test_exported_from_package_root(self):
    """The replay agent imports the helper from the package root, not the submodule."""
    import isaaclab_teleop

    assert isaaclab_teleop.cloudxr_eula_accepted is cloudxr_eula_accepted

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added in 2508e10, as your assertion.

I reproduced the gap before adding it rather than taking it on faith. Deleting from .session_lifecycle import cloudxr_eula_accepted from the stub and re-running the file:

1 failed, 39 passed in 2.09s
FAILED TestCloudXREulaAcceptance::test_exported_from_package_root
  - AttributeError: No isaaclab_teleop attribute cloudxr_eula_accepted

The AttributeError comes out of lazy_loader/__init__.py:90, so lazy_export() genuinely has nothing to resolve the name with once that line is gone — the surviving "cloudxr_eula_accepted" entry in __all__ is not enough on its own. The other 39 tests stay green, which is the part that makes this worth covering: scripts/environments/teleoperation/teleop_replay_agent.py:1006 does from isaaclab_teleop import cloudxr_eula_accepted, so that deletion breaks the replay path at runtime with a fully passing suite.

With the line restored, 40 pass.

Two follow-ups from review.

The fragment was an unsuffixed <slug>.rst, a patch bump, but this PR adds
cloudxr_eula_accepted to isaaclab_teleop.__all__ and the stub that exports it.
docs/source/refs/contributing.rst maps "minor bump (new public API)" to the
.minor.rst suffix, and the fragment's own Added section says the same. CI does
not catch this: tools/changelog/cli.py check validates the filename pattern and
the section headers, not whether the tier matches the change.

The line in __init__.pyi that exports the helper was load-bearing and untested.
teleop_replay_agent.py imports it from the package root, which only resolves
because lazy_export() reads that stub, while the suite imports from
isaaclab_teleop.session_lifecycle directly and so never exercises the
package-level name. Deleting the stub line leaves all 39 tests green while
"from isaaclab_teleop import cloudxr_eula_accepted" raises, so the replay path
would break at runtime with a passing suite. Confirmed by removing the line:
only the new assertion fails, with "No isaaclab_teleop attribute
cloudxr_eula_accepted" out of lazy_loader. 40 tests pass with it restored.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019SsU8ziGULaEBbtmvJSQZW
@2047767028-lang

Copy link
Copy Markdown
Author

Thanks @AntoineRichard — both follow-ups are in 2508e10, and the parsing change in e916ff0 is a fix I should have made myself.

I checked the premise rather than just taking the commit: git grep finds OMNI_KIT_ACCEPT_EULA spelled Y or yes at every use site in this repo and never 1, so the docs sentence offering this variable as working "the same way OMNI_KIT_ACCEPT_EULA works" was writing a cheque the exact-1 parser didn't cover. ISAACLAB_CXR_ACCEPT_EULA=yes was read, rejected silently, and the run then died on the very RuntimeError the variable exists to remove — the worst shape for this kind of bug, since nothing tells the user the variable was seen.

Both follow-ups are answered in the threads above, with the reproduction for each. The suite is at 40 passing, ruff@0.14.10 check/format --check are clean on the touched file, and tools/changelog/cli.py check --include-worktree passes.

@2047767028-lang

Copy link
Copy Markdown
Author

@rwiltz @hougantc-nvda @kellyguo11 — this is approved by @AntoineRichard (2026-09-04) and now only needs a CODEOWNER review to unblock: .github/CODEOWNERS maps /source/isaaclab_teleop/ to the three of you, so his approval does not satisfy the requirement.

Two notes for whoever picks it up:

@2047767028-lang

Copy link
Copy Markdown
Author

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation isaac-lab Related to Isaac Lab team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants