fix(hermes): register bare tool schemas so strict providers accept them - #7068
Conversation
The NemoClaw Hermes plugin registered its four tools (nemoclaw_status,
nemoclaw_info, nemoclaw_reload_skills, transcribe_audio) by passing a
pre-wrapped OpenAI envelope (`{"type":"function","function":{...}}`) to
`ctx.register_tool`. Hermes wraps registered schemas again at request-build
time, so the outbound `tools[]` entries became double-wrapped
(`{"type":"function","function":{"type":"function","function":{...}}}`).
Lenient endpoints (NVIDIA build, Azure) tolerate the nesting, but Google
Gemini's strict OpenAI-compatible endpoint rejects the whole request with
HTTP 400 (`Unknown name "function" at tools[i].function`), breaking every
conversation. For transcribe_audio the double-wrap also dropped its real
`parameters` (file_path/model) to `{}` at the outer level.
Pass the bare function object to `register_tool` so Hermes adds exactly one
envelope, producing spec-valid single-wrapped tools and preserving
transcribe_audio's parameters.
Adds a standalone unittest that registers the tools against a fake ctx and
asserts each schema is a bare function object (no nested envelope) and that
transcribe_audio keeps its real parameters.
Closes #7067
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Jason Ma <jama@nvidia.com>
📝 WalkthroughWalkthroughThe Hermes NemoClaw plugin now registers four tools using bare function schemas instead of pre-wrapped envelopes. Tool descriptions were updated, the transcription parameters were made explicit, and standalone tests validate registration names and schema structure. ChangesHermes tool schema registration
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage remains at 96%, unchanged from the TypeScript / code-coverage/cliThe overall coverage in the Show a code coverage summary of the most impacted files.
Updated |
PR Review Advisor — InformationalAdvisor assessment: Informational / medium confidence Model lanes
Nemotron output stays in workflow artifacts and does not change the assessment above. E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: 1 warning · 0 suggestionsWarningsWarnings do not block.
|
<!-- markdownlint-disable MD041 --> ## Summary Add the v0.0.87 changelog entry and align the DGX Station, platform-support, and rebuild documentation with behavior merged since v0.0.86. The Station documentation retains the Deferred support status while recording the two exact factory-image qualification profiles and the post-reboot receipt compatibility fix from #7130. ## Changes - Add the v0.0.87 changelog summary, including the merged Station resume receipt fix, with links to the owning documentation pages. - Document the exact April 2026 Colossus BaseOS and June 2026 AI Developer Tools Station identities, validation boundaries, and permitted host preparation. - Synchronize those Station qualification paths into the canonical platform matrix and generated provider/platform pages. - Document how an OpenClaw rebuild clears stale managed-provider session-model pins after an inference switch. ### Source summary - [#7130](#7130) -> `docs/changelog/2026-07-17.mdx`: Document compatibility with current six-field and legacy three-field Station resume receipts after host preparation. - [#7128](#7128) -> `docs/changelog/2026-07-17.mdx`: Document restart-safe managed DCode startup and required Docker resource limits. - [#7126](#7126) -> `docs/changelog/2026-07-17.mdx`, `docs/get-started/dgx-station-preparation.mdx`, `ci/platform-matrix.json`: Document the two bounded Station factory-image qualification profiles without promoting Deferred support and synchronize the generated platform/provider references. - [#6947](#6947) -> `docs/changelog/2026-07-17.mdx`: Document streaming sandbox backup archive creation. - [#7117](#7117) -> `docs/changelog/2026-07-17.mdx`: Document Hermes post-restore gateway and managed MCP health verification. - [#7109](#7109) -> `docs/changelog/2026-07-17.mdx`, `docs/manage-sandboxes/recover-rebuild-sandboxes.mdx`: Document stale managed session-model pin reconciliation after rebuild. - [#7068](#7068) -> `docs/changelog/2026-07-17.mdx`: Document strict-provider compatibility for Hermes tool schemas. - [#6965](#6965) -> `docs/changelog/2026-07-17.mdx`: Document managed vLLM download storage estimation. - [#7114](#7114) -> `docs/changelog/2026-07-17.mdx`: Document preserved, redacted rebuild diagnostics. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [x] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: Documentation-only release-prep update; the changelog, platform-generation contracts, and docs build validate the changed pages and links. - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [ ] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [ ] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — `npx vitest run test/generate-platform-docs.test.ts test/station-doc-ownership.test.ts test/changelog-docs.test.ts`: 29 passed; `python3 scripts/generate-platform-docs.py --check`: all generated tables in sync - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [x] `npm run docs` builds without warnings (doc changes only) - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) --- Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added filesystem-aware managed vLLM storage preflight (cold download sizing; interactive vs non-interactive capacity checks). - Improved tool-schema compatibility for strict OpenAI-compatible providers (including Gemini schema handling) using a strict single envelope. - Enhanced sandbox backup creation with streamed archive generation and incremental entry validation. - **Bug Fixes** - Strengthened rebuild/recovery checks with Hermes sandbox health validation and cleanup of stale managed-provider session pins. - Persisted onboarding startup commands with required `nproc`/`nofile` limits across sandbox recreation. - Improved replacement-image rebuild diagnostics with bounded, redacted output handling. - For OpenCLAW “rebuild while preserving state,” stale model/provider pins are cleared when appropriate. - **Documentation** - Expanded DGX Station GB300 no-OTA factory profile/qualification criteria and clarified managed vLLM provider/sandbox constraints. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Summary
The NemoClaw Hermes plugin registered its four tools by passing a pre-wrapped OpenAI envelope (
{"type":"function","function":{...}}) toctx.register_tool. Hermes wraps registered schemas again at request-build time, so the outboundtools[]entries were double-wrapped. Lenient endpoints tolerate the extra nesting, but Google Gemini's strict OpenAI-compatible endpoint rejects the whole request with HTTP 400 (Unknown name "function" at 'tools[i].function'), breaking every conversation for Gemini sandboxes;transcribe_audioadditionally lost its realparameters(dropped to{}at the outer level). After this change the plugin passes the bare function object, so Hermes adds exactly one envelope and the tools validate on strict providers.Related Issue
Closes #7067
Changes
agents/hermes/plugin/__init__.py: unwrap theschema=argument for all fourregister_toolcalls (nemoclaw_status,nemoclaw_info,transcribe_audio,nemoclaw_reload_skills) — pass{"name", "description", "parameters"}directly instead of a pre-wrapped{"type":"function","function":{...}}envelope. This is the fix at the layer that produced the malformed shape (our plugin), rather than adding defensive normalization downstream in Hermes. The file is copied verbatim into the image (agents/hermes/Dockerfile), so the source edit fully covers the deployed/sandbox/.hermes/plugins/nemoclaw/__init__.py.agents/hermes/plugin/test_register_tools.py(new): registers the tools against a fakectxand asserts each schema is a bare function object (top-levelname/parameters, no nested envelope) and thattranscribe_audiokeeps its realparameters. There is no existing Python test harness for this plugin, so this is a standaloneunittest(stdlib + PyYAML, no Hermes runtime).agents/hermes/plugin/plugin.yaml'sprovides_toolsomitstranscribe_audio— a manifest inconsistency, not a cause of the 400; left unchanged to keep this fix minimal.Type of Change
Quality Gates
Verification
Signed-off-by:line and every commit appears asVerifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailablepython3 -m unittest test_register_tools(inagents/hermes/plugin/) → 3 passed; confirmed red on the pre-fix double-wrap (4 failures + 1 error, incl.transcribe_audioparams dropped) and green after. Note: CI has no Python lane foragents/, so this test is host-verified (run locally and on a clean host checkout), not executed by CI.npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:npm run docsbuilds without warnings (doc changes only)Verification detail
transcribe_audioretainsfile_path/model/required. Red/green confirmed by reverting only the source fix. Run locally and on a clean host checkout (Node/Python 22).nemohermes onboardwith the Google Gemini provider and a live message, which needs a Gemini-provider credential/sandbox not available to this loop. A maintainer/reporter can confirm with the issue's repro (onboard Gemini → send a message → expect no HTTP 400; inspectmodel_tools.get_tool_definitions()for single-wrapped entries).Signed-off-by: Jason Ma jama@nvidia.com
Summary by CodeRabbit
Bug Fixes
Tests