fix(onboard): propagate NEMOCLAW_INFERENCE_INPUTS to baked openclaw.json#2441
Conversation
Signed-off-by: Rui Luo <ruluo@nvidia.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds a build-time/runtime env var Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Host as Host shell
participant Onboard as src/lib/onboard.ts
participant Dockerfile as Staged Dockerfile
participant PyGen as Embedded Python config generator
participant Sandbox as Sandbox (/sandbox/.openclaw)
Host->>Onboard: export NEMOCLAW_INFERENCE_INPUTS & run onboard
Onboard->>Onboard: validate env (allowlist: text,image)
alt valid
Onboard->>Dockerfile: patch ARG NEMOCLAW_INFERENCE_INPUTS=text,image
else invalid/absent
Onboard-->>Dockerfile: keep ARG NEMOCLAW_INFERENCE_INPUTS=text
end
Dockerfile->>PyGen: build/run (ENV propagated)
PyGen->>PyGen: parse NEMOCLAW_INFERENCE_INPUTS -> ['text','image'] (fallback ['text'])
PyGen->>Sandbox: write openclaw.json with models[*].input = [...]
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/onboard.test.ts (1)
747-805: Decouple malformed-input cases from unrelatedbuildIdmutation.Line 787 currently injects each malformed test value into
buildId, which can mask failures by coupling this test to unrelatedNEMOCLAW_BUILD_IDhandling. KeepbuildIdconstant (or index-based) so the test isolatesNEMOCLAW_INFERENCE_INPUTSvalidation only.♻️ Proposed test-isolation fix
- for (const value of rejectCases) { + for (const [index, value] of rejectCases.entries()) { fs.writeFileSync(dockerfilePath, baseDockerfile); if (value === undefined) { delete process.env.NEMOCLAW_INFERENCE_INPUTS; } else { process.env.NEMOCLAW_INFERENCE_INPUTS = value; } patchStagedDockerfile( dockerfilePath, "gpt-5.4", "http://127.0.0.1:18789", - `build-inputs-reject-${String(value)}`, + `build-inputs-reject-${index}`, "openai-api", );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/onboard.test.ts` around lines 747 - 805, The test is accidentally injecting each malformed value into the buildId argument of patchStagedDockerfile, coupling NEMOCLAW_INFERENCE_INPUTS validation with buildId handling; change the call to patchStagedDockerfile so the buildId is constant (or based on the loop index) instead of using String(value) (e.g., use "build-inputs-reject" or `build-inputs-reject-${i}`), leaving process.env.NEMOCLAW_INFERENCE_INPUTS set per rejectCases and keeping the rest of the test unchanged (refer to patchStagedDockerfile, NEMOCLAW_INFERENCE_INPUTS, NEMOCLAW_BUILD_ID, and rejectCases).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@test/onboard.test.ts`:
- Around line 747-805: The test is accidentally injecting each malformed value
into the buildId argument of patchStagedDockerfile, coupling
NEMOCLAW_INFERENCE_INPUTS validation with buildId handling; change the call to
patchStagedDockerfile so the buildId is constant (or based on the loop index)
instead of using String(value) (e.g., use "build-inputs-reject" or
`build-inputs-reject-${i}`), leaving process.env.NEMOCLAW_INFERENCE_INPUTS set
per rejectCases and keeping the rest of the test unchanged (refer to
patchStagedDockerfile, NEMOCLAW_INFERENCE_INPUTS, NEMOCLAW_BUILD_ID, and
rejectCases).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 736b58e6-a643-421c-a156-9e983ed656fa
📒 Files selected for processing (3)
Dockerfilesrc/lib/onboard.tstest/onboard.test.ts
There was a problem hiding this comment.
🧹 Nitpick comments (2)
Dockerfile (1)
312-312: Add in-script allowlist validation for defense in depth.Line 312 normalizes input but does not reject unknown modalities. A direct build arg like
audiowould still be baked intoopenclaw.json. Mirror the allowlist check here and fail fast.♻️ Suggested hardening patch
-inference_inputs = [v.strip() for v in os.environ.get('NEMOCLAW_INFERENCE_INPUTS', 'text').split(',') if v.strip()] or ['text']; \ +inference_inputs = [v.strip() for v in os.environ.get('NEMOCLAW_INFERENCE_INPUTS', 'text').split(',') if v.strip()] or ['text']; \ +_allowed_inference_inputs = {'text', 'image'}; \ +if any(v not in _allowed_inference_inputs for v in inference_inputs): \ + raise ValueError('NEMOCLAW_INFERENCE_INPUTS must contain only: text,image'); \🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Dockerfile` at line 312, The current normalization of inference_inputs from NEMOCLAW_INFERENCE_INPUTS should include an allowlist check and fail-fast behavior: define a set of allowed modalities (e.g., ALLOWED_INFERENCE_INPUTS), parse and strip the env var into inference_inputs (as currently done), compute any_unknown = set(parsed_inputs) - ALLOWED_INFERENCE_INPUTS, and if any_unknown is non-empty log an error and exit (non-zero) so a bad build arg like "audio" cannot be baked into openclaw.json; update the code path where inference_inputs is set (variable name inference_inputs and use of NEMOCLAW_INFERENCE_INPUTS) to perform this validation before writing/openclaw.json.test/onboard.test.ts (1)
840-867: Decouple malformed-input coverage fromNEMOCLAW_BUILD_IDmutation path.On Line 860, the test injects
valueintobuildId. That mixes two validation surfaces and can hide the real failure cause. KeepbuildIdconstant and assert the injection payload never lands in the Dockerfile.Suggested patch
- patchStagedDockerfile( + patchStagedDockerfile( dockerfilePath, "gpt-5.4", "http://127.0.0.1:18789", - `build-inputs-reject-${String(value)}`, + "build-inputs-reject", "openai-api", ); - assert.match( - fs.readFileSync(dockerfilePath, "utf8"), + const patched = fs.readFileSync(dockerfilePath, "utf8"); + assert.match( + patched, /^ARG NEMOCLAW_INFERENCE_INPUTS=text$/m, `value="${String(value)}" should not change the ARG default`, ); + assert.doesNotMatch(patched, /RUN rm -rf/);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/onboard.test.ts` around lines 840 - 867, The test is mixing malformed NEMOCLAW_INFERENCE_INPUTS payloads with the buildId parameter which can mask failures; change the loop so only process.env.NEMOCLAW_INFERENCE_INPUTS is varied and pass a fixed buildId to patchStagedDockerfile (e.g. "build-inputs-reject-const" or include the loop index only) instead of using `value`, ensure you still call patchStagedDockerfile and assert the Dockerfile retains `ARG NEMOCLAW_INFERENCE_INPUTS=text` and that the raw injection string (the original `value`) does not appear in the Dockerfile to confirm the payload never landed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@Dockerfile`:
- Line 312: The current normalization of inference_inputs from
NEMOCLAW_INFERENCE_INPUTS should include an allowlist check and fail-fast
behavior: define a set of allowed modalities (e.g., ALLOWED_INFERENCE_INPUTS),
parse and strip the env var into inference_inputs (as currently done), compute
any_unknown = set(parsed_inputs) - ALLOWED_INFERENCE_INPUTS, and if any_unknown
is non-empty log an error and exit (non-zero) so a bad build arg like "audio"
cannot be baked into openclaw.json; update the code path where inference_inputs
is set (variable name inference_inputs and use of NEMOCLAW_INFERENCE_INPUTS) to
perform this validation before writing/openclaw.json.
In `@test/onboard.test.ts`:
- Around line 840-867: The test is mixing malformed NEMOCLAW_INFERENCE_INPUTS
payloads with the buildId parameter which can mask failures; change the loop so
only process.env.NEMOCLAW_INFERENCE_INPUTS is varied and pass a fixed buildId to
patchStagedDockerfile (e.g. "build-inputs-reject-const" or include the loop
index only) instead of using `value`, ensure you still call
patchStagedDockerfile and assert the Dockerfile retains `ARG
NEMOCLAW_INFERENCE_INPUTS=text` and that the raw injection string (the original
`value`) does not appear in the Dockerfile to confirm the payload never landed.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 10c36235-7409-46d4-863d-e7b0aeb3083a
📒 Files selected for processing (3)
Dockerfilesrc/lib/onboard.tstest/onboard.test.ts
Resolves conflicts in Dockerfile and test/nemoclaw-start.test.ts. - Dockerfile config-generation block: kept the externalized scripts/generate-openclaw-config.py invocation (the PR's purpose) and dropped the inline python3 -c block from main. - Dockerfile token step: dropped the PR's --clear-token step and took main's late-layer secrets.token_hex(32) injection (#2482 reverted gateway auth token externalization, so the token is again baked at build time). - scripts/generate-openclaw-config.py: ported the inference_inputs parsing (#2441) and channel healthMonitor field from main; removed the now-obsolete --clear-token mode. - test/nemoclaw-start.test.ts: took main's version, since the PR's token-externalization regression tests no longer match main's reverted design. - test/generate-openclaw-config.test.ts: removed the --clear-token test cases.
## Summary Refreshes user-facing docs for the last 24 hours of merged NemoClaw history and bumps the docs metadata to 0.0.29, the next version after v0.0.28. The updates are limited to behavior supported by merged PR descriptions and diffs. ## Changes - `docs/reference/commands.md`: documented `nemoclaw <name> policy-add --from-file` and `--from-dir`, including custom preset review guidance, from #2077 / commit `7720b175`. - `docs/deployment/deploy-to-remote-gpu.md`: clarified that non-loopback `CHAT_UI_URL` disables OpenClaw device pairing for remote browser-only deployments, from #2449 / commit `f5ee8a4d`. - `docs/inference/inference-options.md`: documented provider-aware credential retry validation and the NVIDIA-only `nvapi-` prefix check, from #2389 / commit `6f7f0c6d`. - `docs/inference/switch-inference-providers.md`: documented `NEMOCLAW_INFERENCE_INPUTS` for text/image-capable model metadata baked into `openclaw.json`, from #2441 / commit `f4391892`. - `docs/reference/troubleshooting.md`: added the Git certificate verification entry for proxy CA propagation through `GIT_SSL_CAINFO`, `GIT_SSL_CAPATH`, `CURL_CA_BUNDLE`, and `REQUESTS_CA_BUNDLE`, from #2345 / commit `fa0dc1ab`. - `docs/versions1.json` and `docs/project.json`: promoted docs version `0.0.29`; `docs/versions1.json` omits unpublished `0.0.26`, `0.0.27`, and `0.0.28` entries. - `.agents/skills/nemoclaw-user-*`: regenerated derived user skill references from the updated docs. - Reviewed with no extra doc changes: #2575 / `d392ec07`, #2565 / `a3231049`, #1965 / `db1ef3ca`, #1990 / `db665834`, #2495 / `7da86fa3`, #2496 / `3192f4f4`, #2490 / `8c209058`, #2487 / `1f615e2f`, #2483 / `5653d33a`, #2482 / `31c782c0`, #2464 / `23bb5703`, #2472 / `a54f9a34`, and #2437 / `6bc860d7`. - Skipped per docs policy: #2420 / `7b76df6b` touched the experimental sandbox config path listed in `docs/.docs-skip`; #2466 / `cc15689c` touched a skipped term and CI-only sandbox image files. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [x] Doc only (includes code sample changes) ## Verification <!-- Check each item you ran and confirmed. Leave unchecked items you skipped. --> - [x] `npx prek run --all-files` passes - [ ] `npm test` passes — failed locally in installer-integration tests and one onboard helper timeout; the doc-scoped hook test projects passed under `prek`. - [ ] Tests added or updated for new or changed behavior - [x] No secrets, API keys, or credentials committed - [x] Docs updated for user-facing behavior changes - [ ] `make docs` builds without warnings (doc changes only) — build succeeded, but local Sphinx emitted the existing version-switcher file read message. - [x] 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 <!-- If an AI agent authored or co-authored this PR, check the box and name the tool. Remove this section for fully human-authored PRs. --> - [x] AI-assisted — tool: Codex --- <!-- DCO sign-off required by CI. Run: git config user.name && git config user.email --> Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Support for custom YAML presets in policy configuration via --from-file and --from-dir. * New build-time inference input option to declare accepted modalities (text or text,image). * **Improvements** * Credential validation now offers interactive recovery: re-enter key, retry, choose another provider, or exit. * Clarified provider-specific API key prefix handling (nvapi- only applies to NVIDIA keys). * **Documentation** * TLS certificate troubleshooting for inspected networks. * Clarified remote dashboard security/device-pairing behavior; command docs updated; docs version bumped. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
…son (NVIDIA#2441) <!-- markdownlint-disable MD041 --> ## Summary The `NEMOCLAW_INFERENCE_INPUTS` variable is not sent all the way to the `openclaw.json` file (and thus the agent configuration). The `input` field in `models[0]` is hardcoded to `['text']` in the Dockerfile, so users who select a vision-capable model via `NEMOCLAW_MODEL` cannot tell OpenClaw that the model accepts image input. This extends NVIDIA#1956's plumbing pattern to cover the last remaining hardcoded inference field. ## Related Issue Fixes NVIDIA#2421 ## Changes - adds 1 ARG to the `Dockerfile` with default `text` (matching the previously-hardcoded value), promotes it to ENV, and the Python script reads from `os.environ` . - `patchStagedDockerfile()` in `onboard.ts` reads `NEMOCLAW_INFERENCE_INPUTS` from the host and patches the ARG line before image build, validated by regex `/^(text|image)(,(text|image))*$/` matching OpenClaw's `model.input` schema (`z.array(z.union([z.literal("text"), z.literal("image")]))`) - Unit tests to verify: positive case (`text,image` → baked) plus a 6-case reject table (`undefined / audio / text, / Text,Image / text, image / shell-injection attempt`) ## 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 <!-- Check each item you ran and confirmed. Leave unchecked items you skipped. --> - [ √] `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](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 - [ ] AI-assisted — tool: Cursor --- <!-- DCO sign-off required by CI. Run: git config user.name && git config user.email --> Signed-off-by: rluo8 <ruluo@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added build/runtime environment support to specify model input modalities (e.g., text, image) with a safe default of "text", enabling image-capable modal setups via env configuration. * Inputs are validated and parsed into a trimmed, comma-separated list before use. * **Tests** * Added regression tests for parsing and validation of the input-modality setting, covering valid multi-value inputs and malformed or injection-like values. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Rui Luo <ruluo@nvidia.com>
## Summary Refreshes user-facing docs for the last 24 hours of merged NemoClaw history and bumps the docs metadata to 0.0.29, the next version after v0.0.28. The updates are limited to behavior supported by merged PR descriptions and diffs. ## Changes - `docs/reference/commands.md`: documented `nemoclaw <name> policy-add --from-file` and `--from-dir`, including custom preset review guidance, from NVIDIA#2077 / commit `7720b175`. - `docs/deployment/deploy-to-remote-gpu.md`: clarified that non-loopback `CHAT_UI_URL` disables OpenClaw device pairing for remote browser-only deployments, from NVIDIA#2449 / commit `f5ee8a4d`. - `docs/inference/inference-options.md`: documented provider-aware credential retry validation and the NVIDIA-only `nvapi-` prefix check, from NVIDIA#2389 / commit `6f7f0c6d`. - `docs/inference/switch-inference-providers.md`: documented `NEMOCLAW_INFERENCE_INPUTS` for text/image-capable model metadata baked into `openclaw.json`, from NVIDIA#2441 / commit `f4391892`. - `docs/reference/troubleshooting.md`: added the Git certificate verification entry for proxy CA propagation through `GIT_SSL_CAINFO`, `GIT_SSL_CAPATH`, `CURL_CA_BUNDLE`, and `REQUESTS_CA_BUNDLE`, from NVIDIA#2345 / commit `fa0dc1ab`. - `docs/versions1.json` and `docs/project.json`: promoted docs version `0.0.29`; `docs/versions1.json` omits unpublished `0.0.26`, `0.0.27`, and `0.0.28` entries. - `.agents/skills/nemoclaw-user-*`: regenerated derived user skill references from the updated docs. - Reviewed with no extra doc changes: NVIDIA#2575 / `d392ec07`, NVIDIA#2565 / `a3231049`, NVIDIA#1965 / `db1ef3ca`, NVIDIA#1990 / `db665834`, NVIDIA#2495 / `7da86fa3`, NVIDIA#2496 / `3192f4f4`, NVIDIA#2490 / `8c209058`, NVIDIA#2487 / `1f615e2f`, NVIDIA#2483 / `5653d33a`, NVIDIA#2482 / `31c782c0`, NVIDIA#2464 / `23bb5703`, NVIDIA#2472 / `a54f9a34`, and NVIDIA#2437 / `6bc860d7`. - Skipped per docs policy: NVIDIA#2420 / `7b76df6b` touched the experimental sandbox config path listed in `docs/.docs-skip`; NVIDIA#2466 / `cc15689c` touched a skipped term and CI-only sandbox image files. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [x] Doc only (includes code sample changes) ## Verification <!-- Check each item you ran and confirmed. Leave unchecked items you skipped. --> - [x] `npx prek run --all-files` passes - [ ] `npm test` passes — failed locally in installer-integration tests and one onboard helper timeout; the doc-scoped hook test projects passed under `prek`. - [ ] Tests added or updated for new or changed behavior - [x] No secrets, API keys, or credentials committed - [x] Docs updated for user-facing behavior changes - [ ] `make docs` builds without warnings (doc changes only) — build succeeded, but local Sphinx emitted the existing version-switcher file read message. - [x] 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 <!-- If an AI agent authored or co-authored this PR, check the box and name the tool. Remove this section for fully human-authored PRs. --> - [x] AI-assisted — tool: Codex --- <!-- DCO sign-off required by CI. Run: git config user.name && git config user.email --> Signed-off-by: Miyoung Choi <miyoungc@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Support for custom YAML presets in policy configuration via --from-file and --from-dir. * New build-time inference input option to declare accepted modalities (text or text,image). * **Improvements** * Credential validation now offers interactive recovery: re-enter key, retry, choose another provider, or exit. * Clarified provider-specific API key prefix handling (nvapi- only applies to NVIDIA keys). * **Documentation** * TLS certificate troubleshooting for inspected networks. * Clarified remote dashboard security/device-pairing behavior; command docs updated; docs version bumped. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
Summary
The
NEMOCLAW_INFERENCE_INPUTSvariable is not sent all the way to theopenclaw.jsonfile (and thus the agent configuration). Theinputfield inmodels[0]is hardcoded to['text']in the Dockerfile, so users who select a vision-capable model viaNEMOCLAW_MODELcannot tell OpenClaw that the model accepts image input. This extends #1956's plumbing pattern to cover the last remaining hardcoded inference field.Related Issue
Fixes #2421
Changes
Dockerfilewith defaulttext(matching the previously-hardcoded value), promotes it to ENV, and the Python script reads fromos.environ.patchStagedDockerfile()inonboard.tsreadsNEMOCLAW_INFERENCE_INPUTSfrom the host and patches the ARG line before image build, validated by regex/^(text|image)(,(text|image))*$/matching OpenClaw'smodel.inputschema (z.array(z.union([z.literal("text"), z.literal("image")])))text,image→ baked) plus a 6-case reject table (undefined / audio / text, / Text,Image / text, image / shell-injection attempt)Type of Change
Verification
npx prek run --all-filespassesnpm testpassesmake docsbuilds without warnings (doc changes only)AI Disclosure
Signed-off-by: rluo8 ruluo@nvidia.com
Summary by CodeRabbit
New Features
Tests