Skip to content

feat(web): bump to 6.3.0-rc2 and adopt new metrics, quality score, logs - #841

Merged
yanziz-nvidia merged 2 commits into
mainfrom
feat/cloudxr-6.3.0-rc2
Jul 29, 2026
Merged

feat(web): bump to 6.3.0-rc2 and adopt new metrics, quality score, logs#841
yanziz-nvidia merged 2 commits into
mainfrom
feat/cloudxr-6.3.0-rc2

Conversation

@yanziz-nvidia

@yanziz-nvidia yanziz-nvidia commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Description

Bumps the CloudXR Web SDK from 6.2.0 → 6.3.0-rc2 and adopts the streaming diagnostics it adds.

The bump itself is API-compatible — everything new in rc2 is additive (3 SessionOptions fields, 3 delegates, 1 Session method, 17 MetricsName entries, a new PerNetwork cadence). The client was built against rc2 with zero code changes first to confirm this, so the version bump could be split out if reviewers prefer.

Session quality + Pose Send FPS on the in-XR HUD

  • MetricsName.SessionQuality (0–4) renders as a 4-bar signal-strength indicator, so an operator sees a degrading link before acting on it rather than inferring it from raw FPS.
  • Pose Send FPS measures the uplink command rate — the number that distinguishes "the video is choppy" from "the robot isn't getting my commands."
  • Both clear on disconnect so a dead stream can't show a stale green reading.

Body-tracking capability detection — bug fix

The SDK derives body-tracking support from XRSession.enabledFeatures, which it can only read from frames delivered before the stream starts. The render loop returned early on state !== Connected, so the SDK never saw such a frame — meaning full-body teleop could silently degrade to hand/controller only despite the client requesting bodyTracking: true.

Now pumps sendTrackingStateToServer() during Connecting. It deliberately passes the raw xrFrame rather than trackingFrameAdapter's: during replay the adapter returns a Proxy with a substituted session, and capability detection must reflect the real XRSession.

All SDK metrics to the OOB teleop hub

Reports all 21 metrics across the render/frame/network cadences keyed by CloudXR.MetricsName, up from 3. A new MetricsAccumulator merges the SDK's partial callbacks, so a metric absent from one tick isn't reported downstream as a zero.

No change to oob_teleop_hub.py_handle_client_metrics already stores an arbitrary {name: value} map per cadence, so future SDK metrics flow through too. The full metric table is documented in oob_teleop_control.rst.

SDK log mirroring

SDK log entries mirror to the browser console at matching severity (console.error/warn/debug/info) so DevTools filtering works. The onLog/logLevel API existed in 6.2.0; rc2 adds the log content worth surfacing.

Pre-stream network test — default off

Wired up with an in-XR countdown and traffic-light result, but off by default: the test holds the session in Connecting for its entire window, and an operator connecting to a robot shouldn't be gated on it. Opt in via the settings panel or ?streamTestMode=warn.

The configured duration is clamped to the [5, 30] second range the SDK accepts, so the on-panel countdown cannot promise a shorter window than the one that actually runs.

Shipped with a required companion fix: message-channel setup is now gated on isConnected, not just a non-null session. Opening a channel sends a control message that requires a connected session — without this guard, enabling the test would break the teleop control channel.

Also

Drops the isaac/ requirement from the local-tarball layout check in download_cloudxr_sdk.sh — that reference client was removed from the SDK bundle after 6.2.0, so requiring it would reject valid 6.3.0+ tarballs.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

The onRenderPerformanceMetrics / onStreamingPerformanceMetrics prop signatures on CloudXRComponent changed from positional numbers to partial objects. CloudXRComponent is internal to webxr_client, so this is not marked breaking — flagging it so reviewers can judge.

Testing

Verified locally (macOS, Node 24.11):

cd deps/cloudxr/webxr_client
npm install          # against nvidia-cloudxr-6.3.0-rc2.tgz
npm run build        # webpack, passes
npm test             # 61/61 pass
npx tsc --noEmit     # 9 pre-existing errors, none new

SKIP=check-copyright-year pre-commit run --all-files   # all pass

The 61 tests include 9 new MetricsAccumulator tests that pin the wire metric names the hub consumes, since renaming one is a breaking protocol change rather than a refactor.

Not verified — needs review attention:

  • Nothing has run against a real headset or a live CloudXR server.
  • The body-tracking fix in particular is structural. Whether IsaacTeleop was actually degrading to hand/controller only needs a before/after on body-tracking hardware.
  • The network test path is off by default and hasn't been exercised end to end.
  • CI will exercise the CXR_WEB_SDK_VERSION=6.3.0-rc2 NGC download path for the first time; local builds used a supplied tarball.

Checklist

  • I have read and understood the contribution guidelines
  • I have run the linter and formatter with SKIP=check-copyright-year pre-commit run --all-files
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix/feature works (or explained why not)
  • I have signed off all my commits (git commit -s) per the DCO

Notes for reviewers

  • deps/cloudxr/nvidia-cloudxr-6.3.0-rc2.tgz is gitignored (fetched by download_cloudxr_sdk.sh); package-lock.json is gitignored too, so neither appears in the diff.
  • Adds jest-environment-jsdom as a devDependency — the CloudXR SDK bundle touches window at import time, so the accumulator suite needs it. jest.setup.js stubs the User Timing entries jsdom lacks.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: the CloudXR Web SDK bump plus new metrics, quality score, and log handling.

Comment @coderabbitai help to get the list of available commands.

@yanziz-nvidia yanziz-nvidia changed the title feat(cloudxr): bump to 6.3.0-rc2 and adopt new metrics, quality score, logs feat(web): bump to 6.3.0-rc2 and adopt new metrics, quality score, logs Jul 29, 2026
@yanziz-nvidia yanziz-nvidia self-assigned this Jul 29, 2026

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@deps/cloudxr/webxr_client/helpers/react/CloudXRComponent.tsx`:
- Around line 566-583: Update the Connecting-state catch around
cxrSession.sendTrackingStateToServer to mirror the existing deferred-callback
error handling: report the failure through the component’s onError/disconnect
recovery path, clear the renderer when not headless before returning, and
preserve the early return after cleanup.

In `@deps/cloudxr/webxr_client/src/App.tsx`:
- Around line 544-556: Update the disconnect handling alongside sessionQuality
so poseSendFps, renderFps, and streamingMetrics are cleared when status is
Disconnected or Error. Preserve the existing non-Connected quality reset and
metricsAccumulator behavior, and ensure the HUD cannot retain values from the
previous session.

In `@deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx`:
- Around line 1054-1057: Enforce a shared finite-integer range of 5–30 for
streamTestDurationSeconds. In deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx
lines 1054-1057, replace truncating parseInt handling with the shared parser and
fall back to getDefaultConfiguration().streamTestDurationSeconds for invalid or
out-of-range values; update deps/cloudxr/webxr_client/src/config/params.ts lines
89-90 to use the same range validator instead of generic numeric validation;
update deps/cloudxr/webxr_client/src/config/resolve.test.ts lines 123-147 to use
5 as the valid sample and add rejected boundary cases.

In `@docs/source/references/oob_teleop_control.rst`:
- Around line 311-313: Update the metric reference in the network metrics table
to use network.loss_score instead of network.network_loss_score, keeping the
existing loss-score description unchanged.

In `@scripts/download_cloudxr_sdk.sh`:
- Line 12: Align is_valid_sdk_layout() and the local installer validation with
the documented optional single top-level directory layout: resolve the wrapper
directory before checking SDK contents, or remove that layout from the
documentation. If wrapped archives remain supported, update the validation error
text near the installer check to describe both accepted layouts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 60bad1db-2518-47cc-8bc4-bb57b5344038

📥 Commits

Reviewing files that changed from the base of the PR and between 583f5cb and c7edc59.

📒 Files selected for processing (19)
  • deps/cloudxr/.env.default
  • deps/cloudxr/webxr_client/helpers/metricsAccumulator.test.ts
  • deps/cloudxr/webxr_client/helpers/metricsAccumulator.ts
  • deps/cloudxr/webxr_client/helpers/metricsUpdates.ts
  • deps/cloudxr/webxr_client/helpers/react/CloudXRComponent.tsx
  • deps/cloudxr/webxr_client/helpers/react/PerformanceCanvasImage.tsx
  • deps/cloudxr/webxr_client/helpers/react/utils.ts
  • deps/cloudxr/webxr_client/helpers/utils.ts
  • deps/cloudxr/webxr_client/jest.setup.js
  • deps/cloudxr/webxr_client/package.json
  • deps/cloudxr/webxr_client/src/App.tsx
  • deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx
  • deps/cloudxr/webxr_client/src/CloudXRUI.tsx
  • deps/cloudxr/webxr_client/src/config/params.ts
  • deps/cloudxr/webxr_client/src/config/resolve.test.ts
  • deps/cloudxr/webxr_client/src/index.html
  • docs/source/getting_started/build_from_source/webxr.rst
  • docs/source/references/oob_teleop_control.rst
  • scripts/download_cloudxr_sdk.sh

Comment thread deps/cloudxr/webxr_client/helpers/react/CloudXRComponent.tsx
Comment thread deps/cloudxr/webxr_client/src/App.tsx
Comment thread deps/cloudxr/webxr_client/src/CloudXR2DUI.tsx
Comment thread docs/source/references/oob_teleop_control.rst
Comment thread scripts/download_cloudxr_sdk.sh
@yanziz-nvidia
yanziz-nvidia marked this pull request as ready for review July 29, 2026 18:25
@yanziz-nvidia
yanziz-nvidia requested a review from farbod-nv July 29, 2026 20:31
yanziz-nvidia and others added 2 commits July 29, 2026 13:53
…, logs

Bumps the CloudXR Web SDK from 6.2.0 to 6.3.0-rc2 and adopts the streaming
diagnostics it adds. The bump itself is API-compatible: everything new is
additive (3 SessionOptions fields, 3 delegates, 1 Session method, 17
MetricsName entries, a PerNetwork cadence), and the client builds against
rc2 unchanged.

Session quality and pose send FPS
- Surface MetricsName.SessionQuality (0-4) as a 4-bar signal-strength indicator
  on the in-XR HUD, so an operator can see a degrading link before acting on it
  rather than inferring it from raw FPS.
- Add a Pose Send FPS card. It measures the uplink command rate, which is what
  distinguishes "the video is choppy" from "the robot isn't getting my commands".
- Clear both on disconnect so a dead stream cannot show a stale green reading.

Body tracking capability detection (bug fix)
- Pump sendTrackingStateToServer() while the session is Connecting. The SDK
  derives body-tracking support from XRSession.enabledFeatures, which it can only
  read from frames delivered before the stream starts. The render loop previously
  returned early on state !== Connected, so the SDK never saw such a frame and
  full-body teleop could silently degrade to hand/controller only despite the
  client requesting bodyTracking.
- Deliberately passes the raw xrFrame rather than trackingFrameAdapter's: during
  replay the adapter returns a Proxy with a substituted session, and capability
  detection must reflect the real XRSession.

Metrics to the OOB teleop hub
- Report all 21 SDK metrics across the render/frame/network cadences, keyed by
  CloudXR.MetricsName, instead of the previous three. New MetricsAccumulator
  merges the SDK's partial callbacks so a metric absent from one tick is not
  reported as zero, and resets between sessions.
- oob_teleop_hub.py needs no change: it already stores metrics as an arbitrary
  {name: value} map per cadence.

SDK logs
- Mirror SDK log entries to the browser console at matching severity. The
  onLog/logLevel API existed in 6.2.0; rc2 adds the log content worth surfacing.

Pre-stream network test
- Wire up the SDK's network test with an in-XR countdown and traffic-light
  result, defaulting to off: the test holds the session in Connecting for its
  whole window, and an operator connecting to a robot should not be gated on it.
  Opt in via the settings panel or ?streamTestMode=warn.
- Clamp the configured duration to the [5, 30] second range the SDK accepts, so
  the on-panel countdown cannot promise a window shorter than the one that runs.
- Gate message-channel setup on isConnected, not just a non-null session.
  Opening a channel sends a control message that requires a connected session,
  which would fail during the test window and break the teleop control channel.

Microphone capture and clientToken/signalingHeaders are available in rc2 but not
adopted: the former is an unnecessary permission prompt for robot teleop, and the
latter targets Stream Manager auth rather than this direct-connect deployment.

Frame-rate negotiation was reviewed and left unchanged: this client already
applies the target rate before session creation and passes the effective rate to
CloudXR.

Also drops the isaac/ requirement from the local-tarball layout check, since that
directory is no longer part of the SDK release bundle.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Yanzi Zhu <yanziz@nvidia.com>
renderFps, poseSendFps and streamingMetrics are module-scoped signals that were
never cleared, so after a disconnect the in-XR panel kept drawing the previous
session's FPS and latency as if they were live. Same class of staleness the
session-quality reset already guarded against, but for the numeric cards.

Clears them alongside metricsAccumulator.reset() on Disconnected/Error only, so
the 'Testing network' transition into a session is unaffected. The computed
texts already fall back to '-' on null, so the cards read as empty rather than
zero.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Yanzi Zhu <yanziz@nvidia.com>
@yanziz-nvidia
yanziz-nvidia force-pushed the feat/cloudxr-6.3.0-rc2 branch from 55a1422 to d898680 Compare July 29, 2026 20:56
@yanziz-nvidia
yanziz-nvidia merged commit 543293a into main Jul 29, 2026
50 checks passed
@yanziz-nvidia
yanziz-nvidia deleted the feat/cloudxr-6.3.0-rc2 branch July 29, 2026 21:22
yanziz-nvidia added a commit that referenced this pull request Jul 30, 2026
…857)

* feat(web): bump to 6.3.0-rc2 and adopt new metrics, quality score, logs (#841)

* feat(cloudxr): bump to 6.3.0-rc2 and adopt new metrics, quality score, logs

Bumps the CloudXR Web SDK from 6.2.0 to 6.3.0-rc2 and adopts the streaming
diagnostics it adds. The bump itself is API-compatible: everything new is
additive (3 SessionOptions fields, 3 delegates, 1 Session method, 17
MetricsName entries, a PerNetwork cadence), and the client builds against
rc2 unchanged.

Session quality and pose send FPS
- Surface MetricsName.SessionQuality (0-4) as a 4-bar signal-strength indicator
  on the in-XR HUD, so an operator can see a degrading link before acting on it
  rather than inferring it from raw FPS.
- Add a Pose Send FPS card. It measures the uplink command rate, which is what
  distinguishes "the video is choppy" from "the robot isn't getting my commands".
- Clear both on disconnect so a dead stream cannot show a stale green reading.

Body tracking capability detection (bug fix)
- Pump sendTrackingStateToServer() while the session is Connecting. The SDK
  derives body-tracking support from XRSession.enabledFeatures, which it can only
  read from frames delivered before the stream starts. The render loop previously
  returned early on state !== Connected, so the SDK never saw such a frame and
  full-body teleop could silently degrade to hand/controller only despite the
  client requesting bodyTracking.
- Deliberately passes the raw xrFrame rather than trackingFrameAdapter's: during
  replay the adapter returns a Proxy with a substituted session, and capability
  detection must reflect the real XRSession.

Metrics to the OOB teleop hub
- Report all 21 SDK metrics across the render/frame/network cadences, keyed by
  CloudXR.MetricsName, instead of the previous three. New MetricsAccumulator
  merges the SDK's partial callbacks so a metric absent from one tick is not
  reported as zero, and resets between sessions.
- oob_teleop_hub.py needs no change: it already stores metrics as an arbitrary
  {name: value} map per cadence.

SDK logs
- Mirror SDK log entries to the browser console at matching severity. The
  onLog/logLevel API existed in 6.2.0; rc2 adds the log content worth surfacing.

Pre-stream network test
- Wire up the SDK's network test with an in-XR countdown and traffic-light
  result, defaulting to off: the test holds the session in Connecting for its
  whole window, and an operator connecting to a robot should not be gated on it.
  Opt in via the settings panel or ?streamTestMode=warn.
- Clamp the configured duration to the [5, 30] second range the SDK accepts, so
  the on-panel countdown cannot promise a window shorter than the one that runs.
- Gate message-channel setup on isConnected, not just a non-null session.
  Opening a channel sends a control message that requires a connected session,
  which would fail during the test window and break the teleop control channel.

Microphone capture and clientToken/signalingHeaders are available in rc2 but not
adopted: the former is an unnecessary permission prompt for robot teleop, and the
latter targets Stream Manager auth rather than this direct-connect deployment.

Frame-rate negotiation was reviewed and left unchanged: this client already
applies the target rate before session creation and passes the effective rate to
CloudXR.

Also drops the isaac/ requirement from the local-tarball layout check, since that
directory is no longer part of the SDK release bundle.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Yanzi Zhu <yanziz@nvidia.com>

* fix(cloudxr): clear HUD metric cards when the session ends

renderFps, poseSendFps and streamingMetrics are module-scoped signals that were
never cleared, so after a disconnect the in-XR panel kept drawing the previous
session's FPS and latency as if they were live. Same class of staleness the
session-quality reset already guarded against, but for the numeric cards.

Clears them alongside metricsAccumulator.reset() on Disconnected/Error only, so
the 'Testing network' transition into a session is unaffected. The computed
texts already fall back to '-' on null, so the cards read as empty rather than
zero.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Yanzi Zhu <yanziz@nvidia.com>

---------

Signed-off-by: Yanzi Zhu <yanziz@nvidia.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Add ESLint and Prettier to the WebXR client (#421)

* Add lint config files

Signed-off-by: Yanzi Zhu <yanziz@nvidia.com>

* Run format

Signed-off-by: Yanzi Zhu <yanziz@nvidia.com>

---------

Signed-off-by: Yanzi Zhu <yanziz@nvidia.com>
Co-authored-by: Yanzi Zhu <yanziz@nvidia.com>

---------

Signed-off-by: Yanzi Zhu <yanziz@nvidia.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Gareth Morgan <gmorgan@nvidia.com>
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