feat(onboard): bake secondary agents via NEMOCLAW_EXTRA_AGENTS_JSON#4653
Conversation
Signed-off-by: Tinson Lai <tinsonl@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 (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughAdds support for baking secondary OpenClaw agents via NEMOCLAW_EXTRA_AGENTS_JSON: Docker ARG/ENV, onboard Dockerfile patching, config generation/validation that prepends canonical main agent, tests, and documentation. ChangesSecondary Agents Feature
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 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 docstrings
🧪 Generate unit tests (beta)
Comment |
Signed-off-by: Tinson Lai <tinsonl@nvidia.com> # Conflicts: # docs/reference/commands.mdx
|
🌿 Preview your docs: https://nvidia-preview-pr-4653.docs.buildwithfern.com/nemoclaw |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
docs/reference/commands.mdx (1)
1391-1391: ⚡ Quick winSplit this table description into one sentence per source line.
This row currently packs multiple sentences into one source line, which hurts reviewability and violates docs formatting rules.
As per coding guidelines, "
One sentence per line in source (makes diffs readable). Flag paragraphs where multiple sentences appear on the same line."🤖 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/commands.mdx` at line 1391, The table cell for NEMOCLAW_EXTRA_AGENTS_JSON is currently one long source line—split it so each sentence is its own source line (one-sentence-per-line rule). Break the content into separate sentences such as: 1) "NEMOCLAW_EXTRA_AGENTS_JSON is a JSON array of OpenClaw secondary-agent entries." 2) "It adds secondary agents to agents.list in the built OpenClaw config." 3) "Each entry requires id (1-32 chars, matching ^[a-z][a-z0-9_-]*$, not main), workspace, and agentDir." 4) "Both workspace and agentDir must be absolute paths under /sandbox/.openclaw/." 5) "Operators must supply per-agent tools policies and subagents.maxSpawnDepth; nothing is implicitly granted." 6) "The canonical main entry is always written first with default: true so secondary agents cannot displace it." 7) "Malformed JSON or invalid entries fail the image build with a structured error." Ensure each of the above sentences occupies its own source line in the docs.
🤖 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 `@scripts/generate-openclaw-config.mts`:
- Around line 521-529: The current containment check uses
pathValue.startsWith(AGENT_DATA_ROOT) which can be bypassed with dot segments;
first normalize the incoming path before any containment checks (e.g., use
path.posix.normalize or path.resolve to collapse "."/".." segments), then
validate the normalizedPath is absolute and verify it is under AGENT_DATA_ROOT
(ensure consistent trailing slash handling) before throwing the existing error;
update the checks around pathValue, AGENT_DATA_ROOT, and the error throws (refer
to variables pathValue, normalizedPath, AGENT_DATA_ROOT and the surrounding
validation logic in scripts/generate-openclaw-config.mts) so the normalized path
is what's tested for containment.
---
Nitpick comments:
In `@docs/reference/commands.mdx`:
- Line 1391: The table cell for NEMOCLAW_EXTRA_AGENTS_JSON is currently one long
source line—split it so each sentence is its own source line
(one-sentence-per-line rule). Break the content into separate sentences such as:
1) "NEMOCLAW_EXTRA_AGENTS_JSON is a JSON array of OpenClaw secondary-agent
entries." 2) "It adds secondary agents to agents.list in the built OpenClaw
config." 3) "Each entry requires id (1-32 chars, matching ^[a-z][a-z0-9_-]*$,
not main), workspace, and agentDir." 4) "Both workspace and agentDir must be
absolute paths under /sandbox/.openclaw/." 5) "Operators must supply per-agent
tools policies and subagents.maxSpawnDepth; nothing is implicitly granted." 6)
"The canonical main entry is always written first with default: true so
secondary agents cannot displace it." 7) "Malformed JSON or invalid entries fail
the image build with a structured error." Ensure each of the above sentences
occupies its own source line in the docs.
🪄 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: 6a9589c5-f0e0-41c4-89b1-244cc0051025
📒 Files selected for processing (6)
Dockerfiledocs/reference/commands.mdxscripts/generate-openclaw-config.mtssrc/lib/onboard/dockerfile-patch.test.tssrc/lib/onboard/dockerfile-patch.tstest/generate-openclaw-config.test.ts
PR Review AdvisorFindings: 0 needs attention, 3 worth checking, 0 nice ideas Review findings🛠️ Needs attention
🔎 Worth checking
🌱 Nice ideas
Since last review detailsCurrent findings:
This is an automated advisory review. A human maintainer must make the final merge decision. |
E2E Advisor RecommendationRequired E2E: Dispatch hint: Auto-dispatched E2E: Full advisor summaryE2E Recommendation AdvisorBase: Required E2E
Optional E2E
New E2E recommendations
Dispatch hint
|
E2E Scenario Advisor RecommendationRequired scenario E2E: Dispatch required scenario E2E:
Full scenario advisor summaryE2E Scenario AdvisorBase: Required scenario E2E
Optional scenario E2E
Relevant changed files
|
Selective E2E Results — ✅ All requested jobs passedRun: 26804857751
|
…uild Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/onboard/dockerfile-patch.ts (1)
263-266: ⚡ Quick winConsider wrapping the base64-encoded value with
sanitizeDockerArgfor consistency and defense-in-depth.All other base64-encoded JSON args in this file use
encodeSanitizedDockerJsonArgor at leastsanitizeDockerArgto strip\r\ncharacters before Docker ARG interpolation (lines 115, 210, 216, 222, 228, 234, 240, 250). While base64 output is inherently safe (alphanumeric +/+=only), applyingsanitizeDockerArgmaintains the established pattern and provides defense-in-depth.🔄 Suggested consistency fix
- const encoded = Buffer.from(extraAgentsRaw, "utf8").toString("base64"); + const encoded = sanitizeDockerArg( + Buffer.from(extraAgentsRaw, "utf8").toString("base64") + ); dockerfile = dockerfile.replace(🤖 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/dockerfile-patch.ts` around lines 263 - 266, Wrap the base64 value assigned to ARG NEMOCLAW_EXTRA_AGENTS_JSON_B64 with the existing sanitization helper instead of inserting `encoded` raw; locate the `encoded` variable and the `dockerfile.replace` call that sets `ARG NEMOCLAW_EXTRA_AGENTS_JSON_B64=...` and pass the value through `sanitizeDockerArg` (or use `encodeSanitizedDockerJsonArg` for parity with other JSON args) before interpolation so it follows the same defense-in-depth pattern as the other ARG insertions.
🤖 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.
Nitpick comments:
In `@src/lib/onboard/dockerfile-patch.ts`:
- Around line 263-266: Wrap the base64 value assigned to ARG
NEMOCLAW_EXTRA_AGENTS_JSON_B64 with the existing sanitization helper instead of
inserting `encoded` raw; locate the `encoded` variable and the
`dockerfile.replace` call that sets `ARG NEMOCLAW_EXTRA_AGENTS_JSON_B64=...` and
pass the value through `sanitizeDockerArg` (or use
`encodeSanitizedDockerJsonArg` for parity with other JSON args) before
interpolation so it follows the same defense-in-depth pattern as the other ARG
insertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: edbf2cfd-f377-481b-9653-7baad3b1812d
📒 Files selected for processing (6)
Dockerfiledocs/reference/commands.mdxscripts/generate-openclaw-config.mtssrc/lib/onboard/dockerfile-patch-extra-agents.test.tssrc/lib/onboard/dockerfile-patch.tstest/generate-openclaw-config.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- docs/reference/commands.mdx
- scripts/generate-openclaw-config.mts
- Dockerfile
Selective E2E Results — ✅ All requested jobs passedRun: 26806681061
|
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
… agents Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
Selective E2E Results — ✅ All requested jobs passedRun: 26809278439
|
prekshivyas
left a comment
There was a problem hiding this comment.
APPROVE. Reviewed the env-driven agent bake end-to-end.
Validation is solid (generate-openclaw-config.mts:224-299): id allowlisted by regex, main reserved and always pinned first with default:true (fixes #4562), paths are resolve()-normalized and matched against the exact canonical /sandbox/.openclaw/workspace-<id> and agents/<id> slots (dot-segment traversal rejected), and a strict per-level key allowlist drops any credential-like field — the baked entry is rebuilt from scratch, never copied from raw input. Confirmed the canonical paths match what provision_agent_workspaces in nemoclaw-start.sh actually parses, and the bare main entry is handled by the if (workspace)/if (agentDir) guards in migration-state.ts (no phantom host root). Using /sandbox/.openclaw/ over the issue's proposed .openclaw-data/ is the correct deviation.
Tests cover the negative space well (malformed, traversal, dup, reserved id, smuggled secrets, default-displacement regression); docs in commands.mdx cover schema, path constraints, and prohibited keys. CI green on 3ee9b5d; both CodeRabbit/CodeQL threads resolved. Resolves #4560, #4562.
Non-blocking nit: a whitespace-only NEMOCLAW_EXTRA_AGENTS_JSON is dropped host-side and never reaches the validator (dockerfile-patch.ts:501) — defensible as "empty == no extras," worth a one-line note if intentional.
Signed-off-by: Prekshi Vyas prekshiv@nvidia.com
Selective E2E Results — ✅ All requested jobs passedRun: 26833892971
|
## Summary - Add the missing `v0.0.57` release-notes section with links to the detailed docs pages for command, inference, onboarding, messaging, status, installer, and policy changes. - Remove public references to docs-skip terms from source docs and regenerate the NemoClaw user skills from the current Fern MDX docs. - Carry forward generated references for the per-agent documentation split, including Hermes-specific reference files. ## Source summary - #4615 and #4653 -> `docs/about/release-notes.mdx`, `docs/reference/commands.mdx`: Release notes now cover host-side `sessions` and `agents` commands plus `NEMOCLAW_EXTRA_AGENTS_JSON` secondary-agent baking. - #4163, #4204, #4611, #4619, and #4676 -> `docs/about/release-notes.mdx`, `docs/inference/use-local-inference.mdx`: Release notes now cover managed vLLM progress/readiness, DGX Spark model default changes, local Ollama streaming usage, and inference route divergence warnings. - #4267, #4601, #4609, #4642, #4645, and #4661 -> `docs/about/release-notes.mdx`, `docs/reference/commands.mdx`: Release notes now cover UFW auto-remediation, local-inference reachability gates, gateway reuse/binding, cancel rollback, and policy selection persistence. - #4577, #4582, #4607, and #4660 -> `docs/about/release-notes.mdx`, `docs/manage-sandboxes/messaging-channels.mdx`: Release notes now cover Slack validation, atomic `channels add`, WhatsApp QR diagnostics, and Slack placeholder normalization. - #4388, #4600, #4646, and #4647 -> `docs/about/release-notes.mdx`, `docs/reference/commands.mdx`: Release notes now cover status failure layers, paused-container hints, Docker-driver doctor behavior, and non-destructive stale-registry recovery. - #4569, #4579, and #4678 -> `docs/about/release-notes.mdx`, `docs/manage-sandboxes/lifecycle.mdx`, `docs/network-policy/integration-policy-examples.mdx`: Release notes now cover installer tag pinning, PyPI `uv` policy access, and observable Jira validation. - #4632 -> `.agents/skills/`: Regenerated user skills from the current per-agent docs source, including newly generated Hermes reference files. ## Verification - `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix nemoclaw-user --doc-platform fern-mdx` - `rg "permissive mode|shields down|shields up|shields status|config rotate-token|rotate-token" docs --glob "*.mdx"` - `rg "permissive mode|shields down|shields up|shields status|config rotate-token|rotate-token" .agents/skills --glob "*.md"` - `npm run docs` - `npm run build:cli` - Commit hooks: markdownlint, docs-to-skills verification, gitleaks, skills YAML, commitlint <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Restructured documentation to clearly distinguish OpenClaw and Hermes agent variants throughout user guides. * Enhanced security, credential storage, and deployment guidance with clearer setup flows. * Added Hermes plugin installation and ecosystem documentation. * Improved workspace, messaging, and policy management references with variant-specific command examples. * Refined troubleshooting and CLI reference sections for clarity. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
Summary
Adds
NEMOCLAW_EXTRA_AGENTS_JSONso operators can bake one or more OpenClaw secondary agents into the sandboxopenclaw.jsonat onboard time, alongside the canonical primarymainagent. The bake always emitsagents.listwith{ id: "main", default: true }first and operator-supplied entries appended after it, so secondary agents cannot displace the primary agent as the default.Related Issue
Closes #4560.
Closes #4562 — complementary to #4560.
Changes
scripts/generate-openclaw-config.mts: validateNEMOCLAW_EXTRA_AGENTS_JSON_B64— id regex, reserved-idmainrejection, duplicate-id rejection,resolve()-based containment under/sandbox/.openclaw/(rejects..traversal), required per-agenttoolsallow/deny policy, requiredsubagents.maxSpawnDepth, nodefault: trueoverrides. Always emitagents.listwith the canonicalmainentry first.src/lib/onboard/dockerfile-patch.ts: readprocess.env.NEMOCLAW_EXTRA_AGENTS_JSONand base64-encode the raw payload intoARG NEMOCLAW_EXTRA_AGENTS_JSON_B64. The host-side stage does not parse or shape-check the JSON, so the build-time validator inscripts/generate-openclaw-config.mtsremains the single source of truth for structured validation errors.Dockerfile: declareARG NEMOCLAW_EXTRA_AGENTS_JSON_B64=W10=and promote it toENV, matching theNEMOCLAW_*_B64convention.test/generate-openclaw-config.test.ts: cases for default-only emission, append-after-main,mainreservation,default: truerejection, duplicate-id rejection, id-regex enforcement, absolute-path and dot-segment traversal rejection, required-tools enforcement, required-subagents enforcement, and primary-agent-default regression with extras present.src/lib/onboard/dockerfile-patch-extra-agents.test.ts: focused test file covering valid-payload encoding, empty-default preservation, and raw-payload passthrough so malformed input reaches the build-time validator instead of being silently dropped on the host.docs/reference/commands.mdx: row pointer plus a new "Extra OpenClaw agents" subsection documenting the field schema, path constraints, validation rules, and an example payload.Type of Change
Verification
npx prek run --all-filespassesnpm testpassesnpm run docsbuilds without warnings (doc changes only)Signed-off-by: Tinson Lai tinsonl@nvidia.com
Summary by CodeRabbit
New Features
Documentation
Tests