Skip to content

fix(plugin): always probe live gateway model for TUI footer - #2661

Merged
ericksoa merged 5 commits into
mainfrom
fix/plugin-tui-stale-model-2608
Apr 29, 2026
Merged

fix(plugin): always probe live gateway model for TUI footer#2661
ericksoa merged 5 commits into
mainfrom
fix/plugin-tui-stale-model-2608

Conversation

@jason-ma-nv

@jason-ma-nv jason-ma-nv commented Apr 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

After a runtime openshell inference set, the OpenClaw TUI footer continued showing the onboard-time model because the plugin only read the model from the on-disk onboard config (which is never updated at runtime). This fix makes the plugin always probe the live gateway inference state at registration time and prefer that result for both the banner display and registered provider model.

Related Issue

Fixes #2608

Changes

  • nemoclaw/src/index.ts: Always call probeOpenShellInference() unconditionally at plugin registration (instead of only when the onboard config is missing fields); prefer probed.model over onboardCfg?.model for bannerModel and the registered provider model catalog
  • nemoclaw/src/index.ts: In activeModelEntries, flip precedence so the live fallbackModel overrides the stale onboard config model
  • nemoclaw/src/register.test.ts: Add regression test asserting that the live gateway model wins over the stale onboard config model after a runtime switch

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Verification

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

AI Disclosure

  • AI-assisted — tool: Claude Code

Signed-off-by: Jason Ma jama@nvidia.com

Summary by CodeRabbit

  • Bug Fixes

    • Model selection now always uses live gateway probe results (and falls back to empty/default when none), ensuring registration, UI banner, and endpoints reflect current runtime gateway info rather than stale onboard config.
  • Tests

    • Added a regression test verifying runtime probing overrides outdated onboard model data and that registration and logs reflect the probed model.

After a runtime `openshell inference set` the plugin was reading the
inference model only from the on-disk onboard config, which is never
updated at runtime, so the TUI footer showed a stale onboard-time model.

Fix: always call probeOpenShellInference() at plugin registration and
prefer its result for the banner and registered provider model so the
footer reflects the live gateway state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Jason Ma <jama@nvidia.com>
@jason-ma-nv jason-ma-nv self-assigned this Apr 29, 2026
@copy-pr-bot

copy-pr-bot Bot commented Apr 29, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Model selection and provider registration now always probe the live OpenShell gateway and prefer the probed gateway model for active/banners, rather than relying on onboard configuration; activeModel defaults to an empty string when neither source provides a model.

Changes

Cohort / File(s) Summary
Model selection & registration
nemoclaw/src/index.ts
Unconditionally call probeOpenShellInference() during register; prefer the probed gateway model when computing activeModelEntries and bannerModel; ensure activeModel defaults to "" if no model is available.
Regression test
nemoclaw/src/register.test.ts
Add test that sets an onboard model, mocks a different probed gateway model, and asserts the registered provider and emitted logs reflect the runtime-probed model.

Sequence Diagram(s)

sequenceDiagram
  participant Register as Register()
  participant Probe as probeOpenShellInference()
  participant Provider as Provider Registry
  participant TUI as OpenClaw TUI / Banner

  Register->>Probe: probeOpenShellInference()
  Note right of Probe: returns probed.model, endpoint, provider
  Probe-->>Register: probed result
  Register->>Provider: register provider using probed.model
  Provider-->>Register: registration confirmation
  Register->>TUI: compute bannerModel (prefer probed.model) and banner endpoint/provider
  TUI-->>Register: render footer with live probed model
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I sniffed the gateway, quick and spry,

found the live model roaming by,
I hopped and updated banner tune,
no stale footers under moon,
hooray — the TUI shows the sky!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: always probing the live gateway model for the TUI footer, directly addressing the issue of stale model display.
Linked Issues check ✅ Passed The PR changes meet all coding requirements from issue #2608: always probe OpenShell inference at registration, prefer probed model over onboard config for banner/provider, and add regression test validating the fix.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the stale model display issue in the TUI footer by unconditionally probing the live gateway and prioritizing it over onboard config.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/plugin-tui-stale-model-2608

Review rate limit: 8/10 reviews remaining, refill in 11 minutes and 20 seconds.

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

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

🧹 Nitpick comments (1)
nemoclaw/src/index.ts (1)

334-353: Don't block plugin registration on the live probe.

execFileSync("openshell", ...) now runs on every plugin load, so a slow or missing CLI can stall startup synchronously before the TUI appears. Consider caching the last known live model or refreshing it after registration instead of on the hot path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nemoclaw/src/index.ts` around lines 334 - 353, The code currently calls
probeOpenShellInference() synchronously on the hot path which can block startup;
change registration to use the onboard config as the immediate source and defer
or async-refresh the live probe: call loadOnboardConfig() and compute
bannerEndpoint/bannerProvider/bannerModel from onboardCfg only (use
onboardCfg?.model or defaults) and call
api.registerProvider(registeredProviderForConfig(onboardCfg,
providerCredentialEnv, /*model*/ onboardCfg?.model ?? undefined)) immediately;
then invoke probeOpenShellInference() off the main path (spawn a Promise/worker)
and when it resolves, recompute the provider info and re-register or update the
provider via api.registerProvider(registeredProviderForConfig(...,
probed.model)) so the probe no longer blocks the TUI startup.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@nemoclaw/src/index.ts`:
- Around line 334-353: The code currently calls probeOpenShellInference()
synchronously on the hot path which can block startup; change registration to
use the onboard config as the immediate source and defer or async-refresh the
live probe: call loadOnboardConfig() and compute
bannerEndpoint/bannerProvider/bannerModel from onboardCfg only (use
onboardCfg?.model or defaults) and call
api.registerProvider(registeredProviderForConfig(onboardCfg,
providerCredentialEnv, /*model*/ onboardCfg?.model ?? undefined)) immediately;
then invoke probeOpenShellInference() off the main path (spawn a Promise/worker)
and when it resolves, recompute the provider info and re-register or update the
provider via api.registerProvider(registeredProviderForConfig(...,
probed.model)) so the probe no longer blocks the TUI startup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b1dfa0f2-a13e-4132-96c1-069e1cc18dfc

📥 Commits

Reviewing files that changed from the base of the PR and between 7c5174e and 0fc2a71.

📒 Files selected for processing (2)
  • nemoclaw/src/index.ts
  • nemoclaw/src/register.test.ts

jason-ma-nv and others added 2 commits April 29, 2026 17:37
…t.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Jason Ma <jama@nvidia.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Jason Ma <jama@nvidia.com>

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@nemoclaw/src/index.ts`:
- Around line 340-350: The footer logic currently prefers onboardCfg for
bannerEndpoint/bannerProvider causing stale values; update initialization so
bannerEndpoint and bannerProvider prefer probed.endpoint and probed.provider
first (like bannerModel does), falling back to
describeOnboardEndpoint(onboardCfg)/describeOnboardProvider(onboardCfg) only if
probed values are falsy, and then to the same string defaults
("build.nvidia.com", "NVIDIA Endpoints"); adjust the assignments around
bannerEndpoint, bannerProvider, probed, and onboardCfg accordingly so the live
probe wins.
🪄 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: 6ab4665e-bbe6-4f9e-ba61-9cc07470c244

📥 Commits

Reviewing files that changed from the base of the PR and between 0fc2a71 and ef6f4a4.

📒 Files selected for processing (2)
  • nemoclaw/src/index.ts
  • nemoclaw/src/register.test.ts

Comment thread nemoclaw/src/index.ts
Comment on lines 340 to 350
let bannerEndpoint = onboardCfg ? describeOnboardEndpoint(onboardCfg) : "";
let bannerProvider = onboardCfg ? describeOnboardProvider(onboardCfg) : "";
let bannerModel = onboardCfg?.model ?? "";
let probedModel = "";

if (!bannerEndpoint || !bannerProvider || !bannerModel) {
const probed = probeOpenShellInference();
if (!bannerEndpoint) bannerEndpoint = probed.endpoint;
if (!bannerProvider) bannerProvider = probed.provider;
if (!bannerModel) bannerModel = probed.model;
probedModel = probed.model;
}
// Prefer the live gateway model over the stale onboard config model.
let bannerModel = probed.model || onboardCfg?.model || "";

if (!bannerEndpoint) bannerEndpoint = probed.endpoint;
if (!bannerProvider) bannerProvider = probed.provider;

if (!bannerEndpoint) bannerEndpoint = "build.nvidia.com";
if (!bannerProvider) bannerProvider = "NVIDIA Endpoints";
if (!bannerModel) bannerModel = "nvidia/nemotron-3-super-120b-a12b";

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.

⚠️ Potential issue | 🟠 Major

Keep the footer banner sourced from the live probe, not just the model.

bannerModel now tracks the probed gateway, but bannerEndpoint and bannerProvider still prefer onboardCfg whenever it exists. After a runtime openshell inference set, the footer can still show stale endpoint/provider metadata, so the UI does not fully reflect the live gateway state this PR is aiming for.

♻️ Suggested fix
-  let bannerEndpoint = onboardCfg ? describeOnboardEndpoint(onboardCfg) : "";
-  let bannerProvider = onboardCfg ? describeOnboardProvider(onboardCfg) : "";
+  let bannerEndpoint = probed.endpoint || (onboardCfg ? describeOnboardEndpoint(onboardCfg) : "");
+  let bannerProvider = probed.provider || (onboardCfg ? describeOnboardProvider(onboardCfg) : "");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let bannerEndpoint = onboardCfg ? describeOnboardEndpoint(onboardCfg) : "";
let bannerProvider = onboardCfg ? describeOnboardProvider(onboardCfg) : "";
let bannerModel = onboardCfg?.model ?? "";
let probedModel = "";
if (!bannerEndpoint || !bannerProvider || !bannerModel) {
const probed = probeOpenShellInference();
if (!bannerEndpoint) bannerEndpoint = probed.endpoint;
if (!bannerProvider) bannerProvider = probed.provider;
if (!bannerModel) bannerModel = probed.model;
probedModel = probed.model;
}
// Prefer the live gateway model over the stale onboard config model.
let bannerModel = probed.model || onboardCfg?.model || "";
if (!bannerEndpoint) bannerEndpoint = probed.endpoint;
if (!bannerProvider) bannerProvider = probed.provider;
if (!bannerEndpoint) bannerEndpoint = "build.nvidia.com";
if (!bannerProvider) bannerProvider = "NVIDIA Endpoints";
if (!bannerModel) bannerModel = "nvidia/nemotron-3-super-120b-a12b";
let bannerEndpoint = probed.endpoint || (onboardCfg ? describeOnboardEndpoint(onboardCfg) : "");
let bannerProvider = probed.provider || (onboardCfg ? describeOnboardProvider(onboardCfg) : "");
// Prefer the live gateway model over the stale onboard config model.
let bannerModel = probed.model || onboardCfg?.model || "";
if (!bannerEndpoint) bannerEndpoint = probed.endpoint;
if (!bannerProvider) bannerProvider = probed.provider;
if (!bannerEndpoint) bannerEndpoint = "build.nvidia.com";
if (!bannerProvider) bannerProvider = "NVIDIA Endpoints";
if (!bannerModel) bannerModel = "nvidia/nemotron-3-super-120b-a12b";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nemoclaw/src/index.ts` around lines 340 - 350, The footer logic currently
prefers onboardCfg for bannerEndpoint/bannerProvider causing stale values;
update initialization so bannerEndpoint and bannerProvider prefer
probed.endpoint and probed.provider first (like bannerModel does), falling back
to describeOnboardEndpoint(onboardCfg)/describeOnboardProvider(onboardCfg) only
if probed values are falsy, and then to the same string defaults
("build.nvidia.com", "NVIDIA Endpoints"); adjust the assignments around
bannerEndpoint, bannerProvider, probed, and onboardCfg accordingly so the live
probe wins.

@jyaunches jyaunches self-assigned this Apr 29, 2026
@jyaunches
jyaunches self-requested a review April 29, 2026 13:58

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

Nice PR!!!

@jyaunches
jyaunches enabled auto-merge (squash) April 29, 2026 14:09
@ericksoa
ericksoa disabled auto-merge April 29, 2026 16:51
@ericksoa
ericksoa merged commit 6e0992c into main Apr 29, 2026
10 checks passed
DemianHeyGen pushed a commit to DemianHeyGen/NemoClaw that referenced this pull request Apr 30, 2026
)

## Summary

After a runtime `openshell inference set`, the OpenClaw TUI footer
continued showing the onboard-time model because the plugin only read
the model from the on-disk onboard config (which is never updated at
runtime). This fix makes the plugin always probe the live gateway
inference state at registration time and prefer that result for both the
banner display and registered provider model.

## Related Issue

Fixes NVIDIA#2608

## Changes

- `nemoclaw/src/index.ts`: Always call `probeOpenShellInference()`
unconditionally at plugin registration (instead of only when the onboard
config is missing fields); prefer `probed.model` over
`onboardCfg?.model` for `bannerModel` and the registered provider model
catalog
- `nemoclaw/src/index.ts`: In `activeModelEntries`, flip precedence so
the live `fallbackModel` overrides the stale onboard config model
- `nemoclaw/src/register.test.ts`: Add regression test asserting that
the live gateway model wins over the stale onboard config model after a
runtime switch

## Type of Change
- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Verification
- [x] `npx prek run --all-files` passes
- [x] `npm test` passes
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [ ] Docs updated for user-facing behavior changes
- [ ] `make docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

## AI Disclosure
- [x] AI-assisted — tool: Claude Code

---
Signed-off-by: Jason Ma <jama@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Model selection now always uses live gateway probe results (and falls
back to empty/default when none), ensuring registration, UI banner, and
endpoints reflect current runtime gateway info rather than stale onboard
config.

* **Tests**
* Added a regression test verifying runtime probing overrides outdated
onboard model data and that registration and logs reflect the probed
model.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Jason Ma <jama@nvidia.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: J. Yaunches <jyaunches@nvidia.com>
Co-authored-by: Aaron Erickson 🦞 <aerickson@nvidia.com>
@wscurran wscurran added area: cli Command line interface, flags, terminal UX, or output area: integrations Third-party service integration behavior area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression feature PR adds or expands user-visible functionality and removed NemoClaw CLI labels Jun 3, 2026
@wscurran wscurran removed OpenShell feature PR adds or expands user-visible functionality labels Jun 3, 2026
@wscurran wscurran added NV QA Bugs found by the NVIDIA QA Team VDR Linked to VDR finding labels Jun 26, 2026
@cv
cv deleted the fix/plugin-tui-stale-model-2608 branch June 28, 2026 00:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output area: integrations Third-party service integration behavior area: sandbox OpenShell sandbox lifecycle, runtime, config, or recovery bug-fix PR fixes a bug or regression NV QA Bugs found by the NVIDIA QA Team VDR Linked to VDR finding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Linux][Agent] openclaw tui footer shows stale model after runtime inference switch

4 participants