feat: add LM Studio as OpenAI-compatible local provider

This commit is contained in:
Bin-Home 2026-04-28 14:28:26 +08:00
parent 87803d50c5
commit 39b005af77
8 changed files with 14 additions and 4 deletions

View file

@ -52,6 +52,7 @@
"provider.anthropic": "Anthropic",
"provider.openrouter": "OpenRouter",
"provider.ollama": "Ollama",
"provider.lmstudio": "LM Studio",
"provider.custom": "Custom",
"settings.apiKey": "API key",
"settings.baseUrl": "Base URL",

View file

@ -52,6 +52,7 @@
"provider.anthropic": "Anthropic",
"provider.openrouter": "OpenRouter",
"provider.ollama": "Ollama",
"provider.lmstudio": "LM Studio",
"provider.custom": "自定义",
"settings.apiKey": "API 密钥",
"settings.baseUrl": "Base URL",

View file

@ -16,6 +16,7 @@ export const PROVIDER_DEFAULTS: Record<ProviderId, ProviderDefault> = {
anthropic: { baseUrl: "https://api.anthropic.com", model: "claude-sonnet-4-6" },
openrouter: { baseUrl: "https://openrouter.ai/api/v1", model: "openai/gpt-4o-mini" },
ollama: { baseUrl: "http://localhost:11434", model: "llama3.1" },
lmstudio: { baseUrl: "http://localhost:1234/v1", model: "local-model" },
custom: { baseUrl: "", model: "" },
};

View file

@ -0,0 +1,4 @@
import { createOpenAICompatible } from "./openai-compat";
export const createLMStudio = (apiKey: string, baseUrl?: string) =>
createOpenAICompatible({ id: "lmstudio", apiKey,
defaultBaseUrl: "http://localhost:1234/v1", baseUrl });

View file

@ -19,6 +19,7 @@ const TABLE: Array<{ provider: ProviderId; match: RegExp; caps: ModelCaps }> = [
{ provider: "minimax", match: /./, caps: { contextWindow: 245_000, supportsPromptCache: false } },
{ provider: "openrouter",match: /./, caps: { contextWindow: 128_000, supportsPromptCache: false } },
{ provider: "ollama", match: /./, caps: { contextWindow: 32_000, supportsPromptCache: false } },
{ provider: "lmstudio", match: /./, caps: { contextWindow: 32_000, supportsPromptCache: false } },
];
const DEFAULT: ModelCaps = { contextWindow: 32_000, supportsPromptCache: false };

View file

@ -3,6 +3,7 @@ import type { ProviderId } from "../types";
import { OpenAIProvider } from "./openai";
import { AnthropicProvider } from "./anthropic";
import { OllamaProvider } from "./ollama";
import { createLMStudio } from "./lmstudio";
import { createDeepSeek } from "./deepseek";
import { createQwen } from "./qwen";
import { createKimi } from "./kimi";
@ -18,6 +19,7 @@ export function createProvider(id: ProviderId, cfg: ProviderConfig): LLMProvider
case "openai": return new OpenAIProvider({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
case "anthropic": return new AnthropicProvider({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl });
case "ollama": return new OllamaProvider({ baseUrl: cfg.baseUrl || "http://localhost:11434" });
case "lmstudio": return createLMStudio(cfg.apiKey, cfg.baseUrl);
case "openrouter": return createOpenRouter(cfg.apiKey, cfg.baseUrl);
case "deepseek": return createDeepSeek(cfg.apiKey, cfg.baseUrl);
case "qwen": return createQwen(cfg.apiKey, cfg.baseUrl);
@ -34,5 +36,5 @@ export function createProvider(id: ProviderId, cfg: ProviderConfig): LLMProvider
}
export function listProviderIds(): ProviderId[] {
return ["deepseek","qwen","kimi","zhipu","zai","minimax","openai","anthropic","openrouter","ollama","custom"];
return ["deepseek","qwen","kimi","zhipu","zai","minimax","openai","anthropic","openrouter","ollama","lmstudio","custom"];
}

View file

@ -1,7 +1,7 @@
export type Mode = "ask" | "edit" | "scheduled";
export type ProviderId =
| "deepseek" | "qwen" | "kimi" | "zhipu" | "zai" | "minimax"
| "openai" | "anthropic" | "openrouter" | "ollama"
| "openai" | "anthropic" | "openrouter" | "ollama" | "lmstudio"
| "custom";
export type Locale = "auto" | "en" | "zh-CN";

View file

@ -2,9 +2,9 @@ import { describe, it, expect } from "vitest";
import { createProvider, listProviderIds } from "../../src/providers/registry";
describe("provider registry", () => {
it("lists all eleven ids", () => {
it("lists all twelve ids", () => {
expect(listProviderIds().sort()).toEqual(
["anthropic","custom","deepseek","kimi","minimax","ollama","openai","openrouter","qwen","zai","zhipu"]
["anthropic","custom","deepseek","kimi","lmstudio","minimax","ollama","openai","openrouter","qwen","zai","zhipu"]
);
});
it("creates openai", () => {