fix(inference): keep first Local Ollama TUI turn under OpenClaw compaction budget (#5468) - #5508
Conversation
…ction budget (NVIDIA#5468) Local Ollama small-context models (e.g. qwen2.5:0.5b, floored to a 16k runtime window) failed the very first OpenClaw TUI turn with "Auto-compaction could not recover this turn". OpenClaw 2026.5.27's default 20k compaction reserve is clamped so at least its 8k minimum prompt budget remains, leaving only ~8k for the first turn — too small for the agent base prompt + tool catalogue (~7.4k). The turn overflows and preemptive compaction, with no prior history to compact, fails. Carry the user-selected upstream provider into the config generator via a new NEMOCLAW_UPSTREAM_PROVIDER Docker ARG/ENV (NEMOCLAW_PROVIDER_KEY collapses managed routes to "inference", hiding ollama-local). For ollama-local windows at or below 28k (OpenClaw's 20k reserve floor + 8k minimum budget), emit agents.defaults.compaction with reserveTokens and reserveTokensFloor lowered to the model's reply budget (maxTokens). Both keys are set because OpenClaw takes max(reserveTokens, reserveTokensFloor). The reserve is clamped so a pathological maxTokens can never push the prompt budget below OpenClaw's 8k minimum. This raises the first-turn prompt budget to contextWindow - maxTokens (12288 for a 16k window); larger windows keep OpenClaw's default safeguard. Verified end-to-end through real `nemoclaw onboard` + `openclaw tui` with Local Ollama and qwen2.5:0.5b: pre-fix reproduces the failure, post-fix returns a normal first assistant reply. Adds unit coverage for upstream propagation and the compaction policy, plus a GPU-lane TUI first-turn guard. Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds ChangesLocal Ollama Small-Context Compaction Fix
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
## Summary Restore issue #5800 parity package `P0-E` for merged bash-suite deltas only. ## Related Issues Refs #5800 Refs #5098 Refs #5197 Refs #5245 Refs #5508 Refs #5587 ## Scope gate - Package: `P0-E — Platform, tunnel, cloud-experimental, and docs parity decisions` - Included PRs all merged and touched `test/e2e`: yes — #5197, #5245, #5508, #5587 - Out of scope: unmerged/non-bash PRs; shell lane retirement / PR #5756 cleanup ## Parity map | ID | Source PR | Contract | Inference classification | Vitest assertion / waiver | Status | | --- | --- | --- | --- | --- | --- | | E1 | #5197 | Deep Agents Code cloud-experimental Landlock check: `.deepagents` and `/tmp` writable, `/usr` and `/etc` read-only. | `hosted-compatible capable` | `ubuntu-repo-cloud-langchain-deepagents-code` live scenario now runs `05-deepagents-code-landlock-readonly.sh` after onboarding. | covered | | E2 | #5197 | Deep Agents Code arbitrary Python egress permits GitHub/PyPI and blocks Tavily/LangSmith/MCP/example.com absent explicit policy. | `hosted-compatible capable` | `ubuntu-repo-cloud-langchain-deepagents-code` live scenario now runs `06-deepagents-code-python-egress.sh` after onboarding. | covered | | E3 | #5245 | Trace timing signal is trusted summary only; raw target-controlled traces are not uploaded. | `none` | Existing `test/e2e-script-workflow.test.ts` and sanitizer tests cover trusted trace summary, scorecard comparison, and redaction boundary. | covered | | E4 | #5508 | GPU Local Ollama small-context config carries reduced OpenClaw compaction reserve. | `none` / local inference | `test/e2e-scenario/live/gpu-e2e.test.ts` now reads `/sandbox/.openclaw/openclaw.json` and asserts `reserveTokens` / `reserveTokensFloor` for small windows. | covered | | E5 | #5508 | Interactive OpenClaw TUI first turn must not fail auto-compaction. | `none` / local inference | No Vitest TUI fixture exists yet; config-level assertion covers the deterministic contract and the interactive smoke remains platform/manual-runner follow-up. Owner: NemoClaw maintainers; date: 2026-06-25; tracked in #5800 closeout. | waived/follow-up | | E6 | #5587 | Cloudflared exact-version override validates Debian version syntax before APT install. | `hosted-compatible capable` for live tunnel job; resolver itself `none` | Existing `test/cloudflared-version-resolver.test.ts`; tunnel workflow boundary already requires resolver use before `apt-get install cloudflared=${cf_version}`. | covered | ## Inference mode support - Default mode for touched live targets: `hosted-compatible capable` for Deep Agents Code and tunnel lifecycle; local Ollama/GPU uses local inference; trace/resolver tests are `none`. - Real inference support preserved: yes for Deep Agents Code scenario via `NVIDIA_INFERENCE_API_KEY`; yes for tunnel lifecycle via existing hosted-compatible route; local Ollama GPU remains local inference. - Modes validated in this PR: local unit/support tests plus live scenario selection without secret; selective hosted/GPU workflow dispatch required after PR opens. - If not validated with real inference: local machine lacks `NVIDIA_INFERENCE_API_KEY`, GPU runner, and Docker daemon; selective GitHub Actions will validate runner/secret boundaries. ## Validation - [x] `npm run build:cli` - [x] `npx vitest run test/e2e-scenario/support-tests/e2e-scenario-matrix.test.ts test/e2e-scenario/support-tests/e2e-scenario-registry.test.ts test/langchain-deepagents-code-image.test.ts test/ollama-local-openclaw-config-propagation.test.ts test/cloudflared-version-resolver.test.ts --silent=false --reporter=default` - [x] `NEMOCLAW_RUN_E2E_SCENARIOS=1 npx vitest run --project e2e-scenarios-live test/e2e-scenario/live/registry-scenarios.test.ts -t '^ubuntu-repo-cloud-langchain-deepagents-code$' --silent=false --reporter=verbose` (local result: skipped due missing `NVIDIA_INFERENCE_API_KEY`, confirms scenario wiring) - [ ] hosted/public selective E2E workflow, if required by classification: pending PR dispatch ## Follow-ups / waivers - E5: Interactive TUI first-turn smoke remains waived until a Vitest TUI fixture exists. Owner: NemoClaw maintainers; date: 2026-06-25; deterministic config contract is covered here. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a new cloud onboarding path for LangChain Deep Agents Code, including dedicated fixtures and live scenario coverage. * Surfaced new “cloud experimental” checks in live run planning and scenario matrix output. * **Bug Fixes** * Improved GPU live E2E validation by asserting the reserve-token compaction policy. * Updated Deep Agents Code expected gateway health handling to be optional. * **Security/Policy** * Expanded Deep Agents Code Python egress allowlists for approved GitHub/PyPI hosts. * **Tests** * Updated E2E checks and assertions (including Python egress probe behavior) and adjusted scenario/support-matrix expectations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Carlos Villela <cvillela@nvidia.com>
## Summary Restore issue NVIDIA#5800 parity package `P0-E` for merged bash-suite deltas only. ## Related Issues Refs NVIDIA#5800 Refs NVIDIA#5098 Refs NVIDIA#5197 Refs NVIDIA#5245 Refs NVIDIA#5508 Refs NVIDIA#5587 ## Scope gate - Package: `P0-E — Platform, tunnel, cloud-experimental, and docs parity decisions` - Included PRs all merged and touched `test/e2e`: yes — NVIDIA#5197, NVIDIA#5245, NVIDIA#5508, NVIDIA#5587 - Out of scope: unmerged/non-bash PRs; shell lane retirement / PR NVIDIA#5756 cleanup ## Parity map | ID | Source PR | Contract | Inference classification | Vitest assertion / waiver | Status | | --- | --- | --- | --- | --- | --- | | E1 | NVIDIA#5197 | Deep Agents Code cloud-experimental Landlock check: `.deepagents` and `/tmp` writable, `/usr` and `/etc` read-only. | `hosted-compatible capable` | `ubuntu-repo-cloud-langchain-deepagents-code` live scenario now runs `05-deepagents-code-landlock-readonly.sh` after onboarding. | covered | | E2 | NVIDIA#5197 | Deep Agents Code arbitrary Python egress permits GitHub/PyPI and blocks Tavily/LangSmith/MCP/example.com absent explicit policy. | `hosted-compatible capable` | `ubuntu-repo-cloud-langchain-deepagents-code` live scenario now runs `06-deepagents-code-python-egress.sh` after onboarding. | covered | | E3 | NVIDIA#5245 | Trace timing signal is trusted summary only; raw target-controlled traces are not uploaded. | `none` | Existing `test/e2e-script-workflow.test.ts` and sanitizer tests cover trusted trace summary, scorecard comparison, and redaction boundary. | covered | | E4 | NVIDIA#5508 | GPU Local Ollama small-context config carries reduced OpenClaw compaction reserve. | `none` / local inference | `test/e2e-scenario/live/gpu-e2e.test.ts` now reads `/sandbox/.openclaw/openclaw.json` and asserts `reserveTokens` / `reserveTokensFloor` for small windows. | covered | | E5 | NVIDIA#5508 | Interactive OpenClaw TUI first turn must not fail auto-compaction. | `none` / local inference | No Vitest TUI fixture exists yet; config-level assertion covers the deterministic contract and the interactive smoke remains platform/manual-runner follow-up. Owner: NemoClaw maintainers; date: 2026-06-25; tracked in NVIDIA#5800 closeout. | waived/follow-up | | E6 | NVIDIA#5587 | Cloudflared exact-version override validates Debian version syntax before APT install. | `hosted-compatible capable` for live tunnel job; resolver itself `none` | Existing `test/cloudflared-version-resolver.test.ts`; tunnel workflow boundary already requires resolver use before `apt-get install cloudflared=${cf_version}`. | covered | ## Inference mode support - Default mode for touched live targets: `hosted-compatible capable` for Deep Agents Code and tunnel lifecycle; local Ollama/GPU uses local inference; trace/resolver tests are `none`. - Real inference support preserved: yes for Deep Agents Code scenario via `NVIDIA_INFERENCE_API_KEY`; yes for tunnel lifecycle via existing hosted-compatible route; local Ollama GPU remains local inference. - Modes validated in this PR: local unit/support tests plus live scenario selection without secret; selective hosted/GPU workflow dispatch required after PR opens. - If not validated with real inference: local machine lacks `NVIDIA_INFERENCE_API_KEY`, GPU runner, and Docker daemon; selective GitHub Actions will validate runner/secret boundaries. ## Validation - [x] `npm run build:cli` - [x] `npx vitest run test/e2e-scenario/support-tests/e2e-scenario-matrix.test.ts test/e2e-scenario/support-tests/e2e-scenario-registry.test.ts test/langchain-deepagents-code-image.test.ts test/ollama-local-openclaw-config-propagation.test.ts test/cloudflared-version-resolver.test.ts --silent=false --reporter=default` - [x] `NEMOCLAW_RUN_E2E_SCENARIOS=1 npx vitest run --project e2e-scenarios-live test/e2e-scenario/live/registry-scenarios.test.ts -t '^ubuntu-repo-cloud-langchain-deepagents-code$' --silent=false --reporter=verbose` (local result: skipped due missing `NVIDIA_INFERENCE_API_KEY`, confirms scenario wiring) - [ ] hosted/public selective E2E workflow, if required by classification: pending PR dispatch ## Follow-ups / waivers - E5: Interactive TUI first-turn smoke remains waived until a Vitest TUI fixture exists. Owner: NemoClaw maintainers; date: 2026-06-25; deterministic config contract is covered here. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a new cloud onboarding path for LangChain Deep Agents Code, including dedicated fixtures and live scenario coverage. * Surfaced new “cloud experimental” checks in live run planning and scenario matrix output. * **Bug Fixes** * Improved GPU live E2E validation by asserting the reserve-token compaction policy. * Updated Deep Agents Code expected gateway health handling to be optional. * **Security/Policy** * Expanded Deep Agents Code Python egress allowlists for approved GitHub/PyPI hosts. * **Tests** * Updated E2E checks and assertions (including Python egress probe behavior) and adjusted scenario/support-matrix expectations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Summary
Local Ollama small-context models (e.g.
qwen2.5:0.5b) could not answer a firsthelloin the OpenClaw TUI: the turn failed with "Auto-compaction could notrecover this turn." NemoClaw floors a Local Ollama runtime window to 16k, but
OpenClaw 2026.5.27's default 20k compaction reserve leaves only ~8k of first-turn
prompt budget — too small for the agent base prompt + tool catalogue (~7.4k) —
so the first turn overflowed and preemptive compaction (no prior history to
compact) failed. This bakes a context-aware compaction reserve into the
generated
openclaw.jsonfor small Local Ollama windows so the first turn fits.Related Issue
Fixes #5468
Changes
scripts/generate-openclaw-config.mts: For the Local Ollama upstreamprovider with a context window at or below 28k (OpenClaw's 20k reserve floor +
its 8k minimum prompt budget), emit
agents.defaults.compactionwithreserveTokensandreserveTokensFloorlowered to the model's reply budget(
maxTokens). This raisespromptBudgetBeforeReservefrom ~8k tocontextWindow - maxTokens(12288 for a 16k window). Both keys are set becauseOpenClaw takes
max(reserveTokens, reserveTokensFloor), so lowering the flooralone would let the 20k default pull the reserve back up. The reserve is
clamped so a pathological
maxTokenscan never make the window worse than thedefault. Larger windows keep OpenClaw's default safeguard untouched.
Dockerfile: AddARG NEMOCLAW_UPSTREAM_PROVIDERand promote it toENVso the config generator can see the user-selected upstream provider
(
ollama-local), which is otherwise collapsed to the managedinferenceprovider key.
dockerfile-patch.tsalready writes this ARG (previously ano-op for the OpenClaw image, which lacked it).
test/ollama-local-openclaw-config-propagation.test.ts: Unit coverage forupstream-provider propagation through the staged Dockerfile and for the
small-context compaction policy (small window applies, non-ollama/large window
does not, threshold boundary, pathological-maxTokens clamp).
test/e2e/test-gpu-e2e.sh: New Phase 5.5 asserting the bakedopenclaw.jsoncarries the small-context reserve policy and that the realopenclaw tuifirst turn is not blocked by preemptive auto-compaction.Type of Change
Verification
End-to-end (real
nemoclaw onboard+ realopenclaw tui, Local Ollama,qwen2.5:0.5b)Reproduced the exact reporter workflow on a Linux host (CPU; the bug is a
config/budget interaction, not GPU-specific) through the worktree CLI:
node ./bin/nemoclaw.js onboard(Local Ollama /qwen2.5:0.5b) → real sandbox →openclaw tui→ sendhello.Pre-fix (baked config:
contextWindow=16384, nocompactionkey):Post-fix (same fresh
nemoclaw onboard --fresh; baked config now addsagents.defaults.compaction{reserveTokens: 4096, reserveTokensFloor: 4096},raising promptBudget from 16384 → 12288):
The first turn returns a real assistant reply with no auto-compaction recovery
failure.
Signed-off-by: Yimo Jiang yimoj@nvidia.com
Summary by CodeRabbit
Release Notes
New Features
Build/Configuration
Tests