fix(inference): validate custom Anthropic endpoint streaming during onboarding (#6289)#6297
Conversation
…nboarding (NVIDIA#6289) Custom Anthropic-compatible endpoints were validated with a non-streaming /v1/messages probe only. Gateways whose non-streaming responses are valid but whose SSE streaming layer is malformed (e.g. duplicate message_start events with the same message id, observed on the Inference Hub route) passed onboarding and then failed at runtime inside the sandbox with Hermes' cryptic 'no final response was produced' (exit 1) — agent runtimes only use the streaming path. Add runAnthropicStreamingEventProbe: a stream:true /v1/messages probe that validates the SSE event sequence (exactly one message_start, at least one content_block_delta, one message_stop). Wire it into probeAnthropicEndpoint behind {probeStreaming} and enable it for the custom Anthropic-compatible onboarding path, mirroring the existing /v1/responses streaming validation (NVIDIA#1833). Reasoning mode skips the streaming probe, matching the custom OpenAI-compatible path. The official Anthropic provider path is unchanged. Malformed streams now fail validation at onboarding with an actionable message naming the duplicate/missing events instead of surfacing later as an empty final response at runtime. The Anthropic credential-retry integration tests move to a focused test/onboard-selection-anthropic-retry.test.ts (with the fake curl now serving SSE for stream:true probes), shrinking onboard-selection.test.ts below its legacy size budget, which is ratcheted down accordingly. Signed-off-by: Tony Luo <xialuo@nvidia.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
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 Anthropic-compatible onboarding streaming validation for ChangesAnthropic Streaming Validation
Estimated code review effort: 4 (Complex) | ~75 minutes Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
…be mocks The duplicated mockStreaming helper and inline -o writer added four if statements to probe.test.ts, tripping the changed-test-file if-count guardrail. Route both through the existing writeCurlOutputBody helper, which exists precisely to keep that budget steady. Signed-off-by: Tony Luo <xialuo@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/lib/inference/probe-anthropic.test.ts (1)
89-89: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winStub the negative-call streaming spies.
vi.spyOn()calls through by default, so if this regression ever occurs the test can invoke the real curl-backed streaming probe before failing.
Mock a harmless return value while still assertingnot.toHaveBeenCalled().Also applies to: 180-180
🤖 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/inference/probe-anthropic.test.ts` at line 89, The streaming spy setup in probe-anthropic.test.ts currently uses vi.spyOn() without stubbing, so it can call the real curl-backed probe before the assertion fails. Update the negative-call tests around runAnthropicStreamingEventProbe (and the other matching spy at the second occurrence) to return a harmless mocked value while still verifying not.toHaveBeenCalled(), so the test never executes the real streaming implementation.test/onboard-selection-anthropic-retry.test.ts (1)
75-75: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueTest titles missing required issue-ref suffix.
Neither test title ends with a local issue reference like
(#6289).As per coding guidelines, "Root-level integration tests under
test/should import source code, use ESM imports, and use behavior-oriented titles with local issue refs in a final(#1234)suffix."Also applies to: 153-153
🤖 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/onboard-selection-anthropic-retry.test.ts` at line 75, The test titles in this suite are missing the required local issue-reference suffix. Update the behavior-oriented titles in the affected `it(...)` blocks, including the one in `onboard-selection-anthropic-retry.test.ts` and the other referenced test, so each ends with a final local issue tag like `(`#6289`)`. Keep the titles descriptive and ensure the suffix is appended exactly once at the end of each test name.Source: Coding guidelines
🤖 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/adapters/http/probe.ts`:
- Line 595: The Anthropic stream validation in probe.ts is currently only
checking event presence/counts, so malformed sequences can still pass. Update
the validation around the capture helper and the Anthropic stream checks to
preserve the ordered event list, add message_stop to the singleton-event
enforcement alongside SINGLETON_ANTHROPIC_STREAMING_EVENTS, and assert the
stream order is valid: message_start must come before any content deltas, and
message_stop must be the final terminal event after all content.
---
Nitpick comments:
In `@src/lib/inference/probe-anthropic.test.ts`:
- Line 89: The streaming spy setup in probe-anthropic.test.ts currently uses
vi.spyOn() without stubbing, so it can call the real curl-backed probe before
the assertion fails. Update the negative-call tests around
runAnthropicStreamingEventProbe (and the other matching spy at the second
occurrence) to return a harmless mocked value while still verifying
not.toHaveBeenCalled(), so the test never executes the real streaming
implementation.
In `@test/onboard-selection-anthropic-retry.test.ts`:
- Line 75: The test titles in this suite are missing the required local
issue-reference suffix. Update the behavior-oriented titles in the affected
`it(...)` blocks, including the one in
`onboard-selection-anthropic-retry.test.ts` and the other referenced test, so
each ends with a final local issue tag like `(`#6289`)`. Keep the titles
descriptive and ensure the suffix is appended exactly once at the end of each
test name.
🪄 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: 5ad66d1a-0eed-4771-aedb-7ce60ed88580
📒 Files selected for processing (11)
ci/test-file-size-budget.jsondocs/inference/inference-options.mdxdocs/reference/troubleshooting.mdxsrc/lib/adapters/http/probe.test.tssrc/lib/adapters/http/probe.tssrc/lib/inference/probe-anthropic.test.tssrc/lib/inference/probe-anthropic.tssrc/lib/onboard/inference-selection-validation.test.tssrc/lib/onboard/inference-selection-validation.tstest/onboard-selection-anthropic-retry.test.tstest/onboard-selection.test.ts
💤 Files with no reviewable changes (1)
- test/onboard-selection.test.ts
Address CodeRabbit review on NVIDIA#6297: - Validate the Anthropic stream as a sequence, not just counts: keep the ordered event list from the SSE capture, require message_start before any content_block_delta and message_stop after the last one, and add message_stop to the singleton set so duplicate terminal events fail too. Interleaved unknown events (ping) stay tolerated. - Stub the negative-call streaming spies in probe-anthropic tests so a regression can never invoke the real curl-backed probe. - Add the (NVIDIA#6289) issue-ref suffix to the moved integration test titles. Signed-off-by: Tony Luo <xialuo@nvidia.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/lib/adapters/http/probe.ts (1)
617-629: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winValidate
message_stopagainst all known content events, not only deltas.Line 626 only compares
message_stopto the lastcontent_block_delta, so streams likemessage_start → content_block_delta → message_stop → content_block_stopcan still pass even thoughmessage_stopis not terminal for the known Anthropic sequence. Check the first/last index of all Anthropic content/message payload events while still ignoring unknown interleavings likeping.Proposed fix
+const ANTHROPIC_CONTENT_STREAMING_EVENTS = [ + "content_block_start", + "content_block_delta", + "content_block_stop", + "message_delta", +]; + function anthropicSequenceErrors(eventSequence: string[]): string[] { const errors: string[] = []; const firstStart = eventSequence.indexOf("message_start"); - const firstDelta = eventSequence.indexOf("content_block_delta"); - const lastDelta = eventSequence.lastIndexOf("content_block_delta"); + const contentIndexes = eventSequence + .map((event, index) => (ANTHROPIC_CONTENT_STREAMING_EVENTS.includes(event) ? index : -1)) + .filter((index) => index >= 0); + const firstContent = contentIndexes[0] ?? -1; + const lastContent = contentIndexes[contentIndexes.length - 1] ?? -1; const lastStop = eventSequence.lastIndexOf("message_stop"); - if (firstDelta < firstStart) { - errors.push("content_block_delta before message_start"); + if (firstContent >= 0 && firstContent < firstStart) { + errors.push("content event before message_start"); } - if (lastStop < lastDelta) { - errors.push("content_block_delta after message_stop"); + if (lastContent >= 0 && lastStop < lastContent) { + errors.push("content event after message_stop"); } return errors; }🤖 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/adapters/http/probe.ts` around lines 617 - 629, The Anthropic sequence validation in anthropicSequenceErrors only checks message_stop against content_block_delta, so it can miss non-terminal stops when other known events appear after it. Update the logic to compare message_stop against the full set of known Anthropic content/message payload events in eventSequence, using the relevant first/last index checks in anthropicSequenceErrors, while continuing to ignore unknown interleavings like ping.
🧹 Nitpick comments (1)
src/lib/adapters/http/probe.test.ts (1)
871-946: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMinor duplication: repeated argv literal across test cases.
The same
["-sS", "--max-time", "15", "https://example.test/v1/messages"]array is repeated in each new test case. Extracting it to a sharedconstwould reduce duplication without affecting behavioral coverage.🤖 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/adapters/http/probe.test.ts` around lines 871 - 946, The new probe tests repeat the same Anthropic streaming argv literal in multiple cases, so extract that shared argument array into a single const in probe.test.ts and reuse it across the affected runAnthropicStreamingEventProbe calls. Keep the existing test behavior the same, and use the shared symbol near mockStreaming and runAnthropicStreamingEventProbe to make the repeated setup easier to maintain.
🤖 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.
Duplicate comments:
In `@src/lib/adapters/http/probe.ts`:
- Around line 617-629: The Anthropic sequence validation in
anthropicSequenceErrors only checks message_stop against content_block_delta, so
it can miss non-terminal stops when other known events appear after it. Update
the logic to compare message_stop against the full set of known Anthropic
content/message payload events in eventSequence, using the relevant first/last
index checks in anthropicSequenceErrors, while continuing to ignore unknown
interleavings like ping.
---
Nitpick comments:
In `@src/lib/adapters/http/probe.test.ts`:
- Around line 871-946: The new probe tests repeat the same Anthropic streaming
argv literal in multiple cases, so extract that shared argument array into a
single const in probe.test.ts and reuse it across the affected
runAnthropicStreamingEventProbe calls. Keep the existing test behavior the same,
and use the shared symbol near mockStreaming and runAnthropicStreamingEventProbe
to make the repeated setup easier to maintain.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 15ff264c-0ced-4524-8ff1-975383c94247
📒 Files selected for processing (4)
src/lib/adapters/http/probe.test.tssrc/lib/adapters/http/probe.tssrc/lib/inference/probe-anthropic.test.tstest/onboard-selection-anthropic-retry.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/lib/inference/probe-anthropic.test.ts
- test/onboard-selection-anthropic-retry.test.ts
…ecks Address CodeRabbit follow-up on NVIDIA#6297: message_stop terminality was only checked against content_block_delta, so a stream ending message_stop -> content_block_stop still passed. Compare against the full known payload-event set (content_block_start/delta/stop, message_delta) while continuing to ignore unknown interleavings like ping. Signed-off-by: Tony Luo <xialuo@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/inference/probe-anthropic.test.ts (1)
90-97: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRepeated streaming-probe mock payload boilerplate across tests.
The
{ ok, curlStatus, missingEvents, duplicateEvents, sequenceErrors, message }shape is duplicated across five tests with only a couple of fields varying. A small factory (e.g.,makeStreamingResult(overrides)) would reduce duplication and make future field additions (likecurlStatus, added in this PR) a one-place change.♻️ Suggested helper
function streamingResult( overrides: Partial<ReturnType<typeof probe.runAnthropicStreamingEventProbe>> = {}, ) { return { ok: true, curlStatus: 0, missingEvents: [], duplicateEvents: [], sequenceErrors: [], message: "", ...overrides, }; }Also applies to: 126-133, 166-176, 203-210, 240-247
🤖 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/inference/probe-anthropic.test.ts` around lines 90 - 97, The streaming probe tests duplicate the same mock result shape in multiple places, so replace the repeated inline objects in probe-anthropic.test.ts with a small helper like a streamingResult/makeStreamingResult factory near the existing runAnthropicStreamingEventProbe spies. Use that helper in each test and pass only the per-test overrides, keeping the default fields centralized so future additions like curlStatus only need one update.
🤖 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/inference/probe-anthropic.test.ts`:
- Around line 90-97: The streaming probe tests duplicate the same mock result
shape in multiple places, so replace the repeated inline objects in
probe-anthropic.test.ts with a small helper like a
streamingResult/makeStreamingResult factory near the existing
runAnthropicStreamingEventProbe spies. Use that helper in each test and pass
only the per-test overrides, keeping the default fields centralized so future
additions like curlStatus only need one update.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: f0066ab4-c793-499d-a53d-4ef7b9aca8e5
📒 Files selected for processing (4)
src/lib/adapters/http/probe.test.tssrc/lib/adapters/http/probe.tssrc/lib/inference/probe-anthropic.test.tssrc/lib/inference/probe-anthropic.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/lib/adapters/http/probe.test.ts
- src/lib/inference/probe-anthropic.ts
- src/lib/adapters/http/probe.ts
Map malformed Anthropic SSE results to fixed diagnostic codes. Render only allowlisted messages while preserving raw-provider suppression. Keep HTTP and curl precedence so timeout recovery remains unchanged. Signed-off-by: Carlos Villela <cvillela@nvidia.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/onboard/probe-diagnostics.test.ts (1)
27-44: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueTest doesn't exercise the added
diagnosticCodesfield.
diagnosticCodeswas added to this failure object (Line 36), but sincecurlStatus: 28is non-zero,summarizeProbeFailureForDisplayreturns before the diagnostics branch runs. The assertions only check the pre-existing curl-exit summary, so this addition isn't actually verified by the test. Consider removing it here if it's not meant to test anything, or moving this coverage to the new streaming test below.🤖 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/probe-diagnostics.test.ts` around lines 27 - 44, The new diagnosticCodes field in this probe test is not actually being exercised because summarizeProbeFailureForDisplay exits early on the curlStatus path. Update the probe diagnostics tests so this case either removes the unused diagnosticCodes entry from the curl/timeout failure fixture, or move that assertion into the streaming-related test that reaches the diagnostics branch in summarizeProbeForDisplay/summarizeProbeFailureForDisplay.
🤖 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/probe-diagnostics.test.ts`:
- Around line 27-44: The new diagnosticCodes field in this probe test is not
actually being exercised because summarizeProbeFailureForDisplay exits early on
the curlStatus path. Update the probe diagnostics tests so this case either
removes the unused diagnosticCodes entry from the curl/timeout failure fixture,
or move that assertion into the streaming-related test that reaches the
diagnostics branch in summarizeProbeForDisplay/summarizeProbeFailureForDisplay.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: aa1f675e-1dd9-4ed5-b36f-987053369a5f
📒 Files selected for processing (5)
src/lib/inference/probe-anthropic.test.tssrc/lib/inference/probe-anthropic.tssrc/lib/onboard/inference-selection-validation.test.tssrc/lib/onboard/probe-diagnostics.test.tssrc/lib/onboard/probe-diagnostics.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/lib/onboard/inference-selection-validation.test.ts
- src/lib/inference/probe-anthropic.test.ts
- src/lib/inference/probe-anthropic.ts
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
## Summary Fix Hermes custom Anthropic routing by using the endpoint's verified OpenAI Chat Completions surface end to end. NemoClaw selects `https://inference.local/v1`, verifies `/v1/chat/completions`, and aligns the OpenShell provider to `type=openai` with `OPENAI_BASE_URL`, avoiding the duplicate Anthropic SSE `message_start` sequence that caused `hermes -z` to finish with `no final response`. The core managed-frontend direction was first proposed by @chengjiew in #6295, and Chengjie Wang is included as a commit co-author. @TonyLuo-NV's #6297 contributed streaming-failure investigation and regression analysis. Thanks to @hulynn for the reproducible managed-proxy report. ## Related Issue Fixes #6289 ## Changes - Resolve Hermes `compatible-anthropic-endpoint` routes to the managed `openai-completions` frontend and reuse #6298's verified OpenAI-surface provider registration while retaining `COMPATIBLE_ANTHROPIC_API_KEY` as the credential binding. - Persist the normalized frontend during fresh onboarding; repair stale provider identity, registry metadata, and sandbox configuration during rebuild or resume. - Reject conflicting explicit API choices and legacy `type=anthropic` runtime switches before mutating OpenShell, registry, or in-sandbox state. - Preserve native Anthropic Messages routing for OpenClaw custom endpoints and first-party Anthropic routes; preserve the existing AWS Bedrock adapter behavior. - Extend unit, integration, command-shape, and live E2E coverage, including the reported `hermes -z` path; document the verified-surface requirement and rebuild migration. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [x] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [x] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [ ] Tests not applicable — justification: - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [x] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [x] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: independent final review found no blockers. Endpoint probing and provider replacement reuse the fail-closed #6298 boundary; this PR adds exact non-secret provider identity checks and introduces no credential values. Human maintainer approval remains required. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification - [x] PR description includes the DCO sign-off declaration 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 — 289 CLI tests, 7 OpenAI-surface onboarding integration tests, 1 focused Hermes config integration test, and 18 E2E support tests passed - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — required GitHub Actions checks pending - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) — completed with 0 errors and 2 existing Fern warnings - [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) Additional local verification: - `npm run build:cli` - `npm run typecheck:cli` - `npm run checks` - `npm run test-size:check` - `npm run test:titles:check` - `npm run source-shape:check` - `npm run test:projects:check` - `npm run test:imports:check` - `npm run docs` (0 errors; 2 existing warnings) --- Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> --------- Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> Signed-off-by: Chengjie Wang <chengjiew@nvidia.com> Co-authored-by: Chengjie Wang <chengjiew@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
cv
left a comment
There was a problem hiding this comment.
Maintainer review: the bounded SSE probe validates the expected event sequence, preserves credential-file handling, and has focused malformed-stream and timeout coverage. CI, DCO, commit verification, and review-thread checks are clean.
<!-- markdownlint-disable MD041 --> ## Summary Prepares the user-facing documentation for NemoClaw v0.0.76 and closes the release-prep documentation gate. It adds the release highlights, documents the arm64 Local NIM warning and expanded image cleanup behavior, and fixes agent-specific command headings in generated guides. ## Changes - Add the v0.0.76 release-notes section and move the shared-gateway route containment entry out of the v0.0.74 history where it was incorrectly placed. - Document the advisory Linux arm64 Local NIM manifest warning in the canonical platform matrix and local-inference guidance. - Document that `gc` scans both gateway-built and locally prebuilt sandbox image repositories. - Keep OpenClaw and Hermes session headings out of the generated Deep Agents command guide. - Add a focused variant regression test for the agent-specific session headings. ### Source summary | Merged sources | Documentation coverage | | --- | --- | | [#6414](#6414), [#6418](#6418), [#6416](#6416), [#6344](#6344) | v0.0.76 release notes and the Deep Agents quickstart/inference routes | | [#6340](#6340) | v0.0.76 release notes and existing Deep Agents observability guidance | | [#6338](#6338), [#6378](#6378), [#6297](#6297) | v0.0.76 release notes and existing inference/troubleshooting guidance | | [#6362](#6362) | v0.0.76 release notes and existing lifecycle, command, and credential guidance | | [#6330](#6330), [#6307](#6307), [#6008](#6008) | v0.0.76 release notes and existing security, troubleshooting, and command guidance | | [#6382](#6382) | v0.0.76 release notes and existing MCP/command guidance | | [#6326](#6326), [#5868](#5868), [#5539](#5539) | v0.0.76 release notes, platform matrix, inference options, and local-inference guidance | | [#6396](#6396), [#6390](#6390), [#6007](#6007) | v0.0.76 release notes and existing messaging guidance | | [#5388](#5388), [#6249](#6249), [#6303](#6303), [#6306](#6306) | v0.0.76 release notes and command/lifecycle guidance | ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [x] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [x] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [ ] Tests not applicable — justification: - [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 the DCO sign-off declaration 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 --project integration test/generate-platform-docs.test.ts test/agent-variant-docs.test.ts test/sync-agent-variant-docs.test.ts` (3 files, 29 tests passed) - [ ] 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 - [ ] `npm run docs` builds without warnings (doc changes only) — completed with 0 errors and 2 pre-existing Fern warnings - [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: Apurv Kumaria <akumaria@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added v0.0.76 release notes content, and removed an older conflicting bullet from the surrounding release history. * Expanded Local NVIDIA NIM guidance across inference/provider docs, including an advisory for Linux arm64 DGX Spark/DGX Station hosts when a matching `linux/arm64` image manifest is unavailable. * Updated the command reference for correct session-section rendering and clarified `gc` image cleanup sources. * **Tests** * Added coverage ensuring Deep Agents omits sessions headings while Hermes includes them. * **CI** * Refreshed Local NVIDIA NIM provider notes used in the platform matrix. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
## Summary Fix Hermes custom Anthropic routing by using the endpoint's verified OpenAI Chat Completions surface end to end. NemoClaw selects `https://inference.local/v1`, verifies `/v1/chat/completions`, and aligns the OpenShell provider to `type=openai` with `OPENAI_BASE_URL`, avoiding the duplicate Anthropic SSE `message_start` sequence that caused `hermes -z` to finish with `no final response`. The core managed-frontend direction was first proposed by @chengjiew in NVIDIA#6295, and Chengjie Wang is included as a commit co-author. @TonyLuo-NV's NVIDIA#6297 contributed streaming-failure investigation and regression analysis. Thanks to @hulynn for the reproducible managed-proxy report. ## Related Issue Fixes NVIDIA#6289 ## Changes - Resolve Hermes `compatible-anthropic-endpoint` routes to the managed `openai-completions` frontend and reuse NVIDIA#6298's verified OpenAI-surface provider registration while retaining `COMPATIBLE_ANTHROPIC_API_KEY` as the credential binding. - Persist the normalized frontend during fresh onboarding; repair stale provider identity, registry metadata, and sandbox configuration during rebuild or resume. - Reject conflicting explicit API choices and legacy `type=anthropic` runtime switches before mutating OpenShell, registry, or in-sandbox state. - Preserve native Anthropic Messages routing for OpenClaw custom endpoints and first-party Anthropic routes; preserve the existing AWS Bedrock adapter behavior. - Extend unit, integration, command-shape, and live E2E coverage, including the reported `hermes -z` path; document the verified-surface requirement and rebuild migration. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [x] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [x] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [ ] Tests not applicable — justification: - [x] Docs updated for user-facing behavior changes - [ ] Docs not applicable — justification: - [x] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [x] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: independent final review found no blockers. Endpoint probing and provider replacement reuse the fail-closed NVIDIA#6298 boundary; this PR adds exact non-secret provider identity checks and introduces no credential values. Human maintainer approval remains required. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification - [x] PR description includes the DCO sign-off declaration 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 — 289 CLI tests, 7 OpenAI-surface onboarding integration tests, 1 focused Hermes config integration test, and 18 E2E support tests passed - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — required GitHub Actions checks pending - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) — completed with 0 errors and 2 existing Fern warnings - [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) Additional local verification: - `npm run build:cli` - `npm run typecheck:cli` - `npm run checks` - `npm run test-size:check` - `npm run test:titles:check` - `npm run source-shape:check` - `npm run test:projects:check` - `npm run test:imports:check` - `npm run docs` (0 errors; 2 existing warnings) --- Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> --------- Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> Signed-off-by: Chengjie Wang <chengjiew@nvidia.com> Co-authored-by: Chengjie Wang <chengjiew@nvidia.com>
…nboarding (NVIDIA#6289) (NVIDIA#6297) ## Summary Custom Anthropic-compatible endpoints were validated with a non-streaming `/v1/messages` probe only, so endpoints whose SSE streaming layer is malformed (e.g. duplicate `message_start` events with the same message id, observed on the Inference Hub route) passed onboarding and then failed at runtime inside the sandbox with Hermes' cryptic `no final response was produced` (exit 1). This PR adds streaming-event validation to the custom Anthropic onboarding path — mirroring the existing `/v1/responses` streaming validation from NVIDIA#1833 — so the defect is diagnosed at onboarding time with an actionable message. ## Related Issue Refs NVIDIA#6289 This PR is the onboarding guardrail for the malformed Anthropic SSE signature. It intentionally rejects a broken compatible endpoint before sandbox creation; the functional runtime routing fix remains in NVIDIA#6295. ## Changes - Add `runAnthropicStreamingEventProbe` (`src/lib/adapters/http/probe.ts`): sends a `stream: true` request to `/v1/messages` and validates the SSE event sequence — exactly one `message_start`, at least one `content_block_delta`, one `message_stop`. Refactors the shared curl/SSE capture into `captureSseEventCounts`, reused by the existing `/v1/responses` streaming probe with identical behavior (trace events, temp cleanup, curl exit-28 tolerance). - Wire the streaming probe into `probeAnthropicEndpoint` behind a new `{ probeStreaming }` option (`src/lib/inference/probe-anthropic.ts`); tighter `--max-time 15` timing so validation cannot hang the wizard. - Enable it in `validateCustomAnthropicSelection` (`src/lib/onboard/inference-selection-validation.ts`). Skipped when `NEMOCLAW_REASONING=true`, matching the custom OpenAI-compatible path. The official Anthropic provider path is unchanged; Bedrock-classified endpoints are unaffected (streaming probe only runs after the non-streaming `/v1/messages` probe succeeds). - Move the two Anthropic credential-retry integration tests into a focused `test/onboard-selection-anthropic-retry.test.ts` (fake curl now serves a well-formed SSE stream for `"stream":true` probe bodies), shrinking `test/onboard-selection.test.ts` below its legacy size budget; budget ratcheted down 6146 → 5935. - Docs: validation-table row and Anthropic-compatible server section in `docs/inference/inference-options.mdx`; new troubleshooting entry for the onboarding-time duplicate `message_start` failure in `docs/reference/troubleshooting.mdx`. ## Type of Change - [x] Code change with doc updates ## Quality Gates - [x] Tests added or updated for changed behavior - [x] Docs updated for user-facing behavior changes - [x] 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: requesting maintainer review; probes reuse the existing trusted `--config` credential routing (no credential appears in argv), and the new probe adds no new credential surface. ## Verification - [x] PR description includes the DCO sign-off declaration 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 — command/result: `npx vitest run src/lib/adapters/http/probe.test.ts src/lib/inference/probe-anthropic.test.ts src/lib/onboard/inference-selection-validation.test.ts --project cli` (68 passed); `npx vitest run test/onboard-selection.test.ts --project integration` (67 passed); `npx vitest run test/onboard-selection-anthropic-retry.test.ts --project integration` (2 passed); `npx vitest run src/lib/inference/onboard-probes.test.ts src/lib/inference/onboard-probes-responses-fallback.test.ts --project cli` (25 passed, 1 skipped); `npm run test:projects:check` (disjoint); `npm run typecheck:cli` (clean) - [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) — 0 errors; 2 pre-existing warnings on main (login-gated redirects check, theme contrast), unrelated to this change ## DCO Signed-off-by: Tony Luo <xialuo@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added Anthropic-compatible streaming SSE validation during onboarding to catch malformed `/v1/messages` event sequences. * Streaming validation can be skipped for reasoning-only models via `NEMOCLAW_REASONING`. * **Bug Fixes** * Improved reporting and recovery behavior for missing, duplicate, and out-of-order streaming events, including clearer diagnostic messaging. * **Documentation** * Updated inference validation docs and added troubleshooting guidance for onboarding failures caused by malformed SSE events. * **Tests** * Expanded streaming probe and onboarding validation tests; added Anthropic onboarding retry UX coverage; removed obsolete Anthropic retry tests. * **Chores** * Adjusted CI test file size budget. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Tony Luo <xialuo@nvidia.com> Signed-off-by: Carlos Villela <cvillela@nvidia.com> Co-authored-by: Carlos Villela <cvillela@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary Prepares the user-facing documentation for NemoClaw v0.0.76 and closes the release-prep documentation gate. It adds the release highlights, documents the arm64 Local NIM warning and expanded image cleanup behavior, and fixes agent-specific command headings in generated guides. ## Changes - Add the v0.0.76 release-notes section and move the shared-gateway route containment entry out of the v0.0.74 history where it was incorrectly placed. - Document the advisory Linux arm64 Local NIM manifest warning in the canonical platform matrix and local-inference guidance. - Document that `gc` scans both gateway-built and locally prebuilt sandbox image repositories. - Keep OpenClaw and Hermes session headings out of the generated Deep Agents command guide. - Add a focused variant regression test for the agent-specific session headings. ### Source summary | Merged sources | Documentation coverage | | --- | --- | | [NVIDIA#6414](NVIDIA#6414), [NVIDIA#6418](NVIDIA#6418), [NVIDIA#6416](NVIDIA#6416), [NVIDIA#6344](NVIDIA#6344) | v0.0.76 release notes and the Deep Agents quickstart/inference routes | | [NVIDIA#6340](NVIDIA#6340) | v0.0.76 release notes and existing Deep Agents observability guidance | | [NVIDIA#6338](NVIDIA#6338), [NVIDIA#6378](NVIDIA#6378), [NVIDIA#6297](NVIDIA#6297) | v0.0.76 release notes and existing inference/troubleshooting guidance | | [NVIDIA#6362](NVIDIA#6362) | v0.0.76 release notes and existing lifecycle, command, and credential guidance | | [NVIDIA#6330](NVIDIA#6330), [NVIDIA#6307](NVIDIA#6307), [NVIDIA#6008](NVIDIA#6008) | v0.0.76 release notes and existing security, troubleshooting, and command guidance | | [NVIDIA#6382](NVIDIA#6382) | v0.0.76 release notes and existing MCP/command guidance | | [NVIDIA#6326](NVIDIA#6326), [NVIDIA#5868](NVIDIA#5868), [NVIDIA#5539](NVIDIA#5539) | v0.0.76 release notes, platform matrix, inference options, and local-inference guidance | | [NVIDIA#6396](NVIDIA#6396), [NVIDIA#6390](NVIDIA#6390), [NVIDIA#6007](NVIDIA#6007) | v0.0.76 release notes and existing messaging guidance | | [NVIDIA#5388](NVIDIA#5388), [NVIDIA#6249](NVIDIA#6249), [NVIDIA#6303](NVIDIA#6303), [NVIDIA#6306](NVIDIA#6306) | v0.0.76 release notes and command/lifecycle guidance | ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [x] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [x] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [ ] Tests not applicable — justification: - [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 the DCO sign-off declaration 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 --project integration test/generate-platform-docs.test.ts test/agent-variant-docs.test.ts test/sync-agent-variant-docs.test.ts` (3 files, 29 tests passed) - [ ] 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 - [ ] `npm run docs` builds without warnings (doc changes only) — completed with 0 errors and 2 pre-existing Fern warnings - [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: Apurv Kumaria <akumaria@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added v0.0.76 release notes content, and removed an older conflicting bullet from the surrounding release history. * Expanded Local NVIDIA NIM guidance across inference/provider docs, including an advisory for Linux arm64 DGX Spark/DGX Station hosts when a matching `linux/arm64` image manifest is unavailable. * Updated the command reference for correct session-section rendering and clarified `gc` image cleanup sources. * **Tests** * Added coverage ensuring Deep Agents omits sessions headings while Hermes includes them. * **CI** * Refreshed Local NVIDIA NIM provider notes used in the platform matrix. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Summary
Custom Anthropic-compatible endpoints were validated with a non-streaming
/v1/messagesprobe only, so endpoints whose SSE streaming layer is malformed (e.g. duplicatemessage_startevents with the same message id, observed on the Inference Hub route) passed onboarding and then failed at runtime inside the sandbox with Hermes' crypticno final response was produced(exit 1). This PR adds streaming-event validation to the custom Anthropic onboarding path — mirroring the existing/v1/responsesstreaming validation from #1833 — so the defect is diagnosed at onboarding time with an actionable message.Related Issue
Refs #6289
This PR is the onboarding guardrail for the malformed Anthropic SSE signature. It intentionally rejects a broken compatible endpoint before sandbox creation; the functional runtime routing fix remains in #6295.
Changes
runAnthropicStreamingEventProbe(src/lib/adapters/http/probe.ts): sends astream: truerequest to/v1/messagesand validates the SSE event sequence — exactly onemessage_start, at least onecontent_block_delta, onemessage_stop. Refactors the shared curl/SSE capture intocaptureSseEventCounts, reused by the existing/v1/responsesstreaming probe with identical behavior (trace events, temp cleanup, curl exit-28 tolerance).probeAnthropicEndpointbehind a new{ probeStreaming }option (src/lib/inference/probe-anthropic.ts); tighter--max-time 15timing so validation cannot hang the wizard.validateCustomAnthropicSelection(src/lib/onboard/inference-selection-validation.ts). Skipped whenNEMOCLAW_REASONING=true, matching the custom OpenAI-compatible path. The official Anthropic provider path is unchanged; Bedrock-classified endpoints are unaffected (streaming probe only runs after the non-streaming/v1/messagesprobe succeeds).test/onboard-selection-anthropic-retry.test.ts(fake curl now serves a well-formed SSE stream for"stream":trueprobe bodies), shrinkingtest/onboard-selection.test.tsbelow its legacy size budget; budget ratcheted down 6146 → 5935.docs/inference/inference-options.mdx; new troubleshooting entry for the onboarding-time duplicatemessage_startfailure indocs/reference/troubleshooting.mdx.Type of Change
Quality Gates
--configcredential routing (no credential appears in argv), and the new probe adds no new credential surface.Verification
Verifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailablenpx vitest run src/lib/adapters/http/probe.test.ts src/lib/inference/probe-anthropic.test.ts src/lib/onboard/inference-selection-validation.test.ts --project cli(68 passed);npx vitest run test/onboard-selection.test.ts --project integration(67 passed);npx vitest run test/onboard-selection-anthropic-retry.test.ts --project integration(2 passed);npx vitest run src/lib/inference/onboard-probes.test.ts src/lib/inference/onboard-probes-responses-fallback.test.ts --project cli(25 passed, 1 skipped);npm run test:projects:check(disjoint);npm run typecheck:cli(clean)npm run docsbuilds without warnings (doc changes only) — 0 errors; 2 pre-existing warnings on main (login-gated redirects check, theme contrast), unrelated to this changeDCO
Signed-off-by: Tony Luo xialuo@nvidia.com
Summary by CodeRabbit
/v1/messagesevent sequences.NEMOCLAW_REASONING.