feat(sandbox): install provider access tools#3747
Conversation
📝 WalkthroughWalkthroughThis PR adds provider profile support to NemoClaw, enabling agents to request dynamic resource access through OpenShell's policy service. It includes ten provider profile definitions, a complete access-client module for request submission, three new OpenClaw plugin tools, policy integration for provider profile loading, and onboarding provisioning with comprehensive test coverage. ChangesNemoClaw OpenShell Access Integration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Suggested labels
Suggested reviewers
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)
⚔️ Resolve merge conflicts
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Comment |
|
✨ Thanks for submitting this detailed PR to enhance the sandbox environment by installing provider-oriented CLI tools and making the NemoClaw OpenClaw plugin available. This change aims to improve the usability and functionality of the sandbox image by aligning it with the provider profile policy surface. |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (4)
Dockerfile (1)
62-66: Run the container E2E suite for plugin/tooling runtime validation.Given this changes runtime image composition and plugin load paths, run
cloud-e2e,sandbox-survival-e2e,hermes-e2e, andrebuild-openclaw-e2e.As per coding guidelines,
Dockerfilechanges “affect the sandbox container image” and are “only testable with a real container build,” with those E2E jobs recommended.Also applies to: 254-255
🤖 Prompt for 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. In `@Dockerfile` around lines 62 - 66, This change modifies the runtime image by installing provider tools via the RUN step that executes /usr/local/lib/nemoclaw/install-provider-tools.sh, so validate the new image by running the recommended container E2E suites: cloud-e2e, sandbox-survival-e2e, hermes-e2e, and rebuild-openclaw-e2e (also verify the other related RUN change at the second occurrence of the same install step). Ensure each job runs against a real container build of this Dockerfile and report any failures back with the failing job logs and the exact container image digest.Dockerfile.base (1)
75-77: Run the sandbox image E2E matrix for this Docker base-layer change.Please run
cloud-e2e,sandbox-survival-e2e,hermes-e2e, andrebuild-openclaw-e2ebefore merge to validate runtime behavior after base image toolchain changes.As per coding guidelines,
Dockerfile.base“affects the sandbox container image” and these changes are “only testable with a real container build,” with the listed E2E jobs recommended.🤖 Prompt for 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. In `@Dockerfile.base` around lines 75 - 77, This change adds COPY and execution of scripts/install-provider-tools.sh in Dockerfile.base (the COPY line and the RUN invoking /usr/local/lib/nemoclaw/install-provider-tools.sh), which modifies the sandbox base image toolchain; before merging, build the container and run the full sandbox image E2E matrix: execute cloud-e2e, sandbox-survival-e2e, hermes-e2e, and rebuild-openclaw-e2e against the new base image build to validate runtime behavior and ensure the provider tools script causes no regressions.docs/reference/nemoclaw-openshell-integration.md (1)
1-73: ⚡ Quick winComplete required docs page structure for a new
docs/**page.This page is missing required frontmatter fields, a brief opening introduction, and a bottom Next Steps section with related links.
As per coding guidelines, for
docs/**new pages: "Frontmatter includes title, description, keywords, topics, tags, content type, difficulty, audience, and status fields", "Page starts with a one- or two-sentence introduction", and "A 'Next Steps' section at the bottom links to related pages."🤖 Prompt for 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. In `@docs/reference/nemoclaw-openshell-integration.md` around lines 1 - 73, The page "NemoClaw OpenShell Integration" is missing required frontmatter, a short intro, and a "Next Steps" section; add YAML frontmatter containing title, description, keywords, topics, tags, content_type, difficulty, audience, and status at the top of the file, prepend a one- or two-sentence introduction paragraph under the main heading summarizing the page purpose, and append a "Next Steps" section at the bottom linking to related docs (e.g., pages about onboarding, policy.local, adapter contracts or provider profiles) and any follow-up actions; ensure the existing mermaid diagram and section headings (Flow, Agent Tools, Adapter Contract, Provider Profiles) remain unchanged and the new frontmatter fields match the repository's docs schema.src/lib/onboard.ts (1)
9751-9751: Run onboarding E2E coverage for this integration point.Since this changes
src/lib/onboard.tscore flow, please run the recommended onboarding E2E jobs before merge to validate gateway/sandbox lifecycle behavior with provider profile provisioning.As per coding guidelines
src/lib/onboard.ts: “This file contains core onboarding logic... E2E test recommendation: cloud-e2e, sandbox-operations-e2e, rebuild-openclaw-e2e, channels-stop-start-e2e, messaging-compatible-endpoint-e2e, hermes-discord-e2e, hermes-slack-e2e, openshell-gateway-upgrade-e2e.”🤖 Prompt for 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. In `@src/lib/onboard.ts` at line 9751, This change touches the core onboarding flow at ensureProviderProfilesAvailable() in src/lib/onboard.ts, so before merging run the recommended E2E suites to validate gateway/sandbox lifecycle and provider profile provisioning: cloud-e2e, sandbox-operations-e2e, rebuild-openclaw-e2e, channels-stop-start-e2e, messaging-compatible-endpoint-e2e, hermes-discord-e2e, hermes-slack-e2e, and openshell-gateway-upgrade-e2e; if any test fails, capture logs around ensureProviderProfilesAvailable() and provider profile provisioning, fix the failing behavior, and re-run until all pass.
🤖 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 `@docs/reference/nemoclaw-openshell-integration.md`:
- Line 1: Add the required SPDX license header to the top of the Markdown file
docs/reference/nemoclaw-openshell-integration.md by inserting the SPDX copyright
and license lines as a header block (e.g., an HTML comment or plain text)
including "SPDX-FileCopyrightText: <YEAR> <OWNER>" and "SPDX-License-Identifier:
Apache-2.0" as the first lines of the file so the document complies with the
repository rule for *.{md,mdx} files.
In `@nemoclaw-blueprint/provider-profiles/brew.yaml`:
- Around line 12-32: The entries for public hosts (host: github.com, ghcr.io,
pkg-containers.githubusercontent.com, objects.githubusercontent.com,
raw.githubusercontent.com) currently set tls: skip; remove or change those tls
settings so normal TLS verification is enforced (e.g., delete the tls: skip
lines or set tls: verify) for each listed host in the provider profile to
restore proper transport security and policy guarantees.
In `@nemoclaw-blueprint/provider-profiles/npm.yaml`:
- Around line 11-16: Replace the insecure "tls: skip" setting for the external
registry entry (the block containing host: registry.yarnpkg.com and tls: skip)
so TLS verification is enabled by default; remove the tls: skip line or change
it to an affirmative verification setting (e.g., tls: verify or tls: true) in
the provider profile that contains the npm registry configuration to ensure
package registry traffic performs TLS certificate validation.
In `@nemoclaw/src/access-client.ts`:
- Around line 396-401: The loop over listProviderProfilePresets() currently
keeps the built-in preset on name collisions and only copies provider_profile,
which loses provider-sourced endpoints/binaries; change the collision branch in
that loop (the byName.set call where existing is checked) to merge the records
so the incoming preset's provider-sourced fields override the existing entry
(e.g., preserve any other existing metadata but copy
preset.endpoint/binaries/provider_profile/etc. from preset), ensuring
provider-supplied endpoints/binaries are used for overlapping names; locate this
logic around listProviderProfilePresets(), the byName map, and the
existing/preset variables and update the merge strategy accordingly.
In `@src/lib/onboard.ts`:
- Around line 1795-1805: The new helper function ensureProviderProfilesAvailable
in src/lib/onboard.ts causes net growth and breaks the onboard-entrypoint
budget; remove this local helper and either inline its minimal behavior at the
original call site or move it into a separate smaller module so onboard.ts
shrinks. Specifically, replace calls to ensureProviderProfilesAvailable with the
explicit call to
providerProfileOnboard.ensureNemoClawProviderProfiles(runOpenshell, { log: note
}) followed by the same branching on result.status and the
policies.clearProviderProfileCache() call (or export a tiny helper from a new
module and import it), preserving use of symbols
providerProfileOnboard.ensureNemoClawProviderProfiles, runOpenshell, note, and
policies.clearProviderProfileCache.
In `@src/lib/onboard/provider-profiles.ts`:
- Around line 116-123: The current branch always returns status:"unsupported"
whenever `list.status !== 0`; change this so you only return the unsupported
payload when the `list.stdout`/`list.stderr` explicitly indicate the
"unsupported command" signals from the `list-profiles` invocation, and for any
other non-zero exit produce a thrown Error (or rethrow) that includes
`list.status`, `list.stdout`, and `list.stderr` so callers can see
runtime/transient failures; locate the check on `list.status` in
provider-profiles.ts and replace the unconditional return with an explicit
pattern-match for the unsupported-case and an error throw containing
stdout/stderr for all other failures.
In `@test/e2e/test-nemoclaw-policy-local-plugin.sh`:
- Around line 25-29: Before setting the global OpenShell setting, read and store
the current value of agent_policy_proposals_enabled (use "${OPENSHELL_BIN}
settings get --global --key agent_policy_proposals_enabled") into a variable
(e.g., prior_agent_policy_proposals_enabled), then keep that variable in the
script scope and in the cleanup function restore it by calling "${OPENSHELL_BIN}
settings set --global --key agent_policy_proposals_enabled --value
<stored_value> --yes"; ensure the cleanup function (cleanup) is registered to
run on exit (trap) so the original global setting is always reverted.
---
Nitpick comments:
In `@Dockerfile`:
- Around line 62-66: This change modifies the runtime image by installing
provider tools via the RUN step that executes
/usr/local/lib/nemoclaw/install-provider-tools.sh, so validate the new image by
running the recommended container E2E suites: cloud-e2e, sandbox-survival-e2e,
hermes-e2e, and rebuild-openclaw-e2e (also verify the other related RUN change
at the second occurrence of the same install step). Ensure each job runs against
a real container build of this Dockerfile and report any failures back with the
failing job logs and the exact container image digest.
In `@Dockerfile.base`:
- Around line 75-77: This change adds COPY and execution of
scripts/install-provider-tools.sh in Dockerfile.base (the COPY line and the RUN
invoking /usr/local/lib/nemoclaw/install-provider-tools.sh), which modifies the
sandbox base image toolchain; before merging, build the container and run the
full sandbox image E2E matrix: execute cloud-e2e, sandbox-survival-e2e,
hermes-e2e, and rebuild-openclaw-e2e against the new base image build to
validate runtime behavior and ensure the provider tools script causes no
regressions.
In `@docs/reference/nemoclaw-openshell-integration.md`:
- Around line 1-73: The page "NemoClaw OpenShell Integration" is missing
required frontmatter, a short intro, and a "Next Steps" section; add YAML
frontmatter containing title, description, keywords, topics, tags, content_type,
difficulty, audience, and status at the top of the file, prepend a one- or
two-sentence introduction paragraph under the main heading summarizing the page
purpose, and append a "Next Steps" section at the bottom linking to related docs
(e.g., pages about onboarding, policy.local, adapter contracts or provider
profiles) and any follow-up actions; ensure the existing mermaid diagram and
section headings (Flow, Agent Tools, Adapter Contract, Provider Profiles) remain
unchanged and the new frontmatter fields match the repository's docs schema.
In `@src/lib/onboard.ts`:
- Line 9751: This change touches the core onboarding flow at
ensureProviderProfilesAvailable() in src/lib/onboard.ts, so before merging run
the recommended E2E suites to validate gateway/sandbox lifecycle and provider
profile provisioning: cloud-e2e, sandbox-operations-e2e, rebuild-openclaw-e2e,
channels-stop-start-e2e, messaging-compatible-endpoint-e2e, hermes-discord-e2e,
hermes-slack-e2e, and openshell-gateway-upgrade-e2e; if any test fails, capture
logs around ensureProviderProfilesAvailable() and provider profile provisioning,
fix the failing behavior, and re-run until all pass.
🪄 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: ce55ad0d-df47-4506-866b-9bde0e16e1d0
📒 Files selected for processing (33)
DockerfileDockerfile.basedocs/reference/nemoclaw-openshell-integration.mdnemoclaw-blueprint/policies/presets/github.yamlnemoclaw-blueprint/provider-profiles/brave.yamlnemoclaw-blueprint/provider-profiles/brew.yamlnemoclaw-blueprint/provider-profiles/discord.yamlnemoclaw-blueprint/provider-profiles/huggingface.yamlnemoclaw-blueprint/provider-profiles/jira.yamlnemoclaw-blueprint/provider-profiles/local-inference.yamlnemoclaw-blueprint/provider-profiles/npm.yamlnemoclaw-blueprint/provider-profiles/pypi.yamlnemoclaw-blueprint/provider-profiles/slack.yamlnemoclaw-blueprint/provider-profiles/telegram.yamlnemoclaw/src/access-client.test.tsnemoclaw/src/access-client.tsnemoclaw/src/index.tsnemoclaw/src/onboard/config.test.tsnemoclaw/src/onboard/config.tsnemoclaw/src/register.test.tsscripts/generate-openclaw-config.pyscripts/install-provider-tools.shsrc/lib/onboard.tssrc/lib/onboard/provider-profiles.tssrc/lib/policy/index.tssrc/lib/sandbox/build-context.tstest/e2e/nemoclaw-policy-local-runner.mjstest/e2e/test-nemoclaw-policy-local-plugin.shtest/generate-openclaw-config.test.tstest/policies.test.tstest/provider-profile-onboard.test.tstest/sandbox-build-context.test.tstest/validate-blueprint.test.ts
| @@ -0,0 +1,72 @@ | |||
| # NemoClaw OpenShell Integration | |||
There was a problem hiding this comment.
Add the required SPDX license header at the top of this page.
This new Markdown file is missing the required SPDX copyright and Apache-2.0 header.
As per coding guidelines, "**/*.{js,ts,tsx,jsx,sh,yaml,yml,json,md,mdx}: Every source file must include an SPDX license header for copyright and Apache-2.0 license".
🤖 Prompt for 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.
In `@docs/reference/nemoclaw-openshell-integration.md` at line 1, Add the required
SPDX license header to the top of the Markdown file
docs/reference/nemoclaw-openshell-integration.md by inserting the SPDX copyright
and license lines as a header block (e.g., an HTML comment or plain text)
including "SPDX-FileCopyrightText: <YEAR> <OWNER>" and "SPDX-License-Identifier:
Apache-2.0" as the first lines of the file so the document complies with the
repository rule for *.{md,mdx} files.
| tls: skip | ||
| - host: github.com | ||
| port: 443 | ||
| access: full | ||
| tls: skip | ||
| - host: ghcr.io | ||
| port: 443 | ||
| access: full | ||
| tls: skip | ||
| - host: pkg-containers.githubusercontent.com | ||
| port: 443 | ||
| access: full | ||
| tls: skip | ||
| - host: objects.githubusercontent.com | ||
| port: 443 | ||
| access: full | ||
| tls: skip | ||
| - host: raw.githubusercontent.com | ||
| port: 443 | ||
| access: full | ||
| tls: skip |
There was a problem hiding this comment.
Do not skip TLS verification on public endpoints.
Using tls: skip across public hosts weakens transport security and policy guarantees. Please require normal TLS verification unless there is a narrowly justified exception.
Suggested change
- host: formulae.brew.sh
port: 443
access: full
- tls: skip
- host: github.com
port: 443
access: full
- tls: skip
- host: ghcr.io
port: 443
access: full
- tls: skip
- host: pkg-containers.githubusercontent.com
port: 443
access: full
- tls: skip
- host: objects.githubusercontent.com
port: 443
access: full
- tls: skip
- host: raw.githubusercontent.com
port: 443
access: full
- tls: skip🤖 Prompt for 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.
In `@nemoclaw-blueprint/provider-profiles/brew.yaml` around lines 12 - 32, The
entries for public hosts (host: github.com, ghcr.io,
pkg-containers.githubusercontent.com, objects.githubusercontent.com,
raw.githubusercontent.com) currently set tls: skip; remove or change those tls
settings so normal TLS verification is enforced (e.g., delete the tls: skip
lines or set tls: verify) for each listed host in the provider profile to
restore proper transport security and policy guarantees.
| access: full | ||
| tls: skip | ||
| - host: registry.yarnpkg.com | ||
| port: 443 | ||
| access: full | ||
| tls: skip |
There was a problem hiding this comment.
Avoid tls: skip for package registry traffic.
This disables TLS verification for external registries and weakens secure-by-default behavior. Please keep TLS verification enabled.
Suggested change
- host: registry.npmjs.org
port: 443
access: full
- tls: skip
- host: registry.yarnpkg.com
port: 443
access: full
- tls: skip📝 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.
| access: full | |
| tls: skip | |
| - host: registry.yarnpkg.com | |
| port: 443 | |
| access: full | |
| tls: skip | |
| access: full | |
| - host: registry.yarnpkg.com | |
| port: 443 | |
| access: full |
🤖 Prompt for 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.
In `@nemoclaw-blueprint/provider-profiles/npm.yaml` around lines 11 - 16, Replace
the insecure "tls: skip" setting for the external registry entry (the block
containing host: registry.yarnpkg.com and tls: skip) so TLS verification is
enabled by default; remove the tls: skip line or change it to an affirmative
verification setting (e.g., tls: verify or tls: true) in the provider profile
that contains the npm registry configuration to ensure package registry traffic
performs TLS certificate validation.
| for (const preset of listProviderProfilePresets()) { | ||
| const existing = byName.get(preset.name); | ||
| byName.set( | ||
| preset.name, | ||
| existing ? { ...existing, provider_profile: preset.provider_profile } : preset, | ||
| ); |
There was a problem hiding this comment.
Provider-profile preset data is ignored on name collisions.
On Line 400, when names collide, the code keeps the built-in preset rule and only copies provider_profile. That means provider-sourced endpoints/binaries are not used in access proposals for overlapping presets (for example github), which breaks alignment with provider profile policy surface.
Suggested fix
- byName.set(
- preset.name,
- existing ? { ...existing, provider_profile: preset.provider_profile } : preset,
- );
+ byName.set(
+ preset.name,
+ existing
+ ? {
+ ...existing,
+ ...preset,
+ rule: preset.rule,
+ provider_profile: preset.provider_profile,
+ }
+ : preset,
+ );📝 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.
| for (const preset of listProviderProfilePresets()) { | |
| const existing = byName.get(preset.name); | |
| byName.set( | |
| preset.name, | |
| existing ? { ...existing, provider_profile: preset.provider_profile } : preset, | |
| ); | |
| for (const preset of listProviderProfilePresets()) { | |
| const existing = byName.get(preset.name); | |
| byName.set( | |
| preset.name, | |
| existing | |
| ? { | |
| ...existing, | |
| ...preset, | |
| rule: preset.rule, | |
| provider_profile: preset.provider_profile, | |
| } | |
| : preset, | |
| ); |
🤖 Prompt for 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.
In `@nemoclaw/src/access-client.ts` around lines 396 - 401, The loop over
listProviderProfilePresets() currently keeps the built-in preset on name
collisions and only copies provider_profile, which loses provider-sourced
endpoints/binaries; change the collision branch in that loop (the byName.set
call where existing is checked) to merge the records so the incoming preset's
provider-sourced fields override the existing entry (e.g., preserve any other
existing metadata but copy preset.endpoint/binaries/provider_profile/etc. from
preset), ensuring provider-supplied endpoints/binaries are used for overlapping
names; locate this logic around listProviderProfilePresets(), the byName map,
and the existing/preset variables and update the merge strategy accordingly.
| function ensureProviderProfilesAvailable(): void { | ||
| const result = providerProfileOnboard.ensureNemoClawProviderProfiles(runOpenshell, { | ||
| log: note, | ||
| }); | ||
| if (result.status === "unsupported") { | ||
| note(` ${result.message}`); | ||
| } else if (result.status === "already-present" && result.skipped.length > 0) { | ||
| note(` NemoClaw provider profiles already registered: ${result.skipped.join(", ")}`); | ||
| } | ||
| policies.clearProviderProfileCache(); | ||
| } |
There was a problem hiding this comment.
CI blocker: onboarding entrypoint budget fails with this helper addition.
Line 1795-1805 introduces net growth in src/lib/onboard.ts, and CI is already failing the onboard-entrypoint budget (+16 lines). Please move this logic out of onboard.ts (or inline minimally) to get back under budget.
Proposed trim (remove local helper, keep behavior at call site)
-function ensureProviderProfilesAvailable(): void {
- const result = providerProfileOnboard.ensureNemoClawProviderProfiles(runOpenshell, {
- log: note,
- });
- if (result.status === "unsupported") {
- note(` ${result.message}`);
- } else if (result.status === "already-present" && result.skipped.length > 0) {
- note(` NemoClaw provider profiles already registered: ${result.skipped.join(", ")}`);
- }
- policies.clearProviderProfileCache();
-}- ensureProviderProfilesAvailable();
+ const providerProfilesResult = providerProfileOnboard.ensureNemoClawProviderProfiles(runOpenshell, { log: note });
+ if (providerProfilesResult.status === "unsupported") {
+ note(` ${providerProfilesResult.message}`);
+ } else if (providerProfilesResult.status === "already-present" && providerProfilesResult.skipped.length > 0) {
+ note(` NemoClaw provider profiles already registered: ${providerProfilesResult.skipped.join(", ")}`);
+ }
+ policies.clearProviderProfileCache();📝 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.
| function ensureProviderProfilesAvailable(): void { | |
| const result = providerProfileOnboard.ensureNemoClawProviderProfiles(runOpenshell, { | |
| log: note, | |
| }); | |
| if (result.status === "unsupported") { | |
| note(` ${result.message}`); | |
| } else if (result.status === "already-present" && result.skipped.length > 0) { | |
| note(` NemoClaw provider profiles already registered: ${result.skipped.join(", ")}`); | |
| } | |
| policies.clearProviderProfileCache(); | |
| } |
| function ensureProviderProfilesAvailable(): void { | |
| const result = providerProfileOnboard.ensureNemoClawProviderProfiles(runOpenshell, { | |
| log: note, | |
| }); | |
| if (result.status === "unsupported") { | |
| note(` ${result.message}`); | |
| } else if (result.status === "already-present" && result.skipped.length > 0) { | |
| note(` NemoClaw provider profiles already registered: ${result.skipped.join(", ")}`); | |
| } | |
| policies.clearProviderProfileCache(); | |
| } | |
| const providerProfilesResult = providerProfileOnboard.ensureNemoClawProviderProfiles(runOpenshell, { log: note }); | |
| if (providerProfilesResult.status === "unsupported") { | |
| note(` ${providerProfilesResult.message}`); | |
| } else if (providerProfilesResult.status === "already-present" && providerProfilesResult.skipped.length > 0) { | |
| note(` NemoClaw provider profiles already registered: ${providerProfilesResult.skipped.join(", ")}`); | |
| } | |
| policies.clearProviderProfileCache(); |
🤖 Prompt for 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.
In `@src/lib/onboard.ts` around lines 1795 - 1805, The new helper function
ensureProviderProfilesAvailable in src/lib/onboard.ts causes net growth and
breaks the onboard-entrypoint budget; remove this local helper and either inline
its minimal behavior at the original call site or move it into a separate
smaller module so onboard.ts shrinks. Specifically, replace calls to
ensureProviderProfilesAvailable with the explicit call to
providerProfileOnboard.ensureNemoClawProviderProfiles(runOpenshell, { log: note
}) followed by the same branching on result.status and the
policies.clearProviderProfileCache() call (or export a tiny helper from a new
module and import it), preserving use of symbols
providerProfileOnboard.ensureNemoClawProviderProfiles, runOpenshell, note, and
policies.clearProviderProfileCache.
| if (list.status !== 0) { | ||
| return { | ||
| status: "unsupported", | ||
| imported: [], | ||
| skipped: [], | ||
| message: "OpenShell provider profiles are not available; using local preset fallbacks.", | ||
| }; | ||
| } |
There was a problem hiding this comment.
Do not treat every list failure as “unsupported.”
Line 116 currently downgrades all list-profiles failures to unsupported, which can hide transient/runtime failures and silently skip provider-profile sync. Only return unsupported when the output matches unsupported-command signals; otherwise throw with stderr/stdout details.
Suggested fix
if (list.status !== 0) {
- return {
- status: "unsupported",
- imported: [],
- skipped: [],
- message: "OpenShell provider profiles are not available; using local preset fallbacks.",
- };
+ if (isUnsupportedProviderProfileCommand(list)) {
+ return {
+ status: "unsupported",
+ imported: [],
+ skipped: [],
+ message: "OpenShell provider profiles are not available; using local preset fallbacks.",
+ };
+ }
+ const details =
+ outputText(list.stderr) || outputText(list.stdout) || "provider list-profiles failed";
+ throw new Error(`NemoClaw provider profile discovery failed: ${details.trim()}`);
}📝 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.
| if (list.status !== 0) { | |
| return { | |
| status: "unsupported", | |
| imported: [], | |
| skipped: [], | |
| message: "OpenShell provider profiles are not available; using local preset fallbacks.", | |
| }; | |
| } | |
| if (list.status !== 0) { | |
| if (isUnsupportedProviderProfileCommand(list)) { | |
| return { | |
| status: "unsupported", | |
| imported: [], | |
| skipped: [], | |
| message: "OpenShell provider profiles are not available; using local preset fallbacks.", | |
| }; | |
| } | |
| const details = | |
| outputText(list.stderr) || outputText(list.stdout) || "provider list-profiles failed"; | |
| throw new Error(`NemoClaw provider profile discovery failed: ${details.trim()}`); | |
| } |
🤖 Prompt for 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.
In `@src/lib/onboard/provider-profiles.ts` around lines 116 - 123, The current
branch always returns status:"unsupported" whenever `list.status !== 0`; change
this so you only return the unsupported payload when the
`list.stdout`/`list.stderr` explicitly indicate the "unsupported command"
signals from the `list-profiles` invocation, and for any other non-zero exit
produce a thrown Error (or rethrow) that includes `list.status`, `list.stdout`,
and `list.stderr` so callers can see runtime/transient failures; locate the
check on `list.status` in provider-profiles.ts and replace the unconditional
return with an explicit pattern-match for the unsupported-case and an error
throw containing stdout/stderr for all other failures.
| "${OPENSHELL_BIN}" settings set --global \ | ||
| --key agent_policy_proposals_enabled \ | ||
| --value true \ | ||
| --yes | ||
|
|
There was a problem hiding this comment.
Restore global OpenShell settings in cleanup.
Line 25 updates agent_policy_proposals_enabled globally, but the previous value is never restored. This can leak state into later runs and cause flaky e2e behavior. Please capture the prior value before mutation and revert it in cleanup.
🤖 Prompt for 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.
In `@test/e2e/test-nemoclaw-policy-local-plugin.sh` around lines 25 - 29, Before
setting the global OpenShell setting, read and store the current value of
agent_policy_proposals_enabled (use "${OPENSHELL_BIN} settings get --global
--key agent_policy_proposals_enabled") into a variable (e.g.,
prior_agent_policy_proposals_enabled), then keep that variable in the script
scope and in the cleanup function restore it by calling "${OPENSHELL_BIN}
settings set --global --key agent_policy_proposals_enabled --value
<stored_value> --yes"; ensure the cleanup function (cleanup) is registered to
run on exit (trap) so the original global setting is always reverted.
cv
left a comment
There was a problem hiding this comment.
Reviewed with the PR review advisor rubric (static patch review only; not evaluating CI/mergeability). Requesting changes as this PR is currently opened against main and includes the lower stack blockers:
- Provider profile import still treats every non-zero
openshell provider list-profiles -o jsonas unsupported (src/lib/onboard/provider-profiles.ts:116). Real OpenShell/runtime failures should not be hidden as compatibility fallback. - Provider profile endpoint ports are accepted with
Number(endpoint.port) <= 0in both the policy layer and plugin client paths, allowingNaNto be serialized into generated policy/proposals. - The OpenClaw access client hardcodes proxy requests to
http://policy.local:80..., ignoring configuredOPENSHELL_POLICY_LOCAL_URLport/host in proxy mode. - URL resource normalization only maps GitHub hosts to preset ids, so non-GitHub URLs can be transformed into unknown ids that
list_presetsnever returns.
Incremental note for this PR: scripts/install-provider-tools.sh:35 installs third-party npm CLIs globally as root during the image build. Versions are pinned, which is good, but package lifecycle scripts still execute. Please either use --ignore-scripts where compatible or document/test why lifecycle scripts are required and trusted for these packages.
If this PR is intended to be reviewed as only the sandbox-tool layer, retarget it onto the parent PR after the lower-layer fixes land; as submitted against main, these blockers are in this PR's diff.
Summary
Installs the provider-oriented CLI tools that provider profiles expose, and makes the NemoClaw OpenClaw plugin available from the sandbox image. This keeps the sandbox image aligned with the provider profile policy surface while OpenShell approval still controls network and credential use.
Changes
scripts/install-provider-tools.shfor pinnedgh,glab,jq,claude,codex,opencode, andcopilotsetup.Dockerfile.base,Dockerfile, and optimized sandbox build context staging./usr/local/share/nemoclaw/openclaw-plugins/nemoclaw.Type of Change
Verification
npx prek run --all-filespassesnpm testpassesmake docsbuilds without warnings (doc changes only)Signed-off-by: Patrick Riel priel@nvidia.com
Summary by CodeRabbit
New Features
gh) support.Documentation
Bug Fixes
Chores