feat(whatsapp): add WhatsApp channel support for sandbox onboarding#2025
feat(whatsapp): add WhatsApp channel support for sandbox onboarding#2025paritoshd-nv wants to merge 1 commit into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds WhatsApp channel support: new policy preset and tier entry, onboarding QR-pairing flow and dashboard output, sandbox provider teardown update, Dockerfile build-time logic to enable and optionally patch OpenClaw’s WhatsApp plugin for HTTPS proxying, and corresponding tests and validations. Changes
Sequence DiagramsequenceDiagram
actor User
participant Onboard as Onboarding
participant Policy as Policy Engine
participant Docker as Docker Build
participant OpenClaw as OpenClaw Runtime
participant Proxy as Network/Proxy
User->>Onboard: select "whatsapp" channel
Onboard->>Policy: request suggested presets
Policy-->>Onboard: include "whatsapp" preset
Onboard->>User: show QR pairing instructions
User->>Docker: build sandbox with WhatsApp enabled
Docker->>OpenClaw: enable plugin path in openclaw.json
Docker->>OpenClaw: (if root & target found) patch session-*.js to use HttpsProxyAgent when HTTPS_PROXY
OpenClaw->>Proxy: initiate wss / noise / rest connections per policies
Proxy-->>OpenClaw: proxy handshake (HTTP/1.1 required for WebSocket)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 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.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Dockerfile`:
- Around line 259-265: The current RUN block computes WA_ENABLED and, when
WhatsApp is selected, silently skips plugin registration if the bundled
extension path (WA_EXT) or its openclaw.plugin.json is missing; change the logic
so that when WA_ENABLED is 1 and the check [ -d "$WA_EXT" ] && [ -f
"$WA_EXT/openclaw.plugin.json" ] fails, the build exits non‑zero (e.g., echo an
error to stderr and run exit 1) instead of printing a benign message—update the
else branch in the WA_EXT existence check to fail the build and include the
path/filename (WA_EXT and openclaw.plugin.json) in the error for clarity.
- Around line 289-300: If WhatsApp is enabled (WA_ENABLED) and a chunk is found
(WA_CHUNK) but the patch verification after the sed command fails, the current
`|| echo "ERROR: Patch verification failed"` path still returns exit code 0 and
allows the image to build; change that to fail the build: after running the sed
and the grep verification (the lines referencing sed -i on "$WA_CHUNK" and grep
-q 'HttpsProxyAgent' "$WA_CHUNK"), ensure the failure path exits non‑zero (for
example replace the final `|| echo "ERROR: Patch verification failed"` with a
construct that writes the error to stderr and exits 1) so that when WA_ENABLED
is 1 and verification fails the Docker build layer fails.
In `@src/lib/onboard.ts`:
- Around line 3203-3210: The code currently adds "whatsapp" to
activeMessagingChannels but doesn't force a sandbox rebuild when an existing
sandbox was created without WhatsApp; modify the onboarding logic so that when
Array.isArray(enabledChannels) && enabledChannels.includes("whatsapp") &&
!activeMessagingChannels.includes("whatsapp") you not only push "whatsapp" onto
activeMessagingChannels but also set the flag that prevents reuse (e.g., set
reuseSandbox = false or set a needsRecreate variable) so the Dockerfile/patch
step runs; update both occurrences referenced (the block using
enabledChannels/activeMessagingChannels at lines around the shown diff and the
similar block at the other location) to ensure a recreate is forced when
WhatsApp is newly enabled.
In `@src/nemoclaw.ts`:
- Around line 1632-1633: The provider cleanup loop uses a hard-coded suffix list
in the for-loop where runOpenshell(["provider", "delete",
`${sandboxName}-${suffix}`], ...) is called; update that suffix list to match
the exact providers created during onboarding (including "slack-app" and any new
"whatsapp-bridge" if onboarding creates it) so the cleanup deletes
`${sandboxName}-slack-app` as well; locate the loop with runOpenshell and
sandboxName in src/nemoclaw.ts and adjust the array to include "slack-app" (and
remove any stale/mismatched entries) so all credential providers created by
src/lib/onboard.ts are cleaned up.
In `@test/validate-blueprint.test.ts`:
- Around line 355-356: The Endpoint type is missing the enforcement property
which causes a TS type mismatch when code accesses ep!.enforcement; update the
Endpoint type definition (symbol: Endpoint) to include enforcement?: string (or
the appropriate type used by whatsapp.yaml) so consumers like the code that
accesses ep!.enforcement compile under strict mode; ensure any other usages of
Endpoint accept the optional enforcement field and run type checks.
🪄 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: Pro Plus
Run ID: 7245136f-0f1d-46f0-ada0-46786503227d
📒 Files selected for processing (9)
Dockerfilenemoclaw-blueprint/policies/presets/whatsapp.yamlnemoclaw-blueprint/policies/tiers.yamlsrc/lib/onboard.tssrc/nemoclaw.tstest/cli.test.tstest/policies.test.tstest/policy-tiers.test.tstest/validate-blueprint.test.ts
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
a3acb9c to
7d0a027
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
src/lib/onboard.ts (1)
3203-3210:⚠️ Potential issue | 🟠 MajorWhatsApp enablement still does not force a rebuild when reusing an existing sandbox.
Adding WhatsApp to
activeMessagingChannelshere is too late for reuse cases. At Line 2977, reuse can still return early, so a sandbox created before WhatsApp support may be reused without Dockerfile/plugin updates.💡 Proposed fix
@@ - const needsProviderMigration = + const needsProviderMigration = hasMessagingTokens && messagingTokenDefs.some(({ name, token }) => token && !providerExistsInGateway(name)); + + const recordedChannels = new Set( + Array.isArray(registry.getSandbox(sandboxName)?.messagingChannels) + ? registry.getSandbox(sandboxName).messagingChannels + : [], + ); + const needsWhatsAppMigration = + Array.isArray(enabledChannels) && + enabledChannels.includes("whatsapp") && + !recordedChannels.has("whatsapp"); @@ - if (!isRecreateSandbox() && !needsProviderMigration && !credentialRotation.changed) { + if ( + !isRecreateSandbox() && + !needsProviderMigration && + !needsWhatsAppMigration && + !credentialRotation.changed + ) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard.ts` around lines 3203 - 3210, enabledChannels may include "whatsapp" but adding it to activeMessagingChannels happens after the early reuse check, so an existing sandbox can be reused without WhatsApp-related rebuilds; move the logic that pushes "whatsapp" onto activeMessagingChannels (the block that checks enabledChannels.includes("whatsapp")) to run before the early reuse/return decision (the reuse-existing-sandbox check) or, alternatively, ensure the reuse path also adds "whatsapp" and triggers a rebuild by setting the same flag used to force Dockerfile/plugin regeneration; reference the variables enabledChannels and activeMessagingChannels and the early reuse branch so the sandbox build decision sees WhatsApp enabled.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Dockerfile`:
- Around line 289-300: The WhatsApp proxy patch must be gated by an OpenClaw
version check: when WA_ENABLED is true, detect the OpenClaw version (e.g., by
reading OC_DIST/package.json or another included version token) and only allow a
missing WA_CHUNK to be treated as a non-fatal skip if the OpenClaw version is >=
2026.4.15; otherwise, if WA_CHUNK is empty or the grep patch pattern is not
found and version < 2026.4.15, fail the build (exit 1). Update the Dockerfile
logic around WA_CHUNK and the patch verification (the sed/grep block) to perform
this version comparison and change the current warning-only branch into a fatal
error for older versions while keeping the skip behavior for >= 2026.4.15.
In `@src/lib/onboard.ts`:
- Line 6130: printDashboard(...) can be called with an empty
selectedMessagingChannels on resume/reuse paths, which hides WhatsApp pairing
instructions; update the resume flow so that before calling
printDashboard(sandboxName, model, provider, nimContainer, agent,
selectedMessagingChannels) you populate selectedMessagingChannels when it's
empty by deriving channels from the existing nimContainer/agent (e.g., inspect
nimContainer.messagingChannels or agent.config to include "whatsapp" if enabled)
or by computing a fallback list based on the sandbox state, then pass that
non-empty array to printDashboard so WhatsApp pairing hints are shown on resume.
---
Duplicate comments:
In `@src/lib/onboard.ts`:
- Around line 3203-3210: enabledChannels may include "whatsapp" but adding it to
activeMessagingChannels happens after the early reuse check, so an existing
sandbox can be reused without WhatsApp-related rebuilds; move the logic that
pushes "whatsapp" onto activeMessagingChannels (the block that checks
enabledChannels.includes("whatsapp")) to run before the early reuse/return
decision (the reuse-existing-sandbox check) or, alternatively, ensure the reuse
path also adds "whatsapp" and triggers a rebuild by setting the same flag used
to force Dockerfile/plugin regeneration; reference the variables enabledChannels
and activeMessagingChannels and the early reuse branch so the sandbox build
decision sees WhatsApp enabled.
🪄 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: Pro Plus
Run ID: 8e21a400-7925-46c4-b793-2b203f756c45
📒 Files selected for processing (9)
Dockerfilenemoclaw-blueprint/policies/presets/whatsapp.yamlnemoclaw-blueprint/policies/tiers.yamlsrc/lib/onboard.tssrc/nemoclaw.tstest/cli.test.tstest/policies.test.tstest/policy-tiers.test.tstest/validate-blueprint.test.ts
✅ Files skipped from review due to trivial changes (4)
- src/nemoclaw.ts
- nemoclaw-blueprint/policies/tiers.yaml
- test/validate-blueprint.test.ts
- nemoclaw-blueprint/policies/presets/whatsapp.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
- test/policy-tiers.test.ts
- test/policies.test.ts
7d0a027 to
755f98b
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (4)
src/nemoclaw.ts (1)
1632-1634:⚠️ Potential issue | 🟡 MinorProvider cleanup still missing
slack-app.The addition of
whatsapp-bridgeis correct, but the cleanup loop still omitsslack-app. According to previous review, onboarding creates${sandboxName}-slack-appwhich would be left behind after destroy.Proposed fix
- for (const suffix of ["telegram-bridge", "discord-bridge", "slack-bridge", "whatsapp-bridge"]) { + for (const suffix of [ + "telegram-bridge", + "discord-bridge", + "slack-bridge", + "slack-app", + "whatsapp-bridge", + ]) { runOpenshell(["provider", "delete", `${sandboxName}-${suffix}`], { ignoreError: true }); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/nemoclaw.ts` around lines 1632 - 1634, The provider cleanup loop omits removing the `${sandboxName}-slack-app` provider so that resource is left behind; update the for-loop that calls runOpenshell(["provider","delete", `${sandboxName}-${suffix}`], { ignoreError: true }) to include "slack-app" in the suffix list (alongside "telegram-bridge","discord-bridge","slack-bridge","whatsapp-bridge") so the `${sandboxName}-slack-app` provider is deleted during destroy.Dockerfile (1)
289-302:⚠️ Potential issue | 🟠 MajorVersion-gate the WhatsApp proxy patch to fail on vulnerable OpenClaw builds.
Line 301 treats a missing patch target as a warning-only skip. On vulnerable OpenClaw builds < 2026.4.15, this would ship an image where WhatsApp pairing regresses to the 408 timeout (the issue this PR fixes). Per line 286's comment, the fix is only upstream in 2026.4.15+.
The patch should fail the build if the target is missing and OpenClaw < 2026.4.15; only skip safely if >= 2026.4.15.
Proposed fix with version check
RUN WA_ENABLED="$(echo "$NEMOCLAW_MESSAGING_CHANNELS_B64" | base64 -d 2>/dev/null | grep -q '"whatsapp"' && echo 1 || echo 0)" \ && if [ "$WA_ENABLED" = "1" ]; then \ + OPENCLAW_VERSION="$(node -p "require('/usr/local/lib/node_modules/openclaw/package.json').version")" \ OC_DIST="/usr/local/lib/node_modules/openclaw/dist" \ && WA_CHUNK="$(grep -rl 'async function createWaSocket' "$OC_DIST"/session-*.js 2>/dev/null | head -1)" \ && echo "Patching WhatsApp proxy agent in: ${WA_CHUNK:-NOT FOUND}" \ && if [ -n "$WA_CHUNK" ] && grep -q 'markOnlineOnConnect: false' "$WA_CHUNK"; then \ sed -i 's|markOnlineOnConnect: false|markOnlineOnConnect: false, agent: process.env.HTTPS_PROXY ? new (__require("https-proxy-agent").HttpsProxyAgent)(process.env.HTTPS_PROXY) : undefined|' "$WA_CHUNK"; \ if grep -q 'HttpsProxyAgent' "$WA_CHUNK"; then \ echo "Patch applied successfully"; \ else \ echo "ERROR: Patch verification failed" >&2; exit 1; \ fi; \ - else echo "WARNING: Pattern not found or chunk missing — skipping WhatsApp proxy patch"; fi; \ + elif dpkg --compare-versions "$OPENCLAW_VERSION" ge "2026.4.15"; then \ + echo "OpenClaw ${OPENCLAW_VERSION} already contains the upstream fix — skipping WhatsApp proxy patch"; \ + else \ + echo "ERROR: WhatsApp proxy patch target not found in vulnerable OpenClaw ${OPENCLAW_VERSION}" >&2; exit 1; \ + fi; \ else echo "WhatsApp not selected — skipping proxy patch"; fi🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Dockerfile` around lines 289 - 302, The Dockerfile currently treats a missing WhatsApp proxy patch (WA_CHUNK) as a warning, which must instead fail for vulnerable OpenClaw builds; update the patching block so it reads OpenClaw's version (e.g., from OC_DIST/package.json or another version file under OC_DIST), compare it against "2026.4.15", and if WA_CHUNK is missing and the detected OpenClaw version is less than 2026.4.15 then exit with an error (non-zero) rather than printing a warning; only allow skipping (warning) when the detected version is >= 2026.4.15. Use the existing variables WA_ENABLED, OC_DIST and WA_CHUNK to locate the files and fail the build path accordingly, and ensure the error message includes the discovered OpenClaw version and that the patch target was not found.src/lib/onboard.ts (2)
6130-6130:⚠️ Potential issue | 🟡 MinorUse persisted channels as fallback before printing dashboard pairing hints.
On resume/reuse paths,
selectedMessagingChannelscan still be empty, so WhatsApp pairing instructions may be hidden even when the sandbox has WhatsApp enabled.💡 Proposed fix
- printDashboard(sandboxName, model, provider, nimContainer, agent, selectedMessagingChannels); + const dashboardChannels = + selectedMessagingChannels.length > 0 + ? selectedMessagingChannels + : ( + registry.getSandbox(sandboxName)?.messagingChannels || + session?.messagingChannels || + [] + ); + printDashboard(sandboxName, model, provider, nimContainer, agent, dashboardChannels);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard.ts` at line 6130, selectedMessagingChannels can be empty on resume/reuse, causing WhatsApp pairing hints to be hidden; before calling printDashboard(sandboxName, model, provider, nimContainer, agent, selectedMessagingChannels) populate selectedMessagingChannels from persisted storage if it's empty (e.g. load persisted messaging channels/state used elsewhere in onboarding) so printDashboard receives the restored channels; update the call site that prepares selectedMessagingChannels (or add a small guard right before printDashboard) to merge persisted channels as a fallback when selectedMessagingChannels.length === 0.
3203-3210:⚠️ Potential issue | 🟠 MajorForce recreation when WhatsApp is newly enabled on an existing sandbox.
activeMessagingChannels.push("whatsapp")is correct, but the reuse gate (Line 2977) still skips recreate when WhatsApp was not present in the originally built sandbox. That can reuse an image without WhatsApp plugin/patching and produce a broken pairing flow.💡 Proposed fix
@@ if (liveExists) { const existingSandboxState = getSandboxReuseState(sandboxName); + const recordedChannels = new Set( + Array.isArray(registry.getSandbox(sandboxName)?.messagingChannels) + ? registry.getSandbox(sandboxName).messagingChannels + : [], + ); + const needsMessagingChannelMigration = + Array.isArray(enabledChannels) && + enabledChannels.some((name) => !recordedChannels.has(name)); @@ - if (!isRecreateSandbox() && !needsProviderMigration && !credentialRotation.changed) { + if ( + !isRecreateSandbox() && + !needsProviderMigration && + !needsMessagingChannelMigration && + !credentialRotation.changed + ) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/onboard.ts` around lines 3203 - 3210, When WhatsApp is newly appended to activeMessagingChannels (enabledChannels.includes("whatsapp") case), also force the sandbox/image to be recreated by flipping the reuse gate used earlier in the onboarding logic to prevent reusing an image without the WhatsApp plugin; after activeMessagingChannels.push("whatsapp") set the same boolean/flag that the reuse-gate checks (the boolean used to skip recreation) to false (or set a dedicated forceRecreateSandbox = true) so the build/recreate path runs when WhatsApp was not present originally.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@Dockerfile`:
- Around line 289-302: The Dockerfile currently treats a missing WhatsApp proxy
patch (WA_CHUNK) as a warning, which must instead fail for vulnerable OpenClaw
builds; update the patching block so it reads OpenClaw's version (e.g., from
OC_DIST/package.json or another version file under OC_DIST), compare it against
"2026.4.15", and if WA_CHUNK is missing and the detected OpenClaw version is
less than 2026.4.15 then exit with an error (non-zero) rather than printing a
warning; only allow skipping (warning) when the detected version is >=
2026.4.15. Use the existing variables WA_ENABLED, OC_DIST and WA_CHUNK to locate
the files and fail the build path accordingly, and ensure the error message
includes the discovered OpenClaw version and that the patch target was not
found.
In `@src/lib/onboard.ts`:
- Line 6130: selectedMessagingChannels can be empty on resume/reuse, causing
WhatsApp pairing hints to be hidden; before calling printDashboard(sandboxName,
model, provider, nimContainer, agent, selectedMessagingChannels) populate
selectedMessagingChannels from persisted storage if it's empty (e.g. load
persisted messaging channels/state used elsewhere in onboarding) so
printDashboard receives the restored channels; update the call site that
prepares selectedMessagingChannels (or add a small guard right before
printDashboard) to merge persisted channels as a fallback when
selectedMessagingChannels.length === 0.
- Around line 3203-3210: When WhatsApp is newly appended to
activeMessagingChannels (enabledChannels.includes("whatsapp") case), also force
the sandbox/image to be recreated by flipping the reuse gate used earlier in the
onboarding logic to prevent reusing an image without the WhatsApp plugin; after
activeMessagingChannels.push("whatsapp") set the same boolean/flag that the
reuse-gate checks (the boolean used to skip recreation) to false (or set a
dedicated forceRecreateSandbox = true) so the build/recreate path runs when
WhatsApp was not present originally.
In `@src/nemoclaw.ts`:
- Around line 1632-1634: The provider cleanup loop omits removing the
`${sandboxName}-slack-app` provider so that resource is left behind; update the
for-loop that calls runOpenshell(["provider","delete",
`${sandboxName}-${suffix}`], { ignoreError: true }) to include "slack-app" in
the suffix list (alongside
"telegram-bridge","discord-bridge","slack-bridge","whatsapp-bridge") so the
`${sandboxName}-slack-app` provider is deleted during destroy.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 8679cf48-fffc-4768-908f-b273f79786b4
📒 Files selected for processing (9)
Dockerfilenemoclaw-blueprint/policies/presets/whatsapp.yamlnemoclaw-blueprint/policies/tiers.yamlsrc/lib/onboard.tssrc/nemoclaw.tstest/cli.test.tstest/policies.test.tstest/policy-tiers.test.tstest/validate-blueprint.test.ts
✅ Files skipped from review due to trivial changes (4)
- test/policy-tiers.test.ts
- test/cli.test.ts
- test/policies.test.ts
- nemoclaw-blueprint/policies/tiers.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
- test/validate-blueprint.test.ts
- nemoclaw-blueprint/policies/presets/whatsapp.yaml
755f98b to
7b2678b
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/nemoclaw.ts (1)
1632-1633:⚠️ Potential issue | 🟠 MajorCleanup is still incomplete:
slack-appprovider is not deleted.Line 1632 adds WhatsApp cleanup, but destroy still omits
${sandboxName}-slack-app(created during onboarding), so a provider can be left behind after sandbox teardown.Proposed fix
- for (const suffix of ["telegram-bridge", "discord-bridge", "slack-bridge", "whatsapp-bridge"]) { + for (const suffix of [ + "telegram-bridge", + "discord-bridge", + "slack-bridge", + "slack-app", + "whatsapp-bridge", + ]) { runOpenshell(["provider", "delete", `${sandboxName}-${suffix}`], { ignoreError: true }); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/nemoclaw.ts` around lines 1632 - 1633, The cleanup loop in runOpenshell that deletes providers omits the `${sandboxName}-slack-app` provider; update the array of suffixes in the for loop (the one iterating over ["telegram-bridge", "discord-bridge", "slack-bridge", "whatsapp-bridge"]) to include "slack-app" so runOpenshell(["provider", "delete", `${sandboxName}-slack-app`], { ignoreError: true }) is executed for that provider as well; keep the same ignoreError behavior and use the existing sandboxName variable and runOpenshell call.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Dockerfile`:
- Around line 301-302: The patch gate currently compares versions
lexicographically in the Node one-liner (node -e "const
v=require('/usr/local/lib/node_modules/openclaw/package.json').version;process.exit(v>='2026.4.15'?0:1)"),
which misclassifies versions like 2026.4.9 and 2026.10.0; change the check to a
proper semantic comparison by invoking Node's semver comparison (e.g.,
require('semver').gte(v, '2026.4.15')) or by splitting and numerically comparing
major/minor/patch segments, and use the same method when printing the version in
the echo branch (the two node -e invocations referencing
require('/usr/local/lib/node_modules/openclaw/package.json').version). Ensure
the command exits 0 only when semver.gte(...) returns true.
---
Duplicate comments:
In `@src/nemoclaw.ts`:
- Around line 1632-1633: The cleanup loop in runOpenshell that deletes providers
omits the `${sandboxName}-slack-app` provider; update the array of suffixes in
the for loop (the one iterating over ["telegram-bridge", "discord-bridge",
"slack-bridge", "whatsapp-bridge"]) to include "slack-app" so
runOpenshell(["provider", "delete", `${sandboxName}-slack-app`], { ignoreError:
true }) is executed for that provider as well; keep the same ignoreError
behavior and use the existing sandboxName variable and runOpenshell call.
🪄 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: Pro Plus
Run ID: 45e403a5-5848-401a-8fb4-7c9d21c3a76c
📒 Files selected for processing (9)
Dockerfilenemoclaw-blueprint/policies/presets/whatsapp.yamlnemoclaw-blueprint/policies/tiers.yamlsrc/lib/onboard.tssrc/nemoclaw.tstest/cli.test.tstest/policies.test.tstest/policy-tiers.test.tstest/validate-blueprint.test.ts
✅ Files skipped from review due to trivial changes (3)
- test/policy-tiers.test.ts
- nemoclaw-blueprint/policies/tiers.yaml
- test/policies.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- test/cli.test.ts
- test/validate-blueprint.test.ts
- nemoclaw-blueprint/policies/presets/whatsapp.yaml
- src/lib/onboard.ts
| elif node -e "const v=require('/usr/local/lib/node_modules/openclaw/package.json').version;process.exit(v>='2026.4.15'?0:1)"; then \ | ||
| echo "OpenClaw $(node -e "process.stdout.write(require('/usr/local/lib/node_modules/openclaw/package.json').version)") has upstream proxy fix — skipping patch"; \ |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
node <<'NODE'
const threshold = '2026.4.15';
for (const v of ['2026.4.9', '2026.4.15', '2026.10.0']) {
const lexicographic = v >= threshold;
const [y, m, p] = v.split('.').map(Number);
const numeric = (y > 2026) || (y === 2026 && (m > 4 || (m === 4 && p >= 15)));
console.log(`${v}: current=${lexicographic} expected=${numeric}`);
}
NODERepository: NVIDIA/NemoClaw
Length of output: 173
Use a semantic version check for the patch gate.
The current code uses lexicographic string comparison (v >= '2026.4.15'), which incorrectly classifies versions: 2026.4.9 evaluates as fixed (true when it should be false) and 2026.10.0 evaluates as older (false when it should be true). This can skip the proxy patch on vulnerable builds or unnecessarily patch safe newer versions.
Suggested fix
- elif node -e "const v=require('/usr/local/lib/node_modules/openclaw/package.json').version;process.exit(v>='2026.4.15'?0:1)"; then \
+ elif node -e "const [y,m,p]=require('/usr/local/lib/node_modules/openclaw/package.json').version.split('.').map(Number); process.exit((y > 2026 || (y === 2026 && (m > 4 || (m === 4 && p >= 15)))) ? 0 : 1)"; then \
echo "OpenClaw $(node -e "process.stdout.write(require('/usr/local/lib/node_modules/openclaw/package.json').version)") has upstream proxy fix — skipping patch"; \🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Dockerfile` around lines 301 - 302, The patch gate currently compares
versions lexicographically in the Node one-liner (node -e "const
v=require('/usr/local/lib/node_modules/openclaw/package.json').version;process.exit(v>='2026.4.15'?0:1)"),
which misclassifies versions like 2026.4.9 and 2026.10.0; change the check to a
proper semantic comparison by invoking Node's semver comparison (e.g.,
require('semver').gte(v, '2026.4.15')) or by splitting and numerically comparing
major/minor/patch segments, and use the same method when printing the version in
the echo branch (the two node -e invocations referencing
require('/usr/local/lib/node_modules/openclaw/package.json').version). Ensure
the command exits 0 only when semver.gte(...) returns true.
Add WhatsApp as a messaging channel option during nemoclaw onboard. WhatsApp uses QR code pairing (no token), so the onboard flow skips the token prompt and prints pairing instructions in the summary. Changes: - Add whatsapp.yaml network policy preset with security-hardened endpoints (3/8 access:full for WebSocket/Noise, 5/8 L7-enforced) - Add WhatsApp to onboard channel selector and policy auto-suggestion - Register WhatsApp plugin in sandbox image when channel is selected - Patch Baileys proxy agent in sandbox image for OpenClaw 2026.4.2 (fixed upstream in 2026.4.15+; patch self-skips after version bump) - Add whatsapp-bridge to sandbox destroy cleanup - Add regression tests for preset, tier, and cleanup Closes NVIDIA#513 Signed-off-by: Paritosh Dixit <paritoshd@nvidia.com>
7b2678b to
ebf2751
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
nemoclaw-blueprint/policies/presets/whatsapp.yaml (1)
65-70: Consider future-proofing against potential default branch changes in WhiskeySockets/Baileys.Line 70 currently hardcodes
/master/in the allowed path, which is the current default branch. However, if the upstream repository were to change its default branch tomainor another name, this hardcoded path would fail and cause pairing behavior to regress. To make the policy more resilient, consider allowing multiple path variants (e.g., both/master/and/main/depending on your Baileys version pin), or document this as a maintenance point if you monitor Baileys branch updates.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@nemoclaw-blueprint/policies/presets/whatsapp.yaml` around lines 65 - 70, The allowed path currently hardcodes "/WhiskeySockets/Baileys/master/src/Defaults/index.ts" which will break if the repo's default branch changes; update the policy rules (the allow entry under rules for host raw.githubusercontent.com) to accept both branch variants (e.g., add an additional allow rule for "/WhiskeySockets/Baileys/main/src/Defaults/index.ts" or replace with a branch-agnostic pattern/wildcard/regex if supported) or add a comment documenting that the entry must be updated when Baileys changes its default branch.
🤖 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-blueprint/policies/presets/whatsapp.yaml`:
- Around line 65-70: The allowed path currently hardcodes
"/WhiskeySockets/Baileys/master/src/Defaults/index.ts" which will break if the
repo's default branch changes; update the policy rules (the allow entry under
rules for host raw.githubusercontent.com) to accept both branch variants (e.g.,
add an additional allow rule for
"/WhiskeySockets/Baileys/main/src/Defaults/index.ts" or replace with a
branch-agnostic pattern/wildcard/regex if supported) or add a comment
documenting that the entry must be updated when Baileys changes its default
branch.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 0e377021-de5b-42a9-82bc-00dfad1d5947
📒 Files selected for processing (9)
Dockerfilenemoclaw-blueprint/policies/presets/whatsapp.yamlnemoclaw-blueprint/policies/tiers.yamlsrc/lib/onboard.tssrc/nemoclaw.tstest/cli.test.tstest/policies.test.tstest/policy-tiers.test.tstest/validate-blueprint.test.ts
✅ Files skipped from review due to trivial changes (4)
- nemoclaw-blueprint/policies/tiers.yaml
- test/policies.test.ts
- test/validate-blueprint.test.ts
- src/nemoclaw.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- test/policy-tiers.test.ts
- test/cli.test.ts
- src/lib/onboard.ts
- Dockerfile
|
✨ Thanks for submitting this PR that proposes a new feature to add WhatsApp channel support for sandbox onboarding, which could help expand the capabilities of NemoClaw. Possibly related open issues: |
|
@paritoshd-nv any chance this PR can be updated to resolve conflicts? would be great to have first-class Whatsapp support in onboarding. Thanks! |
Add WhatsApp as a messaging channel option during nemoclaw onboard. WhatsApp uses QR code pairing (no token), so the onboard flow skips the token prompt and prints pairing instructions in the summary.
Changes:
Closes #513
Summary
Related Issue
Changes
Type of Change
Verification
npx prek run --all-filespassesnpm testpassesmake docsbuilds without warnings (doc changes only)AI Disclosure
Signed-off-by: Your Name your-email@example.com
Summary by CodeRabbit
New Features
Chores
Tests