Skip to content

fix(lmstudio): replace SDK model discovery with HTTP - #2170

Open
renovate[bot] wants to merge 4 commits into
mainfrom
renovate/npm-lmstudio-sdk-zod-vulnerability
Open

renovate[bot] wants to merge 4 commits into
mainfrom
renovate/npm-lmstudio-sdk-zod-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Description

Replace @lmstudio/sdk with HTTP model discovery to remove its Zod version conflict. Remove the SDK dependency, its Zod override, and its exclusive lockfile entries.

Discovery tries native v1, then v0, then OpenAI-compatible model lists. Only HTTP 404 or 405 triggers fallback. Authentication errors, timeouts, cancellation, and invalid response bodies do not trigger fallback.

Concurrent calls share discovery, loading, and cache refresh for each normalized server URL and saved model ID. Existing instances are reused. Instance aliases support saved selections without adding extra dropdown entries.

Compatibility

  • LM Studio below 0.4.0 gets reduced metadata. v0 provides maximum context and LLM/VLM type information. OpenAI-compatible discovery provides IDs only. Native v1 is required for explicit loading and runtime context details.
  • Saved path IDs only partly work. Saved IDs remain unchanged. A catalog miss uses default metadata and still sends the ID to chat. The live probe accepted an SDK file path for chat but rejected it for native loading. This does not establish compatibility across older releases, model formats, or unloaded/JIT configurations.
  • A rejected model selection produces a reselection message without changing the saved setting.

Validation

  • Final author validation: 100 focused tests passed, including the race, aliases, wording, and parser regression tests.
  • Independent working-tree review: 36 files and 1,005 tests passed, covering LM Studio and all of core/webview.
  • Lint passed on touched TypeScript files. Suppression counts decreased by three.
  • Frozen offline lockfile validation passed.
  • Both Knip modes and all eight Knip policy tests passed.
  • Extension and root type checking report only the existing export-markdown.ts(100,58) error. Independent review reproduced it without these changes. The pre-push hook hit this same error; it was bypassed for the push. Pre-commit lint and formatting hooks passed.
  • Live HTTP/SDK probes used llmster 0.0.27+1, llama.cpp CPU runtime 2.66.0, and SmolLM2 135M. The final implementation has mocked response-contract coverage; it has not had a live rerun.

Repeat focused tests from src with pnpm exec vitest run api/providers/fetchers/__tests__/lmstudio.test.ts api/providers/__tests__/lm-studio.spec.ts api/providers/__tests__/lmstudio.spec.ts. The independent broader run also covered all of core/webview.

Documentation and scope

Compatibility behavior and probe limits are documented in docs/providers/lm-studio-http.md.

This resolves the dependency conflict behind the original security bump by removing the SDK. It does not dismiss the advisory or claim a false positive.

The no-model-loaded case now asks the user to load a model or enable JIT. Native catalogs skip invalid individual entries. Remaining follow-ups: avoid repeated discovery for unsupported/unmatched selections, and bound or report long-running model loads.

Codex prepared the implementation and tests. The maintainer reviewed the working tree and independently ran the broader checks.

@renovate
renovate Bot requested a review from taltas as a code owner October 24, 2026 09:59
@renovate renovate Bot added the security label Oct 24, 2026
@renovate renovate Bot added the security label Oct 24, 2026
@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one): 1

  • coderabbit-review-active

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Review status

This PR was opened by an automated account. A human maintainer must verify the change intent, provenance, and validation before merging.

Current step: Awaiting fresh human maintainer or CODEOWNER approval.

Review-state labels are managed by this workflow; do not edit them manually. community-approved is managed the same way — do not add or remove it manually. It signals a fresh community code approval for the current head as an advisory priority only; maintainer review is still required.

@edelauna

edelauna commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Status: blocked on upstream. Do not merge.

This bump breaks @lmstudio/sdk. The SDK declares zod ^3.22.4 and fails to load under zod 4:

Invalid default value for field envVars: ... HSA_OVERRIDE_GFX_VERSION: expected string, received undefined

The failing CI jobs all show this error:

  • platform-unit-test (Ubuntu and Windows): 9 spec files fail to load, including the LM Studio provider specs.
  • e2e-mock and theme-fixtures: the extension crashes on activation.

Cause: the SDK uses z.record(<enum keys>, z.string()). Zod 3 treats this as partial. Zod 4 requires every key. The fix upstream is z.partialRecord(...).

Advisory: GHSA-mrhx-c7xc-m3w5 lists 4.6.6 as the only patched version. No zod 3.x patch exists. The flaw is in zod 4 $ZodArray code. The SDK imports plain zod, which is the v3 implementation, so it is likely not affected. I did not confirm this against the zod 3 source.

Upstream: I posted the findings on lmstudio-ai/lmstudio-js#362 and asked whether they plan zod 4 support: lmstudio-ai/lmstudio-js#362 (comment). The latest SDK (2.1.0) still declares zod ^3.22.4.

This PR stays open until upstream supports zod 4. Then we can retry the override.

@renovate
renovate Bot force-pushed the renovate/npm-lmstudio-sdk-zod-vulnerability branch from 13c4cff to 8b590d5 Compare October 26, 2026 20:52
@renovate renovate Bot changed the title chore(deps): update dependency @lmstudio/sdk>zod to v4 [security] Update dependency @lmstudio/sdk>zod to v4 [SECURITY] Oct 29, 2026
@renovate renovate Bot changed the title Update dependency @lmstudio/sdk>zod to v4 [SECURITY] chore(deps): update dependency @lmstudio/sdk>zod to v4 [security] Oct 30, 2026
@renovate renovate Bot changed the title chore(deps): update dependency @lmstudio/sdk>zod to v4 [security] Update dependency @lmstudio/sdk>zod to v4 [SECURITY] Oct 30, 2026
@renovate renovate Bot changed the title Update dependency @lmstudio/sdk>zod to v4 [SECURITY] chore(deps): update dependency @lmstudio/sdk>zod to v4 [security] Oct 31, 2026
@renovate
renovate Bot force-pushed the renovate/npm-lmstudio-sdk-zod-vulnerability branch 2 times, most recently from 3820162 to 043f222 Compare November 7, 2026 15:29
@edelauna edelauna changed the title chore(deps): update dependency @lmstudio/sdk>zod to v4 [security] fix(lmstudio): replace SDK model discovery with HTTP Nov 8, 2026
@renovate

renovate Bot commented Nov 8, 2026

Copy link
Copy Markdown
Contributor Author

Edited/Blocked Notification

Renovate will not automatically rebase this PR, because it does not recognize the last commit author and assumes somebody else may have edited the PR.

You can manually request rebase by checking the rebase/retry box above.

⚠️ Warning: custom changes will be lost.

Comment thread src/api/providers/lm-studio.ts Fixed
@codecov

codecov Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.37037% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/api/providers/fetchers/lmstudio.ts 90.82% 3 Missing and 7 partials ⚠️
src/api/providers/lm-studio.ts 84.21% 0 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

@github-actions github-actions Bot added the awaiting-maintainer CodeRabbit approved; waiting for a human maintainer label Nov 8, 2026
@github-actions

github-actions Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Changed-code mutation testing

Report for PR head cc86a52e3961.

Surviving / uncovered mutants Advisories
58 0
Details: mutants, guidance, and reproduction

Changed-code mutation testing

PackageChanged executable linesValidKilledTimeoutSurvivedNo coverageResult
extension2082992410499Advisory findings

Focused tests

  • extension (cwd src): core/task/__tests__/ask-auto-deny.spec.ts, core/webview/__tests__/ClineProvider.spec.ts, api/providers/__tests__/kimi-code.spec.ts, core/webview/__tests__/ClineProvider.taskHistory.spec.ts, core/task-persistence/__tests__/TaskHistoryStore.spec.ts, __tests__/extension.spec.ts, core/task/__tests__/Task.spec.ts, core/task/__tests__/ask-queued-message-drain.spec.ts, core/task/__tests__/Task.persistence.spec.ts, core/tools/__tests__/executeCommand.spec.ts, activate/__tests__/registerCommands.spec.ts, core/webview/__tests__/webviewMessageHandler.spec.ts, core/webview/__tests__/ClineProvider.sticky-mode.spec.ts, core/tools/__tests__/executeCommandTool.spec.ts, core/webview/__tests__/ClineProvider.apiHandlerRebuild.spec.ts, core/webview/__tests__/ClineProvider.sticky-profile.spec.ts, core/config/__tests__/importExport.spec.ts, api/providers/__tests__/lmstudio.spec.ts, __tests__/ClineProvider.history-resume-delegation.spec.ts, api/providers/fetchers/__tests__/lmstudio.test.ts, core/task/__tests__/Task.dispose.test.ts, core/task/__tests__/ask-clear-approval-buttons.spec.ts, api/providers/__tests__/lm-studio.spec.ts, api/providers/__tests__/lmstudio-native-tools.spec.ts, core/task/__tests__/ask-allowlist-cwd.spec.ts, core/task/__tests__/Task.streaming-tool-calls.spec.ts, core/webview/__tests__/ClineProvider.stale-view.spec.ts, api/providers/__tests__/lm-studio-timeout.spec.ts, core/config/__tests__/ProviderSettingsManager.spec.ts, core/task/__tests__/flushPendingToolResultsToHistory.spec.ts, core/task/__tests__/grace-retry-errors.spec.ts, __tests__/single-open-invariant.spec.ts, core/webview/__tests__/ClineProvider.lockApiConfig.spec.ts, core/task/__tests__/Task.throttle.test.ts, api/providers/__tests__/model-catalog-adapters.spec.ts, core/task/__tests__/Task.run-shadow.spec.ts, core/webview/__tests__/webviewMessageHandler.routerModels.spec.ts, core/task/__tests__/reasoning-preservation.test.ts, core/assistant-message/__tests__/presentAssistantMessage-custom-tool.spec.ts, core/assistant-message/__tests__/presentAssistantMessage-tool-usage-attribution.spec.ts, api/providers/utils/__tests__/lmstudio.spec.ts, __tests__/ClineProvider.delegation.spec.ts, core/webview/__tests__/webviewMessageHandler.delete.spec.ts, api/providers/__tests__/nanogpt.spec.ts, core/webview/__tests__/webviewMessageHandler.checkpoint.spec.ts, core/webview/__tests__/checkpointRestoreHandler.spec.ts, core/webview/__tests__/webviewMessageHandler.edit.spec.ts, core/webview/__tests__/ClineProvider.flicker-free-cancel.spec.ts, __tests__/ClineProvider.subtask-links.spec.ts, activate/__tests__/registerCodeActions.spec.ts, services/code-index/__tests__/code-index-status-manager.spec.ts, utils/__tests__/autoImportSettings.spec.ts, core/task/__tests__/grounding-sources.test.ts, api/providers/__tests__/io-intelligence.spec.ts, core/webview/__tests__/webviewMessageHandler.openFile.spec.ts, core/webview/__tests__/generateSystemPrompt.spec.ts, api/providers/__tests__/friendli.spec.ts, core/task/__tests__/Task.ignored-disabled-tools-notice.spec.ts, core/assistant-message/__tests__/presentAssistantMessage-unknown-tool.spec.ts, extension/__tests__/api-task-conversation-history-length.spec.ts, core/task/__tests__/Task.resume-eviction-race.spec.ts, core/task/__tests__/Task.abort-reason-race.spec.ts, core/assistant-message/__tests__/presentAssistantMessage-auto-deny.spec.ts, extension/__tests__/api-start-task-logging.spec.ts, __tests__/removeClineFromStack-delegation.spec.ts, core/assistant-message/__tests__/presentAssistantMessage-images.spec.ts, activate/__tests__/handleUri.spec.ts, extension/__tests__/api-configuration.spec.ts, core/webview/__tests__/messageEnhancer.test.ts, core/assistant-message/__tests__/presentAssistantMessage-tool-repetition.spec.ts, core/webview/__tests__/webviewMessageHandler.cloudAuth.spec.ts, core/webview/__tests__/webviewMessageHandler.searchFiles.spec.ts, api/__tests__/index.spec.ts, core/webview/__tests__/webviewMessageHandler.importRooHistory.spec.ts, extension/__tests__/api-start-new-task.spec.ts, core/webview/__tests__/webviewMessageHandler.readFileContent.spec.ts, core/webview/__tests__/webviewMessageHandler.readOriginalContent.spec.ts, core/task/__tests__/Task.pending-action.spec.ts, core/task/__tests__/ask-abort-race.spec.ts, extension/__tests__/api-has-task-ui-message-text.spec.ts, core/webview/__tests__/ClineProvider.pending-action.spec.ts, core/webview/__tests__/webviewMessageHandler.abandonSubtask.spec.ts, activate/__tests__/handleTask.spec.ts, __tests__/abandonSubtask.spec.ts, utils/__tests__/enhance-prompt.spec.ts, services/marketplace/__tests__/marketplace-setting-check.spec.ts, core/webview/__tests__/webviewMessageHandler.lockApiConfig.spec.ts, core/assistant-message/__tests__/presentAssistantMessage.spec.ts, extension/__tests__/api-send-message.spec.ts, __tests__/nested-delegation-resume.spec.ts, extension/__tests__/api-delegation-events.spec.ts, core/task/__tests__/Task.sticky-profile-race.spec.ts, core/task/__tests__/ToolExecutionContext.spec.ts, __tests__/task-run-dispatch.spec.ts, core/assistant-message/__tests__/toTelemetryToolName.spec.ts, extension/__tests__/api-delete-queued-message.spec.ts, services/code-index/__tests__/code-index-scope.spec.ts, core/webview/__tests__/ClineProviderFactory.spec.ts, __tests__/api-subtask.spec.ts, extension/__tests__/api-theme-fixture.spec.ts, core/task/__tests__/Task.terminal-operation.spec.ts, test-utils/__tests__/provider.spec.ts, __tests__/new-task-delegation.spec.ts, extension/__tests__/api-terminal-profile.spec.ts

All surviving and uncovered mutants

Warning annotations highlight up to 20 unique locations (maximum 7 per file). This summary lists every advisory mutant.

extension

src/api/providers/fetchers/lmstudio.ts

LineStatusMutatorReplacement
71SurvivedArrayDeclaration["Stryker was here"]
76SurvivedConditionalExpressionfalse
89SurvivedConditionalExpressionfalse
92NoCoverageStringLiteral""
92SurvivedConditionalExpressionfalse
93SurvivedCallExpression;
101NoCoverageConditionalExpressiontrue
101NoCoverageConditionalExpressionfalse
101NoCoverageStringLiteral""
102NoCoverageCallExpression;
104NoCoverageLogicalOperatorfirstServerError && error
121SurvivedStringLiteral``
121SurvivedLogicalOperatormodel.display_name && model.key
122NoCoverageBooleanLiteraltrue
122SurvivedOptionalChainingmodel.capabilities.vision
128SurvivedLogicalOperatoraxios.isAxiosError(error) || error.code === "ECONNREFUSED"
128SurvivedConditionalExpressiontrue
128SurvivedEqualityOperatorerror.code !== "ECONNREFUSED"
132SurvivedStringLiteral``
154SurvivedConditionalExpressionfalse
155SurvivedMethodExpressioncatalog.models
155SurvivedConditionalExpressiontrue
158SurvivedConditionalExpressiontrue
160SurvivedConditionalExpressionfalse
176SurvivedStringLiteral""
196SurvivedOptionalChainingselectInstance(model, model.key).config
198SurvivedMethodExpressioncatalog.models
198SurvivedConditionalExpressiontrue
201SurvivedConditionalExpressiontrue
203SurvivedConditionalExpressiontrue
203SurvivedConditionalExpressionfalse
203SurvivedCallExpression;
228SurvivedStringLiteral""

src/api/providers/lm-studio.ts

LineStatusMutatorReplacement
313SurvivedConditionalExpressionfalse
313SurvivedLogicalOperator(!error || typeof error !== "object") && !("status" in error)
313SurvivedConditionalExpressionfalse
313SurvivedLogicalOperator!error && typeof error !== "object"
313SurvivedConditionalExpressionfalse
314SurvivedConditionalExpressionfalse
316SurvivedLogicalOperatordetail || typeof detail === "object"
316SurvivedConditionalExpressiontrue
317SurvivedConditionalExpressionfalse
317SurvivedLogicalOperatordetail || typeof detail === "object"
317SurvivedConditionalExpressiontrue
317SurvivedEqualityOperatortypeof detail !== "object"
317SurvivedStringLiteral""
317SurvivedStringLiteral""
318NoCoverageStringLiteral"Stryker was here!"
318SurvivedConditionalExpressiontrue
318SurvivedLogicalOperator"message" in error || typeof error.message === "string"
318SurvivedConditionalExpressiontrue
320SurvivedRegex/no models loaded/i
327SurvivedConditionalExpressionfalse
327SurvivedStringLiteral""
328SurvivedRegex/model.*(?:not found|does not exist|not available)|no models found/i
344NoCoverageStringLiteral"Stryker was here!"

src/api/providers/utils/lmstudio.ts

LineStatusMutatorReplacement
6SurvivedConditionalExpressiontrue
6SurvivedEqualityOperatorend >= 0

Resolve a mutation gap

Add or strengthen a focused test that fails under the mutation. If the mutant is equivalent, request maintainer approval for the narrowest mutator-specific exclusion and explain why it cannot change behavior:

// Stryker disable next-line ConditionalExpression: normalized input cannot reach the alternate branch
const result = condition ? value : fallback

Broad all exclusions and exclusions without a concrete reason are reported as advisories.

Reproduce locally

From a full checkout containing both commits:

pnpm install --frozen-lockfile
node scripts/stryker-diff.mjs ci --base a7157157239af0e9f3c544ff121dca83a5880274 --head db913f884ac62ada166f5743a891f023c226792e

Mutation reports

  • extension: reports/mutation/extension/mutation.html

The workflow uploads generated reports in the changed-code-mutation-report artifact. A direct artifact link appears below after upload.

@github-actions github-actions Bot removed the awaiting-maintainer CodeRabbit approved; waiting for a human maintainer label Nov 9, 2026
@edelauna
edelauna force-pushed the renovate/npm-lmstudio-sdk-zod-vulnerability branch from 1032833 to 3a2c435 Compare November 9, 2026 23:29
@github-actions github-actions Bot added has-conflicts PR has merge conflicts with the base branch awaiting-author PR is waiting for the author to address requested changes labels Nov 9, 2026
@edelauna
edelauna force-pushed the renovate/npm-lmstudio-sdk-zod-vulnerability branch from 146b39d to cc86a52 Compare November 10, 2026 01:41
@github-actions github-actions Bot added awaiting-maintainer CodeRabbit approved; waiting for a human maintainer and removed has-conflicts PR has merge conflicts with the base branch awaiting-author PR is waiting for the author to address requested changes labels Nov 10, 2026

This branch has not been deployed

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

Labels

awaiting-maintainer CodeRabbit approved; waiting for a human maintainer security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants