Skip to content

Add lms remove command to delete downloaded models#580

Open
hwrdprkns wants to merge 4 commits into
lmstudio-ai:mainfrom
hwrdprkns:feature/lms-remove-command
Open

Add lms remove command to delete downloaded models#580
hwrdprkns wants to merge 4 commits into
lmstudio-ai:mainfrom
hwrdprkns:feature/lms-remove-command

Conversation

@hwrdprkns

Copy link
Copy Markdown

What

Adds a remove (alias rm) subcommand to delete downloaded models from disk — the counterpart to lms get.

Resolves #579. Addresses the requests in #199 and #223, where the only available answer was to manually rm files from the models folder.

Usage

lms remove [modelKey]
  • No argument → interactive fuzzy picker of downloaded models (mirrors lms unload).
  • With a model key → targets that model directly.
  • Variants → if a model has multiple downloaded variants, prompts to remove a single variant or the entire model.
  • Safety:
    • Shows the model in the same table format as lms ls, plus its on-disk location, then asks for confirmation. -y/--yes skips the prompt.
    • Refuses to remove a model that is currently loaded (asks the user to lms unload first).
  • Prunes now-empty publisher/repo folders after deletion.

Since the SDK/backend exposes no delete RPC, removal is a filesystem delete of the model's path under the resolved models folder — the same approach as the documented manual workaround, made safe and built-in. rm(..., { recursive: true, force: true }) handles both file-style paths (a single .gguf) and folder-style paths (variant-based models whose path is a directory).

Changes

  • New src/subcommands/remove.ts — the command. Built on the same primitives as unload/import (createClient, @inquirer/prompts search/select + fuzzy, askQuestion from confirm.ts).
  • New src/modelsFolder.ts — extracted resolveModelsFolderPath/locateSettingsJson out of importCmd.ts so both commands share one implementation. Added an ensureExists option so remove doesn't recreate the models folder. importCmd.ts now imports from here (behavior unchanged).
  • src/subcommands/list.ts — exported printDownloadedModelsTable (and the LoadedModelInfo type) so remove output matches lms ls exactly.
  • src/index.ts — registered remove in the "Local models" group.
  • New src/subcommands/remove.test.ts — unit tests for the path-containment helper used by the loaded-model guard and the empty-folder pruning.

Testing notes

I was unable to run npm install / tsc / eslint locally because several @lmstudio/* dependencies (e.g. @lmstudio/lms-common-server) aren't published to the public npm registry — consistent with the note in CONTRIBUTING that binaries are built in the lmstudio.js monorepo. The code was written to match existing patterns and types, and formatted with the repo's Prettier config. I validated the path/variant assumptions against real lms ls --json output on a live install (single-file .gguf paths, folder paths for variant models, and two quants sharing a folder). I'd appreciate a CI run to confirm the build, and I'm glad to adjust naming/flags/behavior.

`lms` can download models (`lms get`) but has no way to delete them; the
only guidance has been to manually `rm` files from the models folder
(see lmstudio-ai#199, lmstudio-ai#223). This adds a `remove` (alias `rm`) subcommand.

- `lms remove [modelKey]`: removes a downloaded model from disk.
  - No argument -> interactive fuzzy picker (mirrors `lms unload`).
  - With a model key -> targets that model directly.
- Models with multiple downloaded variants prompt to remove a single
  variant or the entire model.
- Shows the model in the same table format as `lms ls`, plus its
  on-disk location, then asks for confirmation. `-y/--yes` skips it.
- Refuses to remove a model that is currently loaded (asks the user to
  `lms unload` first).
- Prunes now-empty publisher/repo folders after deletion.

Refactor: extract `resolveModelsFolderPath`/`locateSettingsJson` out of
`importCmd.ts` into a shared `modelsFolder.ts` and reuse it (adds an
`ensureExists` option so removal doesn't recreate the folder). Export
`printDownloadedModelsTable` from `list.ts` so the output matches `lms ls`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f470fe7d0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/subcommands/remove.ts Outdated
@hwrdprkns

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@github-actions github-actions Bot added the CLA signed Indicates if all contributors have signed the CLA label Jun 8, 2026
The loaded-model guard compared only the relative path, so a model loaded
on a remote LM Link device with the same path would block deleting the
local download even though local files aren't in use. Filter loaded
entries to the local device (via getModelInfo().deviceIdentifier +
deviceNameResolver.isLocal) before the path-containment check, matching
how `unload` distinguishes local vs remote models.

Addresses Codex review feedback on lmstudio-ai#580.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e3d00183c6

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/subcommands/remove.ts
`lms remove` deletes files from the locally-resolved models folder, but it
inherits `--host` from addCreateClientOptions. With `--host <server>` it
would list models from the remote instance while deleting local paths —
either silently doing nothing or removing the wrong local model. Since
there is no server-side delete RPC, fail fast when `--host` is set and
tell the user to run the command on the machine where the model is stored.

Addresses Codex review feedback (P1) on lmstudio-ai#580.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ef284a882

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/subcommands/remove.ts Outdated
resolveRemovalTarget looked up variants by model key only, which can
include variants downloaded on LM Link peers. Since only base models were
filtered to local devices, a remote-only variant could be offered and,
when selected, either no-op while reporting success or delete a local file
with the same relative path. Filter variants with
deviceNameResolver.isLocal(variant.deviceIdentifier) before building the
removal choices.

Addresses Codex review feedback (P2) on lmstudio-ai#580.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@hwrdprkns

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA signed Indicates if all contributors have signed the CLA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: lms remove command to delete downloaded models

1 participant