Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/inference/choose-local-inference-server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,10 @@ Refer to [Host Files and State](../../reference/host-files-and-state) before del

When you intend to remove the entire NemoClaw installation, run `$$nemoclaw uninstall`.
Full uninstall verifies exact managed container ownership before it removes the runtime and its state.
It preserves the shared Hugging Face cache used by vLLM.
Add `--delete-models` only when you also accept deletion of NemoClaw-pulled Ollama models.
It preserves the shared Hugging Face cache used by vLLM by default.
Add `--delete-models` only when you accept deletion of every model reported by the host's local Ollama inventory and all non-credential data in the current user's shared Hugging Face cache.
This opt-in can delete cached files that other applications installed or use.
It preserves the Hugging Face `token` and `stored_tokens` authentication files.
If cleanup reports an ownership or Docker error, leave the state files in place, resolve the reported resource, and rerun uninstall.
After a successful full uninstall, `docker container inspect nemoclaw-vllm` must report no object.

Expand Down
5 changes: 4 additions & 1 deletion docs/inference/set-up-llama-cpp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,10 @@ It preserves `~/.cache/huggingface/` because other applications can use that cac
If exact cleanup fails, NemoClaw preserves the sandbox registry entry and ownership state for a retry.

For full NemoClaw removal, run `$$nemoclaw uninstall`.
Full uninstall applies the same exact-ownership checks and preserves the shared Hugging Face cache.
Full uninstall applies the same exact-ownership checks and preserves the shared Hugging Face cache by default.
Pass `--delete-models` only when you accept deletion of all non-credential data in the current user's shared cache after managed model runtimes stop.
The same flag also deletes every model installed in the host's local Ollama inventory.
Uninstall preserves the Hugging Face `token` and `stored_tokens` authentication files.

## Related Topics

Expand Down
31 changes: 30 additions & 1 deletion docs/manage-sandboxes/uninstall-nemoclaw.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ It preserves resources from a separate OpenClaw installation while continuing to
|---|---|
| `--yes` | Skip the confirmation prompt. |
| `--keep-openshell` | Leave OpenShell binaries, NemoClaw-managed gateway service files, and local gateway state in place, and do not stop the host gateway process. |
| `--delete-models` | Also remove NemoClaw-pulled Ollama models. |
| `--delete-models` | Delete every model reported by the host's local Ollama inventory and all non-credential data in the current user's shared `~/.cache/huggingface/` cache after managed model runtimes stop. Hugging Face authentication files remain. |
| `--destroy-user-data` | Also remove preserved user data in `rebuild-backups/`, `backups/`, and `sandboxes.json`. |
| `--all-gateway-ports` | Uninstall every gateway port on the host instead of only the selected one. |
| `--gateway <name>` | Optional consistency check; must match the name derived from `NEMOCLAW_GATEWAY_PORT`. |
Expand All @@ -33,6 +33,35 @@ It preserves resources from a separate OpenClaw installation while continuing to
For example, `NEMOCLAW_GATEWAY_PORT=9123 $$nemoclaw uninstall` selects `nemoclaw-9123` and its port-scoped state.
Do not use `--gateway` to select another instance; when supplied for compatibility, its value must match the derived name or uninstall stops before cleanup.

## Delete Host Models

The `--delete-models` flag is an explicit opt-in for deleting host model files.

<Warning>
This flag deletes every model that the local Ollama inventory reports, including models installed or used by other applications.
It also deletes all non-credential data in the current user's `~/.cache/huggingface/` directory, which other applications can use for models, datasets, and other cached assets.
Affected applications must download and verify their cached files again.
The Hugging Face `token` and `stored_tokens` authentication files remain, so this cleanup does not sign the current user out.
</Warning>

Run full uninstall with model deletion:

```bash
$$nemoclaw uninstall --delete-models
```

NemoClaw stops and verifies its managed local and distributed model runtimes before it deletes non-credential data from the local Hugging Face cache.
It validates that `~/.cache/` and `~/.cache/huggingface/` are real, current-user-owned directories that are not symlinks or group- or world-writable.
It inventories Ollama before it deletes any Ollama model.
An Ollama inventory error, model deletion error, unsafe cache path, or cache-data deletion error makes uninstall exit nonzero.
Cleanup can partially complete before an error.
Resolve the reported error, inspect the remaining models and runtimes, and rerun uninstall.

Without `--delete-models`, uninstall preserves both model stores.
When sibling gateway environments remain, uninstall preserves both model stores even if you pass `--delete-models`.
An all-gateway-port sweep deletes them only after every selected gateway cleanup succeeds and no sibling environment remains.
The flag does not scan arbitrary directories or delete model caches on remote peers.

## Uninstall Every Gateway Port

One uninstall removes one gateway port.
Expand Down
13 changes: 10 additions & 3 deletions docs/reference/commands.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3954,8 +3954,15 @@ These host-local checks run before NemoClaw deletes their state.
If Docker is unavailable or a resource does not match its persisted ownership state, uninstall exits nonzero before the remaining uninstall steps and preserves that state for recovery.
Host-local cleanup can partially complete before an error.
Restore Docker access or resolve the named ownership conflict, inspect the remaining container and network, and retry uninstall.
Managed llama.cpp and vLLM model files remain in the shared Hugging Face cache.
The `--delete-models` flag does not remove this shared cache.
Managed llama.cpp and vLLM model files remain in the shared Hugging Face cache by default.
With `--delete-models`, uninstall deletes every model in the local Ollama inventory and all non-credential data in the current user's shared `~/.cache/huggingface/` cache.
This opt-in can delete cached files that other applications installed or use.
It preserves the Hugging Face `token` and `stored_tokens` authentication files.
NemoClaw stops and verifies its managed local and distributed model runtimes before it deletes non-credential data from the local Hugging Face cache.
It does not scan arbitrary directories or delete model caches on remote peers.
When sibling gateway environments remain, uninstall preserves both model stores even if you pass `--delete-models`.
An Ollama inventory error, model deletion error, unsafe cache path, or cache-data deletion error makes uninstall exit nonzero.
Cleanup can partially complete before an error, so resolve the reported error and rerun uninstall.
It does not use the legacy `gateway destroy` command for that gateway.
<AgentOnly variant="openclaw">

Expand All @@ -3981,7 +3988,7 @@ Uninstall does not otherwise target the declared external directory.
|---|---|
| `--yes` | Skip the confirmation prompt |
| `--keep-openshell` | Leave OpenShell binaries, NemoClaw-managed gateway service files, and local gateway state in place, and do not stop the host gateway process |
| `--delete-models` | Also remove NemoClaw-pulled Ollama models. The shared Hugging Face cache remains in place. |
| `--delete-models` | Delete every model reported by the host's local Ollama inventory and all non-credential data in the current user's shared `~/.cache/huggingface/` cache after managed model runtimes stop. Hugging Face authentication files remain. |
| `--destroy-user-data` | Also remove preserved user data (`rebuild-backups/`, `backups/`, `sandboxes.json`) |
| `--all-gateway-ports` | Uninstall every gateway port on the host, not only the port `NEMOCLAW_GATEWAY_PORT` selects |
| `--gateway <name>` | Optional consistency check; must match the name derived from `NEMOCLAW_GATEWAY_PORT` |
Expand Down
10 changes: 7 additions & 3 deletions docs/reference/host-files-and-state.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Run `$$nemoclaw onboard` to register a sandbox again.
| `~/.nemoclaw/backups/` | Workspace backups written by legacy backup helpers and some recovery flows. | Only after confirming you no longer need those workspace archives. |
| `~/.nemoclaw/mounts/` | Default local mount points created by share or mount commands. | Unmount first, then remove unused directories. |
| `~/.nemoclaw/blueprints/` | Cached blueprint inputs used by onboarding and sandbox recreation. | Avoid manual deletion unless you plan to rerun onboarding from fresh inputs. |
| `~/.cache/huggingface/` | Shared Hugging Face cache used by managed vLLM and managed llama.cpp model acquisition. The llama.cpp path resolves the exact YAML-declared revision and GGUF file, then verifies its size, SHA-256 digest, and filesystem identity before launch. Other applications can use the same cache. | Only after stopping every process that uses the cache. Destroy and full uninstall preserve this shared cache, including when you pass `--delete-models`. Deleting it makes affected applications download and verify model files again. |
| `~/.cache/huggingface/` | Shared Hugging Face cache used by managed vLLM and managed llama.cpp model acquisition. The llama.cpp path resolves the exact YAML-declared revision and GGUF file, then verifies its size, SHA-256 digest, and filesystem identity before launch. Other applications can use the same cache. | Only after stopping every process that uses the cache. Sandbox destroy and full uninstall without `--delete-models` preserve it. Full uninstall with `--delete-models` deletes its non-credential data after managed model runtimes stop and only when no sibling gateway remains. The `token` and `stored_tokens` authentication files remain. Affected applications must download and verify their cached files again. |

## Migration Snapshot Retention

Expand Down Expand Up @@ -137,8 +137,12 @@ Before full uninstall deletes shared state, it removes only an exact authenticat
Catalog-selected host-local vLLM also requires its exact owner-only runtime receipt; legacy authenticated containers without catalog profile labels retain their existing cleanup behavior.
It refuses the remaining uninstall steps when Docker is unavailable or persisted ownership cannot be proved.
Resolve the reported Docker or ownership error and rerun uninstall with the state still present.
The shared Hugging Face cache used by managed vLLM and managed llama.cpp remains in place.
The `--delete-models` flag removes NemoClaw-pulled Ollama models, not the shared Hugging Face cache.
The shared Hugging Face cache used by managed vLLM and managed llama.cpp remains in place by default.
With `--delete-models`, full uninstall deletes every model in the local Ollama inventory and all non-credential data in the current user's shared Hugging Face cache.
The flag can delete cached files that other applications installed or use.
It preserves the Hugging Face `token` and `stored_tokens` authentication files.
NemoClaw deletes the non-credential cache data only after managed model runtimes stop and only when no sibling gateway remains.
An Ollama inventory error, model deletion error, unsafe cache path, or cache-data deletion error makes uninstall exit nonzero.

For operational uninstall steps, refer to:

Expand Down
2 changes: 1 addition & 1 deletion scripts/smoke-macos-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Options:
--allow-existing-state Allow running even if NemoClaw/OpenShell state already exists
--keep-logs Preserve log files after success
--remove-openshell Allow uninstall.sh to remove openshell
--delete-models Allow uninstall.sh to delete Ollama models
--delete-models Allow uninstall.sh to delete all Ollama models and non-credential Hugging Face cache data (authentication files remain)
-h, --help Show this help

Environment:
Expand Down
6 changes: 3 additions & 3 deletions src/commands/internal/uninstall/plan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
// SPDX-License-Identifier: Apache-2.0

import { Flags } from "@oclif/core";
import { buildHostUninstallPlan } from "../../../lib/actions/uninstall/plan";
import { CLI_DISPLAY_NAME, CLI_NAME } from "../../../lib/cli/branding";
import { jsonFlag } from "../../../lib/cli/common-flags";
import { NemoClawCommand } from "../../../lib/cli/nemoclaw-oclif-command";

import { buildHostUninstallPlan } from "../../../lib/actions/uninstall/plan";

export default class InternalUninstallPlanCommand extends NemoClawCommand {
static hidden = true;
static strict = true;
Expand All @@ -21,7 +20,8 @@ export default class InternalUninstallPlanCommand extends NemoClawCommand {
description: "Accepted for parity with run-plan; ignored while planning",
}),
"delete-models": Flags.boolean({
description: `Plan removal of ${CLI_DISPLAY_NAME}-pulled Ollama models`,
description:
"Plan removal of all Ollama models and non-credential Hugging Face cache data (authentication files remain)",
}),
"keep-openshell": Flags.boolean({ description: "Keep the openshell binary installed" }),
gateway: Flags.string({ description: "Gateway name", default: "nemoclaw" }),
Expand Down
3 changes: 2 additions & 1 deletion src/commands/internal/uninstall/run-plan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ export default class InternalUninstallRunPlanCommand extends NemoClawCommand {
"all-gateway-ports-child": Flags.boolean({ hidden: true }),
"keep-openshell": Flags.boolean({ description: "Leave the openshell binary installed" }),
"delete-models": Flags.boolean({
description: `Remove ${CLI_DISPLAY_NAME}-pulled Ollama models`,
description:
"Remove all Ollama models and non-credential Hugging Face cache data (authentication files remain)",
}),
"destroy-user-data": Flags.boolean({
description:
Expand Down
4 changes: 3 additions & 1 deletion src/lib/actions/root-help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ export function help(): void {
lines.push(` ${G}Uninstall flags:${R}`);
lines.push(` --yes${" ".repeat(29)}Skip the confirmation prompt`);
lines.push(` --keep-openshell${" ".repeat(18)}Leave the openshell binary installed`);
lines.push(` --delete-models${" ".repeat(19)}Remove ${CLI_DISPLAY_NAME}-pulled Ollama models`);
lines.push(
` --delete-models${" ".repeat(19)}Remove all Ollama models and non-credential Hugging Face cache data (authentication files remain)`,
);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
lines.push(
` --destroy-user-data${" ".repeat(15)}Remove preserved ~/.nemoclaw/ user data (rebuild-backups/, backups/, sandboxes.json)`,
);
Expand Down
43 changes: 43 additions & 0 deletions src/lib/actions/uninstall/run-plan-dual-station.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import path from "node:path";

import { describe, expect, it, vi } from "vitest";

import { DUAL_STATION_VLLM_RUNTIME_RECEIPT_FILE } from "../../inference/serving/managed-runtime-receipts";

import {
type RunResult,
runUninstallPlan as runUninstallPlanBase,
Expand Down Expand Up @@ -90,6 +92,47 @@ describe("managed distributed vLLM runtime uninstall", () => {
}
});

it("stops a distributed runtime before requesting shared Hugging Face cache-data cleanup", () => {
const home = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-uninstall-cache-order-"));
const stateDir = path.join(home, ".nemoclaw");
const receiptPath = path.join(stateDir, DUAL_STATION_VLLM_RUNTIME_RECEIPT_FILE);
const cacheDir = path.join(home, ".cache", "huggingface");
fs.mkdirSync(stateDir, { mode: 0o700 });
fs.writeFileSync(receiptPath, "{}\n", { mode: 0o600 });
fs.mkdirSync(`${receiptPath}.ssh-binding`, { mode: 0o700 });
fs.mkdirSync(cacheDir, { recursive: true });
const runDualStationRuntimeCleanup = vi.fn(() => ok());
const runHuggingFaceCacheDataCleanup = vi.fn(() => ok());

try {
const result = runUninstallPlan(
{ assumeYes: true, deleteModels: true, keepOpenShell: true },
{
commandExists: (command) => command === "openshell",
env: { HOME: home, TMPDIR: home } as NodeJS.ProcessEnv,
existsSync: fs.existsSync,
isTty: false,
log: vi.fn(),
rmSync: vi.fn(),
run: okWithKnownGatewayList,
runDualStationRuntimeCleanup,
runHuggingFaceCacheDataCleanup,
},
);

expect(result.exitCode).toBe(0);
expect(runDualStationRuntimeCleanup).toHaveBeenCalledOnce();
expect(runHuggingFaceCacheDataCleanup).toHaveBeenCalledWith(
expect.objectContaining({ stdio: "inherit" }),
);
expect(runDualStationRuntimeCleanup.mock.invocationCallOrder[0]).toBeLessThan(
runHuggingFaceCacheDataCleanup.mock.invocationCallOrder[0],
);
} finally {
fs.rmSync(home, { recursive: true, force: true });
}
});

it("finds host-global pair ownership when the final gateway uses a non-default port", async () => {
const home = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-uninstall-dual-port-"));
const port = 9123;
Expand Down
Loading
Loading