Skip to content

feat(hermes): add managed tool gateway broker#3556

Open
shannonsands wants to merge 3 commits into
NVIDIA:mainfrom
NousResearch:ns322/hermes-managed-tool-gateway-clean
Open

feat(hermes): add managed tool gateway broker#3556
shannonsands wants to merge 3 commits into
NVIDIA:mainfrom
NousResearch:ns322/hermes-managed-tool-gateway-clean

Conversation

@shannonsands
Copy link
Copy Markdown

@shannonsands shannonsands commented May 15, 2026

Summary

Adds Hermes managed Nous Tool Gateway support for OAuth/subscription onboarding while keeping raw Nous OAuth tokens out of the sandbox. NemoClaw now starts a Hermes-owned host broker for selected managed tool planes, generates broker-mode Hermes config/env, and applies broker-scoped policy presets.

Related Issue

Related to NS-322.

Changes

  • Add matrix-driven Hermes managed gateway config for web, image, audio TTS/STT, Browser Use, and optional Modal.
  • Add Hermes host broker lifecycle glue and a broker runtime under agents/hermes/host/ that refreshes Nous OAuth via x-nous-refresh-token, injects upstream auth, rotates inference agent keys, and uses a sandbox-visible opaque broker token.
  • Generate sandbox .env/config for selected managed tools and preserve the selected presets through onboarding, rebuild, connect, and status recovery paths.
  • Add nous-* policy presets that allow only host.openshell.internal:11436 service paths plus Browser Use CDP exceptions.
  • Harden the Hermes plugin shim for broker-mode dotenv hydration, URL-safety, Firecrawl paths, Browser Use state/CDP, FAL queue polling, OpenAI audio/STT, and quiet NemoClaw context.
  • Update tests/docs for managed gateway config, policies, broker auth/rotation/header normalization, and plugin shims.

Type of Change

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

Verification

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

Additional checks run:

  • npm run build:cli
  • npx vitest run test/hermes-tool-gateway-broker.test.ts test/generate-hermes-config.test.ts test/hermes-plugin-handlers.test.ts test/policies.test.ts src/lib/onboard/initial-policy.test.ts src/lib/hermes-provider-auth.test.ts --maxWorkers=1 --testTimeout=30000
  • python3 -m py_compile agents/hermes/plugin/__init__.py
  • git diff --check --cached

Live UAT:

  • nous-web: web_search and web_extract passed through Firecrawl.
  • nous-browser: Browser Use cloud navigation/snapshot/click passed.
  • nous-audio: TTS and STT passed through OpenAI audio gateway.
  • nous-image: image generation passed through FAL queue.
  • nous-code: skipped for this UAT because Modal was not selected and terminal.backend: local was confirmed.
  • Sandbox had no raw NOUS_REFRESH_TOKEN or NOUS_ACCESS_TOKEN; gateway env/config used broker mode.

Note: I attempted the local pre-push/pre-commit hook path. The current macOS worktree does not have a complete root node_modules install, so the hook failed on local tooling resolution (biome, tsx, typescript, vitest/config) before it could provide useful PR-specific signal. The focused Hermes checks above and live UAT passed.


Signed-off-by: Shannon Sands shannon@nousresearch.com

Summary by CodeRabbit

  • New Features

    • Introduced managed tool gateways (web, audio, browser, image, code), a Hermes-managed broker service, plugin broker integrations, an in-sandbox audio transcription tool, onboarding flows to select/manage gateways, and corresponding policy presets.
  • Bug Fixes

    • OAuth refresh now sends the refresh credential via a request header instead of the form body.
  • Documentation

    • CLI/onboarding docs updated with managed gateway guidance and new environment variables.
  • Tests

    • Added unit and integration tests covering broker, presets, plugin patches, and config generation.

Review Change Stack

@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented May 15, 2026

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

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6988d169-ca78-481a-a693-26a49ba1c420

📥 Commits

Reviewing files that changed from the base of the PR and between 179826c and 586f0d1.

📒 Files selected for processing (1)
  • docs/reference/commands.md
✅ Files skipped from review due to trivial changes (1)
  • docs/reference/commands.md

📝 Walkthrough

Walkthrough

Adds a Hermes managed-tool gateway broker: host-side proxy and lifecycle, onboarding selection and Dockerfile build wiring, Hermes config and plugin broker-mode patches, policy presets for managed gateways, OAuth header change, registry/session plumbing, and comprehensive tests.

Changes

Hermes Managed Tool Gateway Broker System

Layer / File(s) Summary
Gateway matrix types & loader
agents/hermes/config/managed-tool-gateway.ts
Types and loader for the managed-tool gateway matrix and config-merge helper used by Hermes config generation.
Build settings, Dockerfile args & env wiring
agents/hermes/Dockerfile, agents/hermes/config/build-env.ts, src/lib/onboard/dockerfile-patch.ts
Adds build ARG/ENV for broker/presets/token, extends build settings to include managedToolGateways, and patches staged Dockerfile with base64 presets and sanitized broker token.
Messaging env lines & config generation
agents/hermes/config/messaging-config.ts, agents/hermes/generate-config.ts
Generates messaging .env lines for broker enable/token and per-preset env entries; generate-config passes managed gateway settings through.
Hermes config integration
agents/hermes/config/hermes-config.ts
Applies selected preset config entries into generated Hermes config and wires api server toolsets and plugin enablement.
Host-side broker service
agents/hermes/host/tool-gateway-broker.ts
Adds an executable host broker that proxies tool requests, injects host OAuth/agent credentials, refreshes tokens, and normalizes proxied responses.
Broker lifecycle manager
src/lib/hermes-tool-gateway-broker.ts
Manages detached broker subprocess lifecycle, state persistence, provider registration, health checks, and ensure/restart logic.
OAuth refresh header change
src/lib/oauth-device-code.ts, src/lib/oauth-device-code.test.ts
Sends refresh token via x-nous-refresh-token header; postForm supports extraHeaders; tests updated.
Hermes provider auth integration
src/lib/hermes-provider-auth.ts, src/lib/hermes-provider-auth.test.ts
Optionally registers refresh provider with broker when presets selected, sets broker token env, and ensures broker readiness; test stubs broker.
Hermes plugin broker-mode patches
agents/hermes/plugin/__init__.py
Installs broker-mode runtime patches, pre-LLM context grounding, and registers a transcribe_audio tool routed through brokered config.
Policy presets for managed gateways
nemoclaw-blueprint/policies/presets/nous-*.yaml, agents/hermes/policy-additions.yaml
Adds nous-{web,audio,browser,image,code} presets and updates agent policy additions (managed_inference) and Nous Research pruning.
Onboarding presets & policy selection
src/lib/onboard/hermes-managed-tools.ts, src/lib/onboard/policy-selection.ts, src/lib/onboard/initial-policy.ts, src/lib/onboard/dockerfile-patch.ts, src/lib/onboard.ts
Adds preset catalog, env parsing, interactive/non-interactive selection, merges required presets into initial boot policy, wires presets through onboarding steps, and aborts/create-time registration when broker token missing.
Session & registry persistence
src/lib/state/onboard-session.ts, src/lib/state/registry.ts
Extends Session and SandboxEntry to store hermesToolGateways, sanitizes updates, initializes from overrides/JSON, and persists non-empty values to registry.
Sandbox operations wiring
src/lib/actions/sandbox/{connect,status,rebuild}.ts
Conditionally ensures broker for Hermes sandboxes in connect/status flows and preserves/passes hermesToolGateways across rebuild and resume flows.
Tests & validation
test/*, test/hermes-tool-gateway-broker.test.ts, test/hermes-plugin-handlers.test.ts, test/generate-hermes-config.test.ts, test/policies.test.ts
Adds integration and unit tests covering broker lifecycle/health, proxy semantics, token rotation, plugin patch behavior, config generation, and preset/policy validation.
Docs
docs/reference/commands.md
Documents Hermes broker on port 11436 and NEMOCLAW_HERMES_TOOL_GATEWAYS onboarding env var.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#3512: Modifies buildMessagingEnvLines in agents/hermes/config/messaging-config.ts—overlaps with this PR’s messaging env generation changes.
  • NVIDIA/NemoClaw#3632: Related to onboarding summary/format changes in src/lib/onboard/summary.ts.

Suggested labels

enhancement: feature, enhancement: policy

Suggested reviewers

  • ericksoa
  • cv

"🐰
I tunneled through configs, presets, and ports,
Brokered the tokens and guarded the ports,
Presets in pockets, policies tight,
Hermes now hops through a safer night,
Hooray — the sandbox routes just right!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title directly and accurately summarizes the main feature addition: a managed tool gateway broker for Hermes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/onboard.ts (1)

10153-10178: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Persist cleared Hermes managed-tool selections too.

The comment above this helper says null clears and undefined leaves unchanged, but the truthy guard drops both [] and null. Switching away from Hermes or deselecting all managed tools therefore leaves the previous session value behind, and resume/drift handling can resurrect stale broker state.

Proposed fix
-  if (updates.hermesToolGateways) normalized.hermesToolGateways = updates.hermesToolGateways;
+  if (updates.hermesToolGateways !== undefined) {
+    normalized.hermesToolGateways = updates.hermesToolGateways;
+  }
🤖 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 10153 - 10178, The guard for
hermesToolGateways uses a truthy check so null and empty-array values get
dropped; change the conditional to check for undefined instead (e.g., replace
"if (updates.hermesToolGateways) normalized.hermesToolGateways =
updates.hermesToolGateways;" with "if (updates.hermesToolGateways !== undefined)
normalized.hermesToolGateways = updates.hermesToolGateways;") so that explicit
null (to clear) and [] (to deselect all) are persisted; apply the same
undefined-check pattern to any other fields using truthy guards like
messagingChannels or policyPresets if present.
🤖 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 `@src/lib/onboard.ts`:
- Around line 389-423: The managed-tool onboarding helpers (e.g., the
HERMES_TOOL_GATEWAY_PRESETS constant and HERMES_TOOL_GATEWAY_PRESET_NAMES set,
plus related helper functions in the ranges around lines 1686-1935 and
9424-9687) should be extracted out of src/lib/onboard.ts into one or more
focused modules under src/lib/onboard/ (for example
src/lib/onboard/hermesGateway.ts and src/lib/onboard/managedTools.ts); move the
constants and any helper functions that build/manipulate gateway selection or
policy wiring into those new files, export the necessary symbols
(HERMES_TOOL_GATEWAY_PRESETS, HERMES_TOOL_GATEWAY_PRESET_NAMES, and their helper
functions), and update onboard.ts to import these exports so onboard.ts only
orchestrates flow and does not contain the implementation details.
- Around line 7184-7185: Call setupHermesToolGateways with the recorded/previous
gateways so the managed-tool picker is seeded from the existing sandbox
selection (e.g., change the call from setupHermesToolGateways(provider,
hermesAuthMethod) to setupHermesToolGateways(provider, hermesAuthMethod,
existing) or the local variable that holds the recorded gateways), ensuring the
existing value is passed through to avoid hermesToolGatewayDrift and unnecessary
recreates.

---

Outside diff comments:
In `@src/lib/onboard.ts`:
- Around line 10153-10178: The guard for hermesToolGateways uses a truthy check
so null and empty-array values get dropped; change the conditional to check for
undefined instead (e.g., replace "if (updates.hermesToolGateways)
normalized.hermesToolGateways = updates.hermesToolGateways;" with "if
(updates.hermesToolGateways !== undefined) normalized.hermesToolGateways =
updates.hermesToolGateways;") so that explicit null (to clear) and [] (to
deselect all) are persisted; apply the same undefined-check pattern to any other
fields using truthy guards like messagingChannels or policyPresets if present.
🪄 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: 6483ead0-a5c2-418f-bc79-85832c4ec59f

📥 Commits

Reviewing files that changed from the base of the PR and between 76d24c7 and 174904c.

📒 Files selected for processing (35)
  • agents/hermes/Dockerfile
  • agents/hermes/config/build-env.ts
  • agents/hermes/config/hermes-config.ts
  • agents/hermes/config/managed-tool-gateway.ts
  • agents/hermes/config/messaging-config.ts
  • agents/hermes/generate-config.ts
  • agents/hermes/host/managed-tool-gateway-matrix.json
  • agents/hermes/host/tool-gateway-broker.ts
  • agents/hermes/plugin/__init__.py
  • agents/hermes/policy-additions.yaml
  • docs/reference/commands.md
  • nemoclaw-blueprint/policies/presets/nous-audio.yaml
  • nemoclaw-blueprint/policies/presets/nous-browser.yaml
  • nemoclaw-blueprint/policies/presets/nous-code.yaml
  • nemoclaw-blueprint/policies/presets/nous-image.yaml
  • nemoclaw-blueprint/policies/presets/nous-web.yaml
  • src/lib/actions/inference-set.test.ts
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/rebuild.ts
  • src/lib/actions/sandbox/status.ts
  • src/lib/hermes-provider-auth.test.ts
  • src/lib/hermes-provider-auth.ts
  • src/lib/hermes-tool-gateway-broker.ts
  • src/lib/oauth-device-code.test.ts
  • src/lib/oauth-device-code.ts
  • src/lib/onboard.ts
  • src/lib/onboard/dockerfile-patch.ts
  • src/lib/onboard/initial-policy.test.ts
  • src/lib/onboard/initial-policy.ts
  • src/lib/state/onboard-session.ts
  • src/lib/state/registry.ts
  • test/generate-hermes-config.test.ts
  • test/hermes-plugin-handlers.test.ts
  • test/hermes-tool-gateway-broker.test.ts
  • test/policies.test.ts

Comment thread src/lib/onboard.ts Outdated
Comment thread src/lib/onboard.ts Outdated
@wscurran
Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this detailed PR to add Hermes managed Nous Tool Gateway support. This change aims to improve the onboarding process by keeping raw Nous OAuth tokens out of the sandbox and generating broker-mode Hermes config/env.

@wscurran wscurran added the Sandbox Use this label to identify issues related to the NemoClaw isolated environment based on OpenShell. label May 15, 2026
Signed-off-by: Test User <test@example.com>
@shannonsands shannonsands force-pushed the ns322/hermes-managed-tool-gateway-clean branch from 174904c to 179826c Compare May 18, 2026 03:48
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/onboard.ts (1)

9746-9756: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Resolve the sandbox name before re-running Hermes inference on resume.

This branch can execute on a resumed session that finished provider/inference setup but never reached sandbox creation, so sandboxName is still null by design. setupInference() now hard-fails on Line 7450 for Hermes, which turns a valid resume into an immediate abort.

Suggested fix
       if (provider === hermesProviderAuth.HERMES_PROVIDER_NAME) {
+        if (!sandboxName) {
+          sandboxName = await promptValidatedSandboxName(agent);
+        }
         startRecordedStep("inference", { provider, model });
         const inferenceResult = await setupInference(
           sandboxName,
           model,
           provider,
🤖 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 9746 - 9756, When provider ===
hermesProviderAuth.HERMES_PROVIDER_NAME ensure sandboxName is resolved before
calling setupInference: check if sandboxName is null/undefined and, if so, await
the existing sandbox resolution/creation routine used elsewhere in this module
to populate sandboxName, then proceed to startRecordedStep("inference", ...) and
call setupInference(sandboxName, ...); reference the symbols provider,
hermesProviderAuth.HERMES_PROVIDER_NAME, sandboxName, and setupInference to
locate where to insert the resolution call.
🧹 Nitpick comments (1)
agents/hermes/Dockerfile (1)

92-110: 💤 Low value

Acknowledge: Broker token baked into image layer by design.

Trivy flags NEMOCLAW_HERMES_TOOL_BROKER_TOKEN as potential secret exposure (DS-0031). Per the PR objectives, this is intentional—the broker token is an opaque, sandbox-visible credential that replaces raw Nous OAuth tokens. The same pattern already exists for NEMOCLAW_PROVIDER_KEY.

For future consideration: if these tokens become more sensitive, consider injecting them at runtime via mounted secrets rather than build args, but the current approach aligns with the broker architecture.

🤖 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 `@agents/hermes/Dockerfile` around lines 92 - 110, Add a short inline comment
above the ARG/ENV block stating that baking NEMOCLAW_HERMES_TOOL_BROKER_TOKEN
into the image is intentional (matches existing NEMOCLAW_PROVIDER_KEY pattern)
and that this is an opaque, sandbox-visible broker credential; reference the ARG
NEMOCLAW_HERMES_TOOL_BROKER_TOKEN and ENV NEMOCLAW_HERMES_TOOL_BROKER_TOKEN by
name and mention the Trivy DS-0031 false-positive, and optionally note the
future alternative of runtime-mounted secrets if sensitivity increases.
🤖 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.

Outside diff comments:
In `@src/lib/onboard.ts`:
- Around line 9746-9756: When provider ===
hermesProviderAuth.HERMES_PROVIDER_NAME ensure sandboxName is resolved before
calling setupInference: check if sandboxName is null/undefined and, if so, await
the existing sandbox resolution/creation routine used elsewhere in this module
to populate sandboxName, then proceed to startRecordedStep("inference", ...) and
call setupInference(sandboxName, ...); reference the symbols provider,
hermesProviderAuth.HERMES_PROVIDER_NAME, sandboxName, and setupInference to
locate where to insert the resolution call.

---

Nitpick comments:
In `@agents/hermes/Dockerfile`:
- Around line 92-110: Add a short inline comment above the ARG/ENV block stating
that baking NEMOCLAW_HERMES_TOOL_BROKER_TOKEN into the image is intentional
(matches existing NEMOCLAW_PROVIDER_KEY pattern) and that this is an opaque,
sandbox-visible broker credential; reference the ARG
NEMOCLAW_HERMES_TOOL_BROKER_TOKEN and ENV NEMOCLAW_HERMES_TOOL_BROKER_TOKEN by
name and mention the Trivy DS-0031 false-positive, and optionally note the
future alternative of runtime-mounted secrets if sensitivity increases.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 16f12a28-8e51-4a31-9ec6-1aa4c7c4e403

📥 Commits

Reviewing files that changed from the base of the PR and between 174904c and 179826c.

📒 Files selected for processing (32)
  • agents/hermes/Dockerfile
  • agents/hermes/config/build-env.ts
  • agents/hermes/config/hermes-config.ts
  • agents/hermes/config/managed-tool-gateway.ts
  • agents/hermes/config/messaging-config.ts
  • agents/hermes/generate-config.ts
  • agents/hermes/host/managed-tool-gateway-matrix.json
  • agents/hermes/host/tool-gateway-broker.ts
  • agents/hermes/plugin/__init__.py
  • agents/hermes/policy-additions.yaml
  • docs/reference/commands.md
  • nemoclaw-blueprint/policies/presets/nous-audio.yaml
  • nemoclaw-blueprint/policies/presets/nous-browser.yaml
  • nemoclaw-blueprint/policies/presets/nous-code.yaml
  • nemoclaw-blueprint/policies/presets/nous-image.yaml
  • nemoclaw-blueprint/policies/presets/nous-web.yaml
  • src/lib/actions/inference-set.test.ts
  • src/lib/actions/sandbox/connect.ts
  • src/lib/actions/sandbox/rebuild.ts
  • src/lib/actions/sandbox/status.ts
  • src/lib/hermes-provider-auth.test.ts
  • src/lib/hermes-provider-auth.ts
  • src/lib/hermes-tool-gateway-broker.ts
  • src/lib/oauth-device-code.test.ts
  • src/lib/oauth-device-code.ts
  • src/lib/onboard.ts
  • src/lib/onboard/dockerfile-patch.ts
  • src/lib/onboard/hermes-managed-tools.ts
  • src/lib/onboard/initial-policy.test.ts
  • src/lib/onboard/initial-policy.ts
  • src/lib/onboard/policy-selection.ts
  • src/lib/onboard/summary.ts
✅ Files skipped from review due to trivial changes (2)
  • src/lib/actions/inference-set.test.ts
  • src/lib/oauth-device-code.test.ts
🚧 Files skipped from review as they are similar to previous changes (21)
  • src/lib/onboard/initial-policy.ts
  • src/lib/onboard/dockerfile-patch.ts
  • src/lib/hermes-provider-auth.ts
  • nemoclaw-blueprint/policies/presets/nous-code.yaml
  • docs/reference/commands.md
  • src/lib/actions/sandbox/status.ts
  • src/lib/actions/sandbox/connect.ts
  • nemoclaw-blueprint/policies/presets/nous-web.yaml
  • nemoclaw-blueprint/policies/presets/nous-image.yaml
  • nemoclaw-blueprint/policies/presets/nous-audio.yaml
  • agents/hermes/config/build-env.ts
  • agents/hermes/generate-config.ts
  • agents/hermes/host/managed-tool-gateway-matrix.json
  • nemoclaw-blueprint/policies/presets/nous-browser.yaml
  • src/lib/hermes-provider-auth.test.ts
  • agents/hermes/config/managed-tool-gateway.ts
  • src/lib/hermes-tool-gateway-broker.ts
  • src/lib/oauth-device-code.ts
  • agents/hermes/policy-additions.yaml
  • src/lib/actions/sandbox/rebuild.ts
  • agents/hermes/host/tool-gateway-broker.ts

cv pushed a commit that referenced this pull request May 19, 2026
## Summary
Maintainer replay of #3556 from @shannonsands / NousResearch, with one
maintainer follow-up commit on top to make the branch shippable.

This keeps the original Hermes managed Nous Tool Gateway support:
OAuth/subscription onboarding without raw Nous OAuth tokens in the
sandbox, a Hermes-owned host broker for selected managed tool planes,
broker-mode Hermes config/env generation, and broker-scoped policy
presets.

## Maintainer Follow-Up
- Resolves the Hermes resume correctness blocker where
`setupInference()` could be called with `sandboxName === null` when the
provider/model route was already selected and ready.
- Preserves the #2753 behavior: the resumed sandbox name is resolved
before Hermes inference reconciliation, but is not persisted to the
onboard session before sandbox creation.
- Updates the Hermes provider reuse test for the intentional
provider-store preflight and adds a regression for resume with no
recorded sandbox name.

## Original PR
Supersedes/continues #3556.

Original author: @shannonsands
Original PR head before this maintainer patch:
`4db9a302c3e385978a12eccc3d9f748c4a91939e`
Maintainer patch commit: `3f767eeff503a1d36827022033ad3aa075b0b7e3`

## Verification
- [x] `npm run build:cli`
- [x] `npx vitest run test/onboard.test.ts -t "Hermes Provider|sandbox
name before"`
- [x] `npx vitest run test/onboard.test.ts
test/onboard-resume-provider-recovery.test.ts
test/onboard-policy-suggestions.test.ts
src/lib/state/onboard-session.test.ts
src/lib/onboard/dockerfile-patch.test.ts
src/lib/hermes-provider-auth.test.ts src/lib/oauth-device-code.test.ts
test/generate-hermes-config.test.ts test/hermes-plugin-handlers.test.ts
test/hermes-tool-gateway-broker.test.ts test/policies.test.ts`
- [x] `npm run checks`
- [x] `git diff --check`

## Merge Gate
Before approval/merge, still require one live Hermes OAuth onboarding
smoke with at least `nous-web`, broker health on
`127.0.0.1:11436/health`, and one managed-tool call through the sandbox.
If local Nous OAuth/subscription is unavailable, get that exact smoke
result from Nous before merging.

Signed-off-by: Shannon Sands <shannon@nousresearch.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>


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

* **New Features**
* Interactive onboarding and selection for five managed Nous tools
(audio, browser, code, image, web).
* Local host-side managed-tool gateway broker and runtime “broker-mode”
plugin; new audio transcription handler.

* **Improvements**
* Broker-aware onboarding, OAuth/device flows, token
registration/persistence, and sandbox lifecycle preservation of
managed-tool selections.
* Generated runtime config/env support for enabling broker and presets;
new policy presets enforcing network and binary restrictions.

* **Documentation**
  * Docs updated with broker behavior and environment options.

* **Tests**
* Added unit and integration tests for broker, plugin, and config
generation.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/NVIDIA/NemoClaw/pull/3742?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Integration: Hermes Sandbox Use this label to identify issues related to the NemoClaw isolated environment based on OpenShell.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants