From 3f01ef3c9fc7037b8b47432186901aa98848e3a2 Mon Sep 17 00:00:00 2001 From: AstroHan Date: Mon, 13 Jul 2026 20:54:12 +0800 Subject: [PATCH] revert: remove dedicated LiteLLM provider --- .../settings/provider-brand-marks.tsx | 1 - .../renderer/settings/provider-display.tsx | 2 - .../src/__tests__/llm-connections.test.ts | 30 +------------ packages/core/src/provider-registry.ts | 17 -------- packages/headless/src/provider-env.ts | 1 - .../__tests__/model-factory-thinking.test.ts | 42 ------------------- packages/ui/src/chat-model-helpers.ts | 1 - 7 files changed, 1 insertion(+), 93 deletions(-) diff --git a/apps/desktop/src/renderer/settings/provider-brand-marks.tsx b/apps/desktop/src/renderer/settings/provider-brand-marks.tsx index 6e31206003..575afa828c 100644 --- a/apps/desktop/src/renderer/settings/provider-brand-marks.tsx +++ b/apps/desktop/src/renderer/settings/provider-brand-marks.tsx @@ -156,7 +156,6 @@ export function ProviderBrandMark({ type }: { type: ProviderType }): ReactElemen return ; case 'openai': case 'codex-subscription': - case 'litellm': case 'openai-compatible': return ; case 'google': diff --git a/apps/desktop/src/renderer/settings/provider-display.tsx b/apps/desktop/src/renderer/settings/provider-display.tsx index 6723784fcf..dd255c8b24 100644 --- a/apps/desktop/src/renderer/settings/provider-display.tsx +++ b/apps/desktop/src/renderer/settings/provider-display.tsx @@ -41,8 +41,6 @@ export function providerDisplay(type: ProviderType): { name: string; description return { name: 'MiniMax', description: 'MiniMax · Anthropic 兼容', badge: 'API' }; case 'MiniMax-cn': return { name: 'MiniMax 中国站', description: 'MiniMax 中国站 · Anthropic 兼容', badge: 'API' }; - case 'litellm': - return { name: 'LiteLLM', description: 'AI gateway proxy for 100+ LLM providers.', badge: 'Gateway' }; case 'ollama': return { name: 'Ollama', description: '本机运行 · 离线可用', badge: 'Local' }; case 'openai-compatible': diff --git a/packages/core/src/__tests__/llm-connections.test.ts b/packages/core/src/__tests__/llm-connections.test.ts index 963c071e22..2a721978b3 100644 --- a/packages/core/src/__tests__/llm-connections.test.ts +++ b/packages/core/src/__tests__/llm-connections.test.ts @@ -25,7 +25,7 @@ import { } from '../llm-connections.js'; describe('provider compatibility contract', () => { - it('keeps persisted provider ids and existing provider ordering stable', () => { + it('exposes only supported first-class provider ids in stable order', () => { assert.deepEqual(Object.keys(PROVIDER_DEFAULTS), [ 'anthropic', 'kimi-coding-plan', @@ -37,7 +37,6 @@ describe('provider compatibility contract', () => { 'MiniMax', 'MiniMax-cn', 'siliconflow', - 'litellm', 'ollama', 'openai-compatible', 'claude-subscription', @@ -70,7 +69,6 @@ describe('provider compatibility contract', () => { 'openai', 'google', 'ollama', - 'litellm', 'openai-compatible', ]); }); @@ -283,19 +281,6 @@ describe('provider URL defaults', () => { assert.equal(PROVIDER_DEFAULTS['codex-subscription'].description, 'ChatGPT/Codex account OAuth path for OpenAI Responses models.'); }); - it('defines LiteLLM as an OpenAI-protocol custom gateway with localhost default', () => { - const litellm = PROVIDER_DEFAULTS['litellm']; - assert.equal(litellm.label, 'LiteLLM'); - assert.equal(litellm.protocol, 'openai'); - assert.equal(litellm.category, 'custom'); - assert.equal(litellm.baseUrl, 'http://localhost:4000/v1'); - assert.equal(litellm.authKind, 'api_key'); - assert.equal(litellm.backendKind, 'ai-sdk'); - assert.equal(litellm.status, 'ready'); - assert.equal(litellm.catalogBadge, 'Gateway'); - assert.deepEqual(litellm.fallbackModels, []); - }); - it('keeps Kimi Coding Plan separate from Moonshot API key access', () => { assert.equal(PROVIDER_DEFAULTS['kimi-coding-plan'].baseUrl, 'https://api.kimi.com/coding/v1'); assert.equal(PROVIDER_DEFAULTS['kimi-coding-plan'].signupUrl, 'https://www.kimi.com/code/console'); @@ -347,19 +332,6 @@ describe('persistedBaseUrl', () => { assert.equal(persistedBaseUrl('google', 'https://my-gemini-proxy.example.com/v1beta'), 'https://my-gemini-proxy.example.com/v1beta'); }); - it('collapses litellm default localhost URL to undefined (no override to persist)', () => { - assert.equal( - persistedBaseUrl('litellm', 'http://localhost:4000/v1'), - undefined, - 'litellm default must not be persisted as an override', - ); - }); - - it('persists a custom litellm proxy URL as a real override', () => { - const custom = 'https://litellm.company.internal/v1'; - assert.equal(persistedBaseUrl('litellm', custom), custom); - }); - it('persists a custom override for openai-compatible (whose default is the empty string)', () => { // openai-compatible is the one provider with no canonical default — any // non-empty value the user supplies is a real override and must persist. diff --git a/packages/core/src/provider-registry.ts b/packages/core/src/provider-registry.ts index 3190ee458b..3114f2b9f4 100644 --- a/packages/core/src/provider-registry.ts +++ b/packages/core/src/provider-registry.ts @@ -260,23 +260,6 @@ const providerRegistry = { catalogOrder: 7, recommendedOrder: 1, }, - litellm: { - label: 'LiteLLM', - description: 'AI gateway proxy for 100+ LLM providers.', - baseUrl: 'http://localhost:4000/v1', - authKind: 'api_key', - backendKind: 'ai-sdk', - fallbackModels: [], - status: 'ready', - protocol: 'openai', - runtimeAdapter: { kind: 'openai-compatible', name: 'provider' }, - modelDiscovery: { kind: 'protocol' }, - category: 'custom', - catalogGroup: 'aggregators', - catalogBadge: 'Gateway', - signupUrl: 'https://docs.litellm.ai/', - catalogOrder: 12, - }, ollama: { label: 'Ollama', description: 'Local models from Ollama on localhost.', diff --git a/packages/headless/src/provider-env.ts b/packages/headless/src/provider-env.ts index ee7587a0d4..4b67a69aa6 100644 --- a/packages/headless/src/provider-env.ts +++ b/packages/headless/src/provider-env.ts @@ -17,7 +17,6 @@ const PROVIDER_CREDENTIAL_ENV = { MiniMax: env('MINIMAX', ['MINIMAX_BASE_URL']), 'MiniMax-cn': env('MINIMAX', ['MINIMAX_BASE_URL']), siliconflow: env('SILICONFLOW', ['SILICONFLOW_BASE_URL']), - litellm: env('OPENAI', ['OPENAI_BASE_URL']), 'openai-compatible': env('OPENAI', ['OPENAI_BASE_URL']), 'claude-subscription': env('ANTHROPIC'), } satisfies Partial>; diff --git a/packages/runtime/src/__tests__/model-factory-thinking.test.ts b/packages/runtime/src/__tests__/model-factory-thinking.test.ts index a660b41c3e..22a5c174dc 100644 --- a/packages/runtime/src/__tests__/model-factory-thinking.test.ts +++ b/packages/runtime/src/__tests__/model-factory-thinking.test.ts @@ -77,39 +77,6 @@ describe('buildProviderOptions: thinking level', () => { }); }); -describe('getAIModel: litellm provider', () => { - test('creates an OpenAI-compatible client with provider name "litellm" and correct modelId', () => { - const model = getAIModel({ - connection: conn('litellm', 'litellm-gateway'), - apiKey: 'sk-test-key', - modelId: 'gpt-4o', - }); - assert.equal(model.modelId, 'gpt-4o'); - assert.equal(model.provider, 'litellm.chat'); - }); - - test('uses the connection baseUrl override when provided', () => { - const model = getAIModel({ - connection: { ...conn('litellm', 'litellm-custom'), baseUrl: 'https://litellm.company.internal/v1' }, - apiKey: 'sk-test-key', - modelId: 'claude-sonnet-4-5-20250929', - }); - assert.equal(model.modelId, 'claude-sonnet-4-5-20250929'); - assert.equal(model.provider, 'litellm.chat'); - }); - - test('falls back to localhost:4000 default when no baseUrl override is set', () => { - const model = getAIModel({ - connection: conn('litellm', 'litellm-default'), - apiKey: 'sk-test-key', - modelId: 'gpt-4o-mini', - }); - // The model is created successfully with default base URL - assert.equal(model.provider, 'litellm.chat'); - assert.equal(model.modelId, 'gpt-4o-mini'); - }); -}); - describe('getAIModel: models.dev registry providers', () => { test('routes SiliconFlow through the shared OpenAI-compatible adapter without rewriting model ids', () => { const model = getAIModel({ @@ -123,15 +90,6 @@ describe('getAIModel: models.dev registry providers', () => { }); }); -describe('buildProviderOptions: litellm falls through to default (empty options)', () => { - test('litellm returns empty options regardless of thinking level', () => { - assert.deepEqual(buildProviderOptions(conn('litellm'), 'gpt-4o'), {}); - assert.deepEqual(buildProviderOptions(conn('litellm'), 'gpt-4o', 'high'), {}); - assert.deepEqual(buildProviderOptions(conn('litellm'), 'gpt-4o', 'off'), {}); - assert.deepEqual(buildProviderOptions(conn('litellm'), 'claude-sonnet-4-5-20250929'), {}); - }); -}); - describe('buildProviderOptions: openai-compatible namespace', () => { test('zai-coding-plan emits reasoningEffort under the raw dashed namespace', () => { assert.deepEqual(buildProviderOptions(conn('zai-coding-plan', 'zai-coding-plan'), 'glm-5.2', 'high'), { 'zai-coding-plan': { reasoningEffort: 'high' } }); diff --git a/packages/ui/src/chat-model-helpers.ts b/packages/ui/src/chat-model-helpers.ts index 12b6839e65..bb7fdf25b9 100644 --- a/packages/ui/src/chat-model-helpers.ts +++ b/packages/ui/src/chat-model-helpers.ts @@ -53,7 +53,6 @@ const PROVIDER_SHORT_LABEL: Partial> = { google: 'Google', deepseek: 'DeepSeek', moonshot: 'Moonshot', - litellm: 'LiteLLM', ollama: 'Ollama', 'kimi-coding-plan': 'Kimi', 'zai-coding-plan': 'Z.AI',