Skip to content

fix: support reasoning compatible endpoints (Fixes #3279) - #3286

Closed
deepujain wants to merge 4 commits into
NVIDIA:mainfrom
deepujain:fix/3279-compatible-reasoning-flag
Closed

fix: support reasoning compatible endpoints (Fixes #3279)#3286
deepujain wants to merge 4 commits into
NVIDIA:mainfrom
deepujain:fix/3279-compatible-reasoning-flag

Conversation

@deepujain

@deepujain deepujain commented May 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Custom OpenAI-compatible providers can opt into reasoning-mode validation through NEMOCLAW_REASONING. When that flag is enabled, NemoClaw skips the Responses/tool-call probe that reasoning-only wrappers often reject, and the sandbox smoke check accepts reasoning text as valid output.

Fixes #3279.

Changes

  • Normalized NEMOCLAW_REASONING aliases such as yes, 1, no, and 0.
  • Persisted compatible-endpoint reasoning state through onboarding session updates and provider resume.
  • Skipped Responses/tool-call and streaming probes for reasoning-mode compatible endpoints.
  • Increased the sandbox smoke response budget and accepted reasoning_content or reasoning when message.content is empty.
  • Added focused tests for flag normalization, provider state handoff, session persistence, and the custom endpoint reasoning path.

Testing

  • npm run build:cli passed.
  • npm run typecheck:cli passed.
  • npm test -- test/onboard-selection.test.ts -t "honors NEMOCLAW_REASONING" passed.
  • npm test -- src/lib/onboard/machine/handlers/provider-inference.test.ts src/lib/state/onboard-session.test.ts src/lib/onboard/compatible-endpoint-smoke.test.ts passed.
  • HOME=/private/tmp/nemoclaw-test-home-3279-rebase npm test -- --reporter=dot was attempted; it timed out locally after 180s before completing.

Evidence it works

The focused custom endpoint test simulates a reasoning-only chat response with empty content and non-empty reasoning_content. With NEMOCLAW_REASONING=yes, onboarding accepts the provider, avoids /responses and streaming probes, and keeps preferredInferenceApi on chat completions. Session tests cover persisting and clearing the reasoning flag during provider handoff and resume.

Signed-off-by: Deepak Jain deepujain@gmail.com

Summary by CodeRabbit

  • New Features
    • Added support for a compatible-endpoint reasoning mode during onboarding, with the chosen setting preserved across sessions and restored when resuming setup.
  • Bug Fixes
    • Improved validation for custom OpenAI-compatible endpoints so onboarding adapts correctly when reasoning features are enabled.
    • Enhanced endpoint smoke checks to better handle different response formats and larger outputs.
  • Documentation
    • Updated platform and provider reference notes to match the latest onboarding behavior.

@copy-pr-bot

copy-pr-bot Bot commented May 8, 2026

Copy link
Copy Markdown

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

coderabbitai Bot commented May 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a NEMOCLAW_REASONING reasoning-mode flag for the "Other OpenAI-compatible endpoint" provider. Two new helpers normalize and apply the flag via process.env. The onboarding session gains a compatibleEndpointReasoning field. Validation probes and the sandbox smoke test branch on the flag. Doc and CI line references are updated to reflect shifted line numbers.

Changes

Reasoning mode for OpenAI-compatible endpoints

Layer / File(s) Summary
Reasoning helpers and exports
src/lib/onboard.ts
normalizeReasoningFlag() maps truthy/falsy aliases to "true", "false", or null; configureCompatibleEndpointReasoning() sets or clears process.env.NEMOCLAW_REASONING and returns the resolved value. Both are exported.
Session persistence for reasoning flag
src/lib/state/onboard-session.ts
Session and SessionUpdates gain compatibleEndpointReasoning; createSession(), normalizeSession(), filterSafeUpdates(), and summarizeForDebug() are updated to read, write, whitelist, and surface the field.
Provider selection, resume, and probe wiring
src/lib/onboard.ts
configureCompatibleEndpointReasoning() is called during custom-provider selection and onboarding resume; the result flows through toSessionUpdates() and setupNim() return; validateCustomOpenAiLikeSelection() branches tool-calling requirements, responses-probe inclusion, and streaming on NEMOCLAW_REASONING === "true".
Sandbox smoke probe
src/lib/onboard.ts
max_tokens raised to 512; response text is extracted from message.content with fallbacks to message.reasoning_content and message.reasoning for reasoning-only models.
Doc and CI line reference updates
ci/platform-matrix.json, docs/inference/inference-options.mdx, docs/reference/platform-support.mdx
Embedded src/lib/onboard.ts line-number citations updated to reflect shifted line numbers after new code additions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#1956: Propagates NEMOCLAW_REASONING and token/context env vars into the sandbox image build via patchStagedDockerfile(), directly connected to the env-var wiring added here.
  • NVIDIA/NemoClaw#5932: Modifies the compatible-endpoint smoke flow to retry transient failures, touching the same probe execution path adjusted in this PR.

Suggested labels

area: onboarding, area: sandbox

Suggested reviewers

  • cv
  • jyaunches
  • ericksoa
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% 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 title clearly and concisely summarizes the main change: reasoning support for compatible endpoints.
Linked Issues check ✅ Passed The changes implement the #3279 requirements by adding runtime reasoning support, skipping incompatible probes, and handling reasoning-style responses.
Out of Scope Changes check ✅ Passed The documentation and matrix edits stay aligned with the onboarding reasoning fix and do not introduce unrelated scope.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
test/onboard-selection.test.ts (1)

2075-2094: ⚡ Quick win

Assert probe path behavior explicitly in reasoning mode.

Line [2077] and Line [2150] currently validate end-state only; this test can still pass if /responses (or streaming probe) is called and then fallback succeeds. Please log curl args and assert reasoning mode avoids /responses/-N while still hitting /chat/completions.

Suggested test hardening
@@
     const scriptPath = path.join(tmpDir, "custom-openai-reasoning-check.js");
+    const curlArgsLog = path.join(tmpDir, "custom-openai-reasoning-curl-args.log");
@@
       path.join(fakeBin, "curl"),
       `#!/usr/bin/env bash
+args_log=${JSON.stringify(curlArgsLog)}
+printf '%s\\n' "$*" >> "$args_log"
 body='{"error":{"message":"bad request"}}'
 status="400"
 outfile=""
 url=""
@@
     assert.equal(payload.result.model, "reasoning-model");
     assert.equal(payload.result.preferredInferenceApi, "openai-completions");
     assert.equal(payload.reasoning, "true");
+    const curlInvocations = fs.readFileSync(curlArgsLog, "utf-8");
+    assert.match(curlInvocations, /chat\/completions/);
+    assert.doesNotMatch(curlInvocations, /\/responses/);
+    assert.doesNotMatch(curlInvocations, /(^|\s)-N(\s|$)/);
     assert.ok(
       payload.messages.every(
         (message: string) => !/Enable reasoning mode for this model/.test(message),
       ),
     );

Also applies to: 2150-2160

🤖 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.test.ts` around lines 2075 - 2094, The fake curl
script written to path.join(fakeBin, "curl") should record its received
arguments so the test can assert probe behavior: modify the heredoc to append
the full "$@" or each processed arg into a temp log file (e.g.,
"$outfile.args.log" or a known capture file in the test dir) before handling
-o/url logic, and keep returning the same body/status logic; then update the
test assertions to read that captured args log and explicitly assert that in
reasoning mode the captured args do not include '/responses' nor the '-N' flag
and do include a call to '/chat/completions'. Ensure you reference the same
fakeBin/curl generation code and the test's reasoning-mode invocation when
adding the new assertions.
test/onboard.test.ts (1)

391-410: ⚡ Quick win

Add an explicit assertion for the unset/default reasoning path.

This test validates aliases, but not the key default behavior when NEMOCLAW_REASONING is unset. Locking that in will better guard the PR’s intended fallback semantics.

✅ Suggested test addition
   expect(normalizeReasoningFlag("maybe")).toBeNull();

+  delete process.env.NEMOCLAW_REASONING;
+  await expect(configureCompatibleEndpointReasoning()).resolves.toBe("false");
+  expect(process.env.NEMOCLAW_REASONING).toBe("false");
+
   process.env.NEMOCLAW_REASONING = "yes";
   await expect(configureCompatibleEndpointReasoning()).resolves.toBe("true");
   expect(process.env.NEMOCLAW_REASONING).toBe("true");
🤖 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.test.ts` around lines 391 - 410, Add an explicit assertion that
the "unset/default" path is covered: before setting NEMOCLAW_REASONING to "yes",
delete process.env.NEMOCLAW_REASONING (or set it to undefined) and call await
expect(configureCompatibleEndpointReasoning()).resolves.toBe(normalizeReasoningFlag(undefined));
this ensures the test asserts the function's fallback behavior when
NEMOCLAW_REASONING is not present and references the existing
normalizeReasoningFlag and configureCompatibleEndpointReasoning symbols.
🤖 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 1508-1511: The configureCompatibleEndpointReasoning function
currently stores the normalized NEMOCLAW_REASONING in process.env only, causing
stale or missing values across onboarding flows; update it to persist the
normalized value into the selected provider state object (use the same
normalization via normalizeReasoningFlag) instead of relying solely on
process.env, and ensure that when provider selection changes the stored flag is
cleared from that provider state and process.env is restored/updated
accordingly; locate configureCompatibleEndpointReasoning and related calls to
normalizeReasoningFlag and modify the provider selection/restore logic where
provider state is mutated so the flag is saved with the provider, removed on
selection change, and used to seed process.env when a provider is active (also
apply the same change pattern to the other occurrence referenced near the file's
later provider-state handling).

---

Nitpick comments:
In `@test/onboard-selection.test.ts`:
- Around line 2075-2094: The fake curl script written to path.join(fakeBin,
"curl") should record its received arguments so the test can assert probe
behavior: modify the heredoc to append the full "$@" or each processed arg into
a temp log file (e.g., "$outfile.args.log" or a known capture file in the test
dir) before handling -o/url logic, and keep returning the same body/status
logic; then update the test assertions to read that captured args log and
explicitly assert that in reasoning mode the captured args do not include
'/responses' nor the '-N' flag and do include a call to '/chat/completions'.
Ensure you reference the same fakeBin/curl generation code and the test's
reasoning-mode invocation when adding the new assertions.

In `@test/onboard.test.ts`:
- Around line 391-410: Add an explicit assertion that the "unset/default" path
is covered: before setting NEMOCLAW_REASONING to "yes", delete
process.env.NEMOCLAW_REASONING (or set it to undefined) and call await
expect(configureCompatibleEndpointReasoning()).resolves.toBe(normalizeReasoningFlag(undefined));
this ensures the test asserts the function's fallback behavior when
NEMOCLAW_REASONING is not present and references the existing
normalizeReasoningFlag and configureCompatibleEndpointReasoning symbols.
🪄 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: 78ba4585-9297-4c89-b6ae-5ad64ecf87cb

📥 Commits

Reviewing files that changed from the base of the PR and between f1568f6 and 077cb4b.

📒 Files selected for processing (3)
  • src/lib/onboard.ts
  • test/onboard-selection.test.ts
  • test/onboard.test.ts

Comment thread src/lib/onboard.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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/state/onboard-session.ts (1)

707-717: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Persist compatibleEndpointReasoning in the safe update whitelist.

SessionUpdates adds this field (Line 131), but filterSafeUpdates() never forwards it, so updates passed via markStepComplete() / completeSession() are silently dropped. That breaks both setting and clearing (null) this value during provider transitions.

Suggested fix
 export function filterSafeUpdates(updates: SessionUpdates): Partial<Session> {
   const safe: Partial<Session> = {};
   if (!isObject(updates)) return safe;
   if (typeof updates.sandboxName === "string") safe.sandboxName = updates.sandboxName;
   if (typeof updates.provider === "string") safe.provider = updates.provider;
   if (typeof updates.model === "string") safe.model = updates.model;
   if (typeof updates.endpointUrl === "string") safe.endpointUrl = redactUrl(updates.endpointUrl);
   if (typeof updates.credentialEnv === "string") safe.credentialEnv = updates.credentialEnv;
   if (typeof updates.preferredInferenceApi === "string")
     safe.preferredInferenceApi = updates.preferredInferenceApi;
+  if (typeof updates.compatibleEndpointReasoning === "string") {
+    safe.compatibleEndpointReasoning = updates.compatibleEndpointReasoning;
+  } else if (updates.compatibleEndpointReasoning === null) {
+    safe.compatibleEndpointReasoning = null;
+  }
   if (typeof updates.nimContainer === "string") safe.nimContainer = updates.nimContainer;
🤖 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/state/onboard-session.ts` around lines 707 - 717, filterSafeUpdates
currently omits the SessionUpdates field compatibleEndpointReasoning so updates
from markStepComplete/completeSession are dropped; update the function
filterSafeUpdates to accept and propagate compatibleEndpointReasoning (including
allowing null to clear it) into the returned Partial<Session> when typeof
updates.compatibleEndpointReasoning is "string" or when
updates.compatibleEndpointReasoning === null, mirroring how other
nullable/optional fields are handled so provider transitions can set and clear
this value.
🤖 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/state/onboard-session.ts`:
- Around line 707-717: filterSafeUpdates currently omits the SessionUpdates
field compatibleEndpointReasoning so updates from
markStepComplete/completeSession are dropped; update the function
filterSafeUpdates to accept and propagate compatibleEndpointReasoning (including
allowing null to clear it) into the returned Partial<Session> when typeof
updates.compatibleEndpointReasoning is "string" or when
updates.compatibleEndpointReasoning === null, mirroring how other
nullable/optional fields are handled so provider transitions can set and clear
this value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 06d7e88a-98bf-4a0d-89a9-ddd0edb6c09a

📥 Commits

Reviewing files that changed from the base of the PR and between 077cb4b and 66bbe29.

📒 Files selected for processing (4)
  • src/lib/onboard.ts
  • src/lib/state/onboard-session.ts
  • test/onboard-selection.test.ts
  • test/onboard.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/onboard-selection.test.ts
  • test/onboard.test.ts
  • src/lib/onboard.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/lib/state/onboard-session.ts (1)

145-166: ⚡ Quick win

Include compatibleEndpointReasoning in debug summary output.

The new persisted field is not exposed by DebugSessionSummary/summarizeForDebug, which makes reasoning-mode resume issues harder to diagnose from debug dumps.

Proposed patch
 export interface DebugSessionSummary {
   version: number;
   sessionId: string;
   status: string;
   resumable: boolean;
   mode: string;
   startedAt: string;
   updatedAt: string;
   sandboxName: string | null;
   provider: string | null;
   model: string | null;
   endpointUrl: string | null;
   credentialEnv: string | null;
   preferredInferenceApi: string | null;
+  compatibleEndpointReasoning: string | null;
   nimContainer: string | null;
   policyPresets: string[] | null;
   gpuPassthrough: boolean;
   lastStepStarted: string | null;
   lastCompletedStep: string | null;
   failure: SessionFailure | null;
   steps: Record<string, StepState>;
 }
@@
     endpointUrl: redactUrl(session.endpointUrl),
     credentialEnv: session.credentialEnv,
     preferredInferenceApi: session.preferredInferenceApi,
+    compatibleEndpointReasoning: session.compatibleEndpointReasoning,
     nimContainer: session.nimContainer,
     policyPresets: session.policyPresets,

Also applies to: 852-867

🤖 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/state/onboard-session.ts` around lines 145 - 166, DebugSessionSummary
and the summarizeForDebug output are missing the new persisted field
compatibleEndpointReasoning, so add compatibleEndpointReasoning: string | null
(matching the persisted type) to the DebugSessionSummary interface and update
the summarizeForDebug function to read the session-compatibleEndpointReasoning
value and include it in the returned summary object (alongside fields like
failure, steps, nimContainer, preferredInferenceApi, etc.) so debug dumps expose
reasoning-mode compatibility; update any related spots mentioned (e.g., the
summarizeForDebug implementation around the lastStep/lastCompletedStep logic) to
populate this field.
🤖 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/state/onboard-session.ts`:
- Around line 145-166: DebugSessionSummary and the summarizeForDebug output are
missing the new persisted field compatibleEndpointReasoning, so add
compatibleEndpointReasoning: string | null (matching the persisted type) to the
DebugSessionSummary interface and update the summarizeForDebug function to read
the session-compatibleEndpointReasoning value and include it in the returned
summary object (alongside fields like failure, steps, nimContainer,
preferredInferenceApi, etc.) so debug dumps expose reasoning-mode compatibility;
update any related spots mentioned (e.g., the summarizeForDebug implementation
around the lastStep/lastCompletedStep logic) to populate this field.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f8e80300-8c3d-41f3-be29-8da2e7314cd8

📥 Commits

Reviewing files that changed from the base of the PR and between 66bbe29 and 2c1672b.

📒 Files selected for processing (1)
  • src/lib/state/onboard-session.ts

@wscurran wscurran added enhancement: provider provider: openai OpenAI API or OpenAI-compatible provider behavior and removed v0.0.39 labels May 11, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this detailed PR about supporting reasoning-compatible endpoints for custom OpenAI providers. This change aims to improve the compatibility of NemoClaw with reasoning-mode validation through the NEMOCLAW_REASONING flag.


Related open issues:

@deepujain

Copy link
Copy Markdown
Contributor Author

Rebased on current main and trimmed the accidental test-file expansion so the diff stays focused. build:cli plus focused reasoning/session/provider tests pass.

@deepujain

Copy link
Copy Markdown
Contributor Author

Follow-up: moved the reasoning-mode helpers under src/lib/onboard/ so the top-level onboard entrypoint is net-neutral for the growth guard. build:cli and the focused reasoning/session/provider tests pass.

@wscurran wscurran added area: inference Inference routing, serving, model selection, or outputs area: providers Inference provider integrations and provider behavior bug-fix PR fixes a bug or regression feature PR adds or expands user-visible functionality needs: rebase PR needs rebase or conflict resolution and removed enhancement: provider labels Jun 3, 2026
@deepujain
deepujain force-pushed the fix/3279-compatible-reasoning-flag branch from f1a0314 to 17b9109 Compare June 4, 2026 19:40
@deepujain

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and kept the onboard entrypoint net-neutral. build:cli plus the focused reasoning, session, provider, and onboard-selection tests pass.

@wscurran wscurran removed the feature PR adds or expands user-visible functionality label Jun 9, 2026
@deepujain
deepujain force-pushed the fix/3279-compatible-reasoning-flag branch from 17b9109 to a33d3d8 Compare June 9, 2026 04:42
@deepujain

Copy link
Copy Markdown
Contributor Author

Rebased on current main, re-signed the commit stack, and cleaned up the PR body DCO sign-off. Build, typecheck, and focused reasoning/session tests pass locally. Ready for another look.

@deepujain
deepujain force-pushed the fix/3279-compatible-reasoning-flag branch from a33d3d8 to 8a84fb3 Compare June 9, 2026 04:45
@deepujain

Copy link
Copy Markdown
Contributor Author

Follow-up: fixed the growth guard by keeping the top-level onboard entrypoint net-negative against main. Build, typecheck, and the focused reasoning/session tests still pass locally.

@deepujain
deepujain force-pushed the fix/3279-compatible-reasoning-flag branch from 8a84fb3 to 0a86ee8 Compare June 9, 2026 04:48
@deepujain

Copy link
Copy Markdown
Contributor Author

One more cleanup: moved the reasoning selection coverage into a focused test file so the legacy test-size budget stays at its limit. Build, typecheck, and the focused tests pass locally.

@deepujain
deepujain force-pushed the fix/3279-compatible-reasoning-flag branch from 0a86ee8 to cbf49c2 Compare June 14, 2026 16:35
@deepujain

Copy link
Copy Markdown
Contributor Author

Rebased on current main and carried compatible reasoning through the core onboarding flow context. Build, typecheck, lint, source-shape, and focused reasoning/session/onboarding tests pass locally.

@wscurran wscurran added the VDR Linked to VDR finding label Jun 26, 2026
@deepujain
deepujain force-pushed the fix/3279-compatible-reasoning-flag branch from cbf49c2 to 351059f Compare June 27, 2026 03:04
@deepujain

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and carried the compatible-endpoint reasoning state through the migrated provider/flow helpers. Build, typecheck, lint, source-shape, and focused reasoning/provider-flow tests pass.

@deepujain

Copy link
Copy Markdown
Contributor Author

Fixed the growth-guardrail failure as well: the onboard entrypoint is now net-neutral for this PR while keeping the reasoning helper behavior in the extracted module. Re-ran build, typecheck, lint, source-shape, and the focused reasoning/provider-flow tests.

cv added a commit that referenced this pull request Jun 29, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 sentences: what this PR does and why. -->

Custom OpenAI-compatible providers can opt into reasoning-mode
validation through `NEMOCLAW_REASONING`, preserving that choice through
provider handoff and resume. This clean-history replacement supersedes
#3286 while retaining Deepak Jain's attribution and all fixes from its
review.

## Related Issue
<!-- Fixes #NNN or Closes #NNN. Remove this section if none. -->

Fixes #3279.
Supersedes #3286.

## Changes
<!-- Bullet list of key changes. -->

- Normalize common reasoning aliases and persist explicit set and clear
operations in onboarding session state.
- Skip Responses API, tool-call, and streaming probes that
reasoning-only compatible endpoints reject.
- Retry length-limited `reasoning_content` and `reasoning` smoke
responses with a larger output budget, then fail clearly if final
content remains empty.
- Carry reasoning state through provider selection, resume, flow
context, debug summaries, and sandbox creation.
- Add focused source and package-contract coverage for aliases, probe
selection, persistence, null clearing, resume, and response fallback
behavior.
- Keep `src/lib/onboard.ts` net-neutral and synchronize generated
platform documentation citations.
- Validation: CLI build and typecheck, focused source tests, the
package-contract test, 18 platform-doc generator tests, full commit
hooks, and push hooks pass. `npm run docs` reports zero errors and two
pre-existing Fern warnings.

## 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
<!-- Check all that apply. For any "covered by existing tests", "not
applicable", or waiver entry, add a brief justification on the same line
or in the Changes section. -->
- [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: maintainer salvage
review completed; all historical CodeRabbit findings and the resolved
thread in #3286 were incorporated
and revalidated.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification
<!-- Check each item you ran and confirmed. Leave unchecked items you
skipped. Doc-only changes do not require npm test unless you ran it. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior
- [ ] Full `npm test` passes (broad runtime changes only)
- [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)
- [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)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


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

* **New Features**
* Added a new reasoning mode for compatible OpenAI-style endpoints, with
support for saving and restoring this setting during setup.
* Compatible-endpoint checks now use a more tailored validation flow
when reasoning mode is enabled.

* **Bug Fixes**
* Improved handling of resumed onboarding so stale reasoning settings
are cleared when switching providers.
* Increased the default token budget for compatible-endpoint sandbox
smoke checks.

* **Documentation**
* Updated setup and platform docs to cover reasoning mode and refreshed
reference links.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Fixes NVIDIA#3279

Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Deepak Jain <deepujain@gmail.com>
@deepujain
deepujain force-pushed the fix/3279-compatible-reasoning-flag branch from 606e238 to 0def0a8 Compare June 30, 2026 02:30
@deepujain

Copy link
Copy Markdown
Contributor Author

Rebased this on current main and kept the reasoning coverage on the current package-contract boundary. Build, typecheck, lint, source-shape, and the focused reasoning/provider-flow tests pass.

@deepujain

Copy link
Copy Markdown
Contributor Author

Closing this as superseded now that #3279 is closed and current main already carries the behavior. The remaining branch diff is only leftover test coverage, so keeping it open would add churn without a clear issue to close.

@deepujain deepujain closed this Jun 30, 2026
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 sentences: what this PR does and why. -->

Custom OpenAI-compatible providers can opt into reasoning-mode
validation through `NEMOCLAW_REASONING`, preserving that choice through
provider handoff and resume. This clean-history replacement supersedes
NVIDIA#3286 while retaining Deepak Jain's attribution and all fixes from its
review.

## Related Issue
<!-- Fixes #NNN or Closes #NNN. Remove this section if none. -->

Fixes NVIDIA#3279.
Supersedes NVIDIA#3286.

## Changes
<!-- Bullet list of key changes. -->

- Normalize common reasoning aliases and persist explicit set and clear
operations in onboarding session state.
- Skip Responses API, tool-call, and streaming probes that
reasoning-only compatible endpoints reject.
- Retry length-limited `reasoning_content` and `reasoning` smoke
responses with a larger output budget, then fail clearly if final
content remains empty.
- Carry reasoning state through provider selection, resume, flow
context, debug summaries, and sandbox creation.
- Add focused source and package-contract coverage for aliases, probe
selection, persistence, null clearing, resume, and response fallback
behavior.
- Keep `src/lib/onboard.ts` net-neutral and synchronize generated
platform documentation citations.
- Validation: CLI build and typecheck, focused source tests, the
package-contract test, 18 platform-doc generator tests, full commit
hooks, and push hooks pass. `npm run docs` reports zero errors and two
pre-existing Fern warnings.

## 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
<!-- Check all that apply. For any "covered by existing tests", "not
applicable", or waiver entry, add a brief justification on the same line
or in the Changes section. -->
- [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: maintainer salvage
review completed; all historical CodeRabbit findings and the resolved
thread in NVIDIA#3286 were incorporated
and revalidated.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification
<!-- Check each item you ran and confirmed. Leave unchecked items you
skipped. Doc-only changes do not require npm test unless you ran it. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior
- [ ] Full `npm test` passes (broad runtime changes only)
- [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)
- [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)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


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

* **New Features**
* Added a new reasoning mode for compatible OpenAI-style endpoints, with
support for saving and restoring this setting during setup.
* Compatible-endpoint checks now use a more tailored validation flow
when reasoning mode is enabled.

* **Bug Fixes**
* Improved handling of resumed onboarding so stale reasoning settings
are cleared when switching providers.
* Increased the default token budget for compatible-endpoint sandbox
smoke checks.

* **Documentation**
* Updated setup and platform docs to cover reasoning mode and refreshed
reference links.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Deepak Jain <deepujain@gmail.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: inference Inference routing, serving, model selection, or outputs area: providers Inference provider integrations and provider behavior bug-fix PR fixes a bug or regression needs: rebase PR needs rebase or conflict resolution provider: openai OpenAI API or OpenAI-compatible provider behavior VDR Linked to VDR finding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NEMOCLAW_REASONING not configurable for Option 3 providers; reasoning-only models fail silently

4 participants