From e33ee4aebbd5c85fde2b4f77b48a10b26fa6ed8b Mon Sep 17 00:00:00 2001 From: RheagalFire Date: Tue, 9 Jun 2026 02:10:51 +0530 Subject: [PATCH 1/3] feat: add LiteLLM AI gateway adapter --- packages/ai-litellm/package.json | 60 +++++++++++++++++++++ packages/ai-litellm/src/adapters/text.ts | 69 ++++++++++++++++++++++++ packages/ai-litellm/src/index.ts | 22 ++++++++ packages/ai-litellm/src/utils/client.ts | 35 ++++++++++++ packages/ai-litellm/src/utils/index.ts | 5 ++ packages/ai-litellm/tsconfig.json | 8 +++ packages/ai-litellm/vite.config.ts | 36 +++++++++++++ 7 files changed, 235 insertions(+) create mode 100644 packages/ai-litellm/package.json create mode 100644 packages/ai-litellm/src/adapters/text.ts create mode 100644 packages/ai-litellm/src/index.ts create mode 100644 packages/ai-litellm/src/utils/client.ts create mode 100644 packages/ai-litellm/src/utils/index.ts create mode 100644 packages/ai-litellm/tsconfig.json create mode 100644 packages/ai-litellm/vite.config.ts diff --git a/packages/ai-litellm/package.json b/packages/ai-litellm/package.json new file mode 100644 index 0000000000..bda415bc5e --- /dev/null +++ b/packages/ai-litellm/package.json @@ -0,0 +1,60 @@ +{ + "name": "@tanstack/ai-litellm", + "version": "0.0.1", + "type": "module", + "description": "LiteLLM AI gateway adapter for TanStack AI. Access 100+ LLM providers through a single proxy.", + "author": "", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/TanStack/ai.git", + "directory": "packages/ai-litellm" + }, + "module": "./dist/esm/index.js", + "types": "./dist/esm/index.d.ts", + "exports": { + ".": { + "types": "./dist/esm/index.d.ts", + "import": "./dist/esm/index.js" + } + }, + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "vite build", + "clean": "premove ./build ./dist", + "lint:fix": "eslint ./src --fix", + "test:build": "publint --strict", + "test:eslint": "eslint ./src", + "test:lib": "vitest run", + "test:lib:dev": "pnpm test:lib --watch", + "test:types": "tsc" + }, + "keywords": [ + "ai", + "ai-sdk", + "typescript", + "tanstack", + "litellm", + "adapter", + "llm", + "gateway", + "multi-provider", + "proxy" + ], + "devDependencies": { + "@vitest/coverage-v8": "4.0.14", + "vite": "^7.3.3" + }, + "peerDependencies": { + "@tanstack/ai": "workspace:^", + "zod": "^4.0.0" + }, + "dependencies": { + "@tanstack/ai-utils": "workspace:*", + "@tanstack/openai-base": "workspace:*", + "openai": "^6.41.0" + } +} diff --git a/packages/ai-litellm/src/adapters/text.ts b/packages/ai-litellm/src/adapters/text.ts new file mode 100644 index 0000000000..600cdd2719 --- /dev/null +++ b/packages/ai-litellm/src/adapters/text.ts @@ -0,0 +1,69 @@ +import OpenAI from 'openai' +import { OpenAIBaseChatCompletionsTextAdapter } from '@tanstack/openai-base' +import { getLiteLLMApiKeyFromEnv, withLiteLLMDefaults } from '../utils/client' +import type { LiteLLMClientConfig } from '../utils' + +/** + * Configuration for the LiteLLM text adapter. + */ +export interface LiteLLMTextConfig extends LiteLLMClientConfig {} + +/** + * LiteLLM Text (Chat) Adapter + * + * Tree-shakeable adapter for LiteLLM AI gateway. LiteLLM exposes an + * OpenAI-compatible Chat Completions endpoint, so we drive it with the + * OpenAI SDK via a baseURL override (the same pattern as ai-groq and + * ai-grok). + * + * LiteLLM supports 100+ providers (OpenAI, Anthropic, Google, Azure, + * AWS Bedrock, Ollama, Groq, Mistral, and more) through a single proxy. + * The model string determines the provider routing, e.g. + * "anthropic/claude-sonnet-4-6" or "openai/gpt-4o". + */ +export class LiteLLMTextAdapter extends OpenAIBaseChatCompletionsTextAdapter< + string, + Record, + readonly [], + Record, + readonly [] +> { + override readonly kind = 'text' as const + override readonly name = 'litellm' as const + + constructor(config: LiteLLMTextConfig, model: string) { + super(model, 'litellm', new OpenAI(withLiteLLMDefaults(config))) + } +} + +/** + * Creates a LiteLLM text adapter with explicit API key. + * + * @example + * ```typescript + * const adapter = createLitellmText('anthropic/claude-sonnet-4-6', 'sk-...'); + * ``` + */ +export function createLitellmText( + model: string, + apiKey: string, + config?: Omit, +): LiteLLMTextAdapter { + return new LiteLLMTextAdapter({ apiKey, ...config }, model) +} + +/** + * Creates a LiteLLM text adapter with API key from `LITELLM_API_KEY`. + * + * @example + * ```typescript + * const adapter = litellmText('anthropic/claude-sonnet-4-6'); + * ``` + */ +export function litellmText( + model: string, + config?: Omit, +): LiteLLMTextAdapter { + const apiKey = getLiteLLMApiKeyFromEnv() + return createLitellmText(model, apiKey, config) +} diff --git a/packages/ai-litellm/src/index.ts b/packages/ai-litellm/src/index.ts new file mode 100644 index 0000000000..850de7d16d --- /dev/null +++ b/packages/ai-litellm/src/index.ts @@ -0,0 +1,22 @@ +/** + * @module @tanstack/ai-litellm + * + * LiteLLM AI gateway adapter for TanStack AI. + * Provides a tree-shakeable adapter for LiteLLM's OpenAI-compatible proxy, + * giving access to 100+ LLM providers through a single interface. + */ + +// Text (Chat) adapter +export { + LiteLLMTextAdapter, + createLitellmText, + litellmText, + type LiteLLMTextConfig, +} from './adapters/text' + +// Utilities +export { + getLiteLLMApiKeyFromEnv, + withLiteLLMDefaults, + type LiteLLMClientConfig, +} from './utils' diff --git a/packages/ai-litellm/src/utils/client.ts b/packages/ai-litellm/src/utils/client.ts new file mode 100644 index 0000000000..61a674a66e --- /dev/null +++ b/packages/ai-litellm/src/utils/client.ts @@ -0,0 +1,35 @@ +import { getApiKeyFromEnv } from '@tanstack/ai-utils' +import type { ClientOptions } from 'openai' + +export interface LiteLLMClientConfig extends Omit { + apiKey?: string +} + +const DEFAULT_LITELLM_BASE_URL = 'http://localhost:4000/v1' + +/** + * Gets LiteLLM API key from environment variables. + * @throws Error if LITELLM_API_KEY is not found + */ +export function getLiteLLMApiKeyFromEnv(): string { + try { + return getApiKeyFromEnv('LITELLM_API_KEY') + } catch { + throw new Error( + 'LITELLM_API_KEY is required. Please set it in your environment variables or use createLitellmText() with an explicit API key.', + ) + } +} + +/** + * Returns an OpenAI client config pointing at the LiteLLM proxy. + * Defaults to http://localhost:4000/v1 when no baseURL is provided. + */ +export function withLiteLLMDefaults( + config: LiteLLMClientConfig, +): LiteLLMClientConfig { + return { + ...config, + baseURL: config.baseURL || DEFAULT_LITELLM_BASE_URL, + } +} diff --git a/packages/ai-litellm/src/utils/index.ts b/packages/ai-litellm/src/utils/index.ts new file mode 100644 index 0000000000..fb34ea3885 --- /dev/null +++ b/packages/ai-litellm/src/utils/index.ts @@ -0,0 +1,5 @@ +export { + getLiteLLMApiKeyFromEnv, + withLiteLLMDefaults, + type LiteLLMClientConfig, +} from './client' diff --git a/packages/ai-litellm/tsconfig.json b/packages/ai-litellm/tsconfig.json new file mode 100644 index 0000000000..c38689f4ea --- /dev/null +++ b/packages/ai-litellm/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "dist" + }, + "include": ["src", "tests"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/ai-litellm/vite.config.ts b/packages/ai-litellm/vite.config.ts new file mode 100644 index 0000000000..77bcc2e60b --- /dev/null +++ b/packages/ai-litellm/vite.config.ts @@ -0,0 +1,36 @@ +import { defineConfig, mergeConfig } from 'vitest/config' +import { tanstackViteConfig } from '@tanstack/vite-config' +import packageJson from './package.json' + +const config = defineConfig({ + test: { + name: packageJson.name, + dir: './', + watch: false, + globals: true, + environment: 'node', + include: ['tests/**/*.test.ts'], + coverage: { + provider: 'v8', + reporter: ['text', 'json', 'html', 'lcov'], + exclude: [ + 'node_modules/', + 'dist/', + 'tests/', + '**/*.test.ts', + '**/*.config.ts', + '**/types.ts', + ], + include: ['src/**/*.ts'], + }, + }, +}) + +export default mergeConfig( + config, + tanstackViteConfig({ + entry: ['./src/index.ts'], + srcDir: './src', + cjs: false, + }), +) From 46c67ec024f07f71353fd21004c9b0962fd2e6aa Mon Sep 17 00:00:00 2001 From: RheagalFire Date: Tue, 9 Jun 2026 02:39:11 +0530 Subject: [PATCH 2/3] chore: add changeset and E2E test wiring for litellm --- .changeset/add-litellm-adapter.md | 7 +++++++ testing/e2e/src/lib/feature-support.ts | 11 +++++++++++ testing/e2e/src/lib/types.ts | 2 ++ testing/e2e/tests/test-matrix.ts | 1 + 4 files changed, 21 insertions(+) create mode 100644 .changeset/add-litellm-adapter.md diff --git a/.changeset/add-litellm-adapter.md b/.changeset/add-litellm-adapter.md new file mode 100644 index 0000000000..cd27642cbf --- /dev/null +++ b/.changeset/add-litellm-adapter.md @@ -0,0 +1,7 @@ +--- +'@tanstack/ai-litellm': minor +--- + +feat: add LiteLLM AI gateway adapter + +New `@tanstack/ai-litellm` package that provides a tree-shakeable text adapter for the LiteLLM proxy. Extends `OpenAIBaseChatCompletionsTextAdapter` (same pattern as `ai-groq` and `ai-grok`), giving access to 100+ LLM providers through a single adapter. diff --git a/testing/e2e/src/lib/feature-support.ts b/testing/e2e/src/lib/feature-support.ts index 6d6b950bd7..65890433ce 100644 --- a/testing/e2e/src/lib/feature-support.ts +++ b/testing/e2e/src/lib/feature-support.ts @@ -17,6 +17,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), 'one-shot-text': new Set([ 'openai', @@ -27,6 +28,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), reasoning: new Set(['openai', 'anthropic', 'gemini']), 'multi-turn': new Set([ @@ -38,6 +40,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), 'tool-calling': new Set([ 'openai', @@ -48,6 +51,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), 'parallel-tool-calls': new Set([ 'openai', @@ -57,6 +61,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), // Gemini excluded: approval flow timing issues with Gemini's streaming format 'tool-approval': new Set([ @@ -67,6 +72,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), // Ollama excluded: aimock doesn't support content+toolCalls for /api/chat format 'text-tool-text': new Set([ @@ -77,6 +83,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), 'structured-output': new Set([ 'openai', @@ -87,6 +94,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), // Streaming structured output: only providers with native streaming JSON // schema support are listed here. Other providers fall back to the @@ -98,6 +106,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), // Multi-turn structured output: every turn produces its own typed // `structured-output` part on the assistant message, and historical @@ -125,6 +134,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), 'agentic-structured': new Set([ 'openai', @@ -135,6 +145,7 @@ export const matrix: Record> = { 'grok', 'openrouter', 'openai-compatible', + 'litellm', ]), // Native-combined-mode adapters only. Each provider's default test model // (or per-feature override in `features.ts`) must opt into combined mode diff --git a/testing/e2e/src/lib/types.ts b/testing/e2e/src/lib/types.ts index 018e7744f1..314d5a2671 100644 --- a/testing/e2e/src/lib/types.ts +++ b/testing/e2e/src/lib/types.ts @@ -10,6 +10,7 @@ export type Provider = | 'openrouter' | 'openrouter-responses' | 'openai-compatible' + | 'litellm' | 'elevenlabs' export type Feature = @@ -48,6 +49,7 @@ export const ALL_PROVIDERS: Provider[] = [ 'openrouter', 'openrouter-responses', 'openai-compatible', + 'litellm', 'elevenlabs', ] diff --git a/testing/e2e/tests/test-matrix.ts b/testing/e2e/tests/test-matrix.ts index 58a166a3ae..cd0cfe956b 100644 --- a/testing/e2e/tests/test-matrix.ts +++ b/testing/e2e/tests/test-matrix.ts @@ -23,6 +23,7 @@ export const providers: Provider[] = [ 'openrouter', 'openrouter-responses', 'openai-compatible', + 'litellm', 'elevenlabs', ] From c55c4238247776ce530ce9c46334e7521a8fc0e2 Mon Sep 17 00:00:00 2001 From: Tom Beckenham <34339192+tombeckenham@users.noreply.github.com> Date: Mon, 20 Jul 2026 17:29:02 +1000 Subject: [PATCH 3/3] feat: document LiteLLM via the generic openai-compatible adapter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LiteLLM exposes an OpenAI Chat Completions endpoint, so it is already usable through the existing @tanstack/ai-openai/compatible adapter (added in #676) — no dedicated package needed. Add a "LiteLLM Proxy" section to the OpenAI-Compatible adapter docs instead. Removes the @tanstack/ai-litellm package, its changeset, and the E2E matrix wiring introduced by this PR: the package duplicated the generic adapter (and with weaker typing — model was `string`), did not type-check or build (wrong message-metadata generic), had no unit tests, and its E2E matrix entries were never wired into providers.ts so they could not run. Co-Authored-By: Claude Opus 4.8 (1M context) --- .changeset/add-litellm-adapter.md | 7 --- docs/adapters/openai-compatible.md | 24 +++++++++ docs/config.json | 2 +- packages/ai-litellm/package.json | 60 --------------------- packages/ai-litellm/src/adapters/text.ts | 69 ------------------------ packages/ai-litellm/src/index.ts | 22 -------- packages/ai-litellm/src/utils/client.ts | 35 ------------ packages/ai-litellm/src/utils/index.ts | 5 -- packages/ai-litellm/tsconfig.json | 8 --- packages/ai-litellm/vite.config.ts | 36 ------------- pnpm-lock.yaml | 25 --------- testing/e2e/src/lib/feature-support.ts | 11 ---- testing/e2e/src/lib/types.ts | 2 - testing/e2e/tests/test-matrix.ts | 1 - 14 files changed, 25 insertions(+), 282 deletions(-) delete mode 100644 .changeset/add-litellm-adapter.md delete mode 100644 packages/ai-litellm/package.json delete mode 100644 packages/ai-litellm/src/adapters/text.ts delete mode 100644 packages/ai-litellm/src/index.ts delete mode 100644 packages/ai-litellm/src/utils/client.ts delete mode 100644 packages/ai-litellm/src/utils/index.ts delete mode 100644 packages/ai-litellm/tsconfig.json delete mode 100644 packages/ai-litellm/vite.config.ts diff --git a/.changeset/add-litellm-adapter.md b/.changeset/add-litellm-adapter.md deleted file mode 100644 index cd27642cbf..0000000000 --- a/.changeset/add-litellm-adapter.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@tanstack/ai-litellm': minor ---- - -feat: add LiteLLM AI gateway adapter - -New `@tanstack/ai-litellm` package that provides a tree-shakeable text adapter for the LiteLLM proxy. Extends `OpenAIBaseChatCompletionsTextAdapter` (same pattern as `ai-groq` and `ai-grok`), giving access to 100+ LLM providers through a single adapter. diff --git a/docs/adapters/openai-compatible.md b/docs/adapters/openai-compatible.md index f612bef561..91713aca37 100644 --- a/docs/adapters/openai-compatible.md +++ b/docs/adapters/openai-compatible.md @@ -15,6 +15,7 @@ keywords: - perplexity - lm studio - vllm + - litellm - adapter --- @@ -184,6 +185,29 @@ const ollama = openaiCompatible({ > Ollama also has a dedicated adapter, [`@tanstack/ai-ollama`](./ollama), which understands its native API. Use `openaiCompatible` only if you specifically want Ollama's OpenAI-compatible surface. +## LiteLLM Proxy + +[LiteLLM](https://github.com/BerriAI/litellm) is a self-hosted gateway that exposes a single OpenAI Chat Completions endpoint in front of 100+ providers (OpenAI, Anthropic, Google, Azure, AWS Bedrock, Mistral, Groq, and more). Because the proxy speaks the OpenAI wire format, it needs no dedicated package — point `openaiCompatible` at your proxy's `baseURL` (default `http://localhost:4000/v1`) and route to a provider with LiteLLM's `provider/model` naming: + +```typescript +import { openaiCompatible } from "@tanstack/ai-openai/compatible"; + +const litellm = openaiCompatible({ + name: "litellm", + baseURL: "http://localhost:4000/v1", // your LiteLLM proxy + apiKey: process.env.LITELLM_API_KEY!, // a virtual key issued by the proxy + models: [ + "anthropic/claude-sonnet-5", + "openai/gpt-5.5", + "gemini/gemini-3.5-flash", + ], +}); +``` + +`litellm("anthropic/claude-sonnet-5")` selects the Anthropic route; `litellm("openai/gpt-5.5")` selects OpenAI — all through the one proxy. Declare only the model routes you configured on the proxy; for precise per-model capabilities (e.g. a reasoning route without image input), use `createModel` as shown under [Declaring Models](#declaring-models). + +> The proxy holds each upstream provider's real credentials; the `apiKey` here is the proxy's own virtual/master key, not the upstream provider's. + ## Azure OpenAI Azure uses a resource-scoped URL and a separate API-version. Use the `/openai/v1` endpoint with `defaultQuery` for the version and `defaultHeaders` for the `api-key` header: diff --git a/docs/config.json b/docs/config.json index cf22278f50..6d5e988885 100644 --- a/docs/config.json +++ b/docs/config.json @@ -586,7 +586,7 @@ "label": "OpenAI-Compatible", "to": "adapters/openai-compatible", "addedAt": "2026-06-01", - "updatedAt": "2026-06-20" + "updatedAt": "2026-07-20" }, { "label": "Claude Code", diff --git a/packages/ai-litellm/package.json b/packages/ai-litellm/package.json deleted file mode 100644 index bda415bc5e..0000000000 --- a/packages/ai-litellm/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "@tanstack/ai-litellm", - "version": "0.0.1", - "type": "module", - "description": "LiteLLM AI gateway adapter for TanStack AI. Access 100+ LLM providers through a single proxy.", - "author": "", - "license": "MIT", - "repository": { - "type": "git", - "url": "git+https://github.com/TanStack/ai.git", - "directory": "packages/ai-litellm" - }, - "module": "./dist/esm/index.js", - "types": "./dist/esm/index.d.ts", - "exports": { - ".": { - "types": "./dist/esm/index.d.ts", - "import": "./dist/esm/index.js" - } - }, - "files": [ - "dist", - "src" - ], - "scripts": { - "build": "vite build", - "clean": "premove ./build ./dist", - "lint:fix": "eslint ./src --fix", - "test:build": "publint --strict", - "test:eslint": "eslint ./src", - "test:lib": "vitest run", - "test:lib:dev": "pnpm test:lib --watch", - "test:types": "tsc" - }, - "keywords": [ - "ai", - "ai-sdk", - "typescript", - "tanstack", - "litellm", - "adapter", - "llm", - "gateway", - "multi-provider", - "proxy" - ], - "devDependencies": { - "@vitest/coverage-v8": "4.0.14", - "vite": "^7.3.3" - }, - "peerDependencies": { - "@tanstack/ai": "workspace:^", - "zod": "^4.0.0" - }, - "dependencies": { - "@tanstack/ai-utils": "workspace:*", - "@tanstack/openai-base": "workspace:*", - "openai": "^6.41.0" - } -} diff --git a/packages/ai-litellm/src/adapters/text.ts b/packages/ai-litellm/src/adapters/text.ts deleted file mode 100644 index 600cdd2719..0000000000 --- a/packages/ai-litellm/src/adapters/text.ts +++ /dev/null @@ -1,69 +0,0 @@ -import OpenAI from 'openai' -import { OpenAIBaseChatCompletionsTextAdapter } from '@tanstack/openai-base' -import { getLiteLLMApiKeyFromEnv, withLiteLLMDefaults } from '../utils/client' -import type { LiteLLMClientConfig } from '../utils' - -/** - * Configuration for the LiteLLM text adapter. - */ -export interface LiteLLMTextConfig extends LiteLLMClientConfig {} - -/** - * LiteLLM Text (Chat) Adapter - * - * Tree-shakeable adapter for LiteLLM AI gateway. LiteLLM exposes an - * OpenAI-compatible Chat Completions endpoint, so we drive it with the - * OpenAI SDK via a baseURL override (the same pattern as ai-groq and - * ai-grok). - * - * LiteLLM supports 100+ providers (OpenAI, Anthropic, Google, Azure, - * AWS Bedrock, Ollama, Groq, Mistral, and more) through a single proxy. - * The model string determines the provider routing, e.g. - * "anthropic/claude-sonnet-4-6" or "openai/gpt-4o". - */ -export class LiteLLMTextAdapter extends OpenAIBaseChatCompletionsTextAdapter< - string, - Record, - readonly [], - Record, - readonly [] -> { - override readonly kind = 'text' as const - override readonly name = 'litellm' as const - - constructor(config: LiteLLMTextConfig, model: string) { - super(model, 'litellm', new OpenAI(withLiteLLMDefaults(config))) - } -} - -/** - * Creates a LiteLLM text adapter with explicit API key. - * - * @example - * ```typescript - * const adapter = createLitellmText('anthropic/claude-sonnet-4-6', 'sk-...'); - * ``` - */ -export function createLitellmText( - model: string, - apiKey: string, - config?: Omit, -): LiteLLMTextAdapter { - return new LiteLLMTextAdapter({ apiKey, ...config }, model) -} - -/** - * Creates a LiteLLM text adapter with API key from `LITELLM_API_KEY`. - * - * @example - * ```typescript - * const adapter = litellmText('anthropic/claude-sonnet-4-6'); - * ``` - */ -export function litellmText( - model: string, - config?: Omit, -): LiteLLMTextAdapter { - const apiKey = getLiteLLMApiKeyFromEnv() - return createLitellmText(model, apiKey, config) -} diff --git a/packages/ai-litellm/src/index.ts b/packages/ai-litellm/src/index.ts deleted file mode 100644 index 850de7d16d..0000000000 --- a/packages/ai-litellm/src/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @module @tanstack/ai-litellm - * - * LiteLLM AI gateway adapter for TanStack AI. - * Provides a tree-shakeable adapter for LiteLLM's OpenAI-compatible proxy, - * giving access to 100+ LLM providers through a single interface. - */ - -// Text (Chat) adapter -export { - LiteLLMTextAdapter, - createLitellmText, - litellmText, - type LiteLLMTextConfig, -} from './adapters/text' - -// Utilities -export { - getLiteLLMApiKeyFromEnv, - withLiteLLMDefaults, - type LiteLLMClientConfig, -} from './utils' diff --git a/packages/ai-litellm/src/utils/client.ts b/packages/ai-litellm/src/utils/client.ts deleted file mode 100644 index 61a674a66e..0000000000 --- a/packages/ai-litellm/src/utils/client.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { getApiKeyFromEnv } from '@tanstack/ai-utils' -import type { ClientOptions } from 'openai' - -export interface LiteLLMClientConfig extends Omit { - apiKey?: string -} - -const DEFAULT_LITELLM_BASE_URL = 'http://localhost:4000/v1' - -/** - * Gets LiteLLM API key from environment variables. - * @throws Error if LITELLM_API_KEY is not found - */ -export function getLiteLLMApiKeyFromEnv(): string { - try { - return getApiKeyFromEnv('LITELLM_API_KEY') - } catch { - throw new Error( - 'LITELLM_API_KEY is required. Please set it in your environment variables or use createLitellmText() with an explicit API key.', - ) - } -} - -/** - * Returns an OpenAI client config pointing at the LiteLLM proxy. - * Defaults to http://localhost:4000/v1 when no baseURL is provided. - */ -export function withLiteLLMDefaults( - config: LiteLLMClientConfig, -): LiteLLMClientConfig { - return { - ...config, - baseURL: config.baseURL || DEFAULT_LITELLM_BASE_URL, - } -} diff --git a/packages/ai-litellm/src/utils/index.ts b/packages/ai-litellm/src/utils/index.ts deleted file mode 100644 index fb34ea3885..0000000000 --- a/packages/ai-litellm/src/utils/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { - getLiteLLMApiKeyFromEnv, - withLiteLLMDefaults, - type LiteLLMClientConfig, -} from './client' diff --git a/packages/ai-litellm/tsconfig.json b/packages/ai-litellm/tsconfig.json deleted file mode 100644 index c38689f4ea..0000000000 --- a/packages/ai-litellm/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "dist" - }, - "include": ["src", "tests"], - "exclude": ["node_modules", "dist"] -} diff --git a/packages/ai-litellm/vite.config.ts b/packages/ai-litellm/vite.config.ts deleted file mode 100644 index 77bcc2e60b..0000000000 --- a/packages/ai-litellm/vite.config.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { defineConfig, mergeConfig } from 'vitest/config' -import { tanstackViteConfig } from '@tanstack/vite-config' -import packageJson from './package.json' - -const config = defineConfig({ - test: { - name: packageJson.name, - dir: './', - watch: false, - globals: true, - environment: 'node', - include: ['tests/**/*.test.ts'], - coverage: { - provider: 'v8', - reporter: ['text', 'json', 'html', 'lcov'], - exclude: [ - 'node_modules/', - 'dist/', - 'tests/', - '**/*.test.ts', - '**/*.config.ts', - '**/types.ts', - ], - include: ['src/**/*.ts'], - }, - }, -}) - -export default mergeConfig( - config, - tanstackViteConfig({ - entry: ['./src/index.ts'], - srcDir: './src', - cjs: false, - }), -) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2e44317e8..5d92af110e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1842,31 +1842,6 @@ importers: specifier: 4.0.14 version: 4.0.14(vitest@4.1.4) - packages/ai-litellm: - dependencies: - '@tanstack/ai': - specifier: workspace:^ - version: link:../ai - '@tanstack/ai-utils': - specifier: workspace:* - version: link:../ai-utils - '@tanstack/openai-base': - specifier: workspace:* - version: link:../openai-base - openai: - specifier: ^6.41.0 - version: 6.41.0(ws@8.21.0)(zod@4.3.6) - zod: - specifier: ^4.0.0 - version: 4.3.6 - devDependencies: - '@vitest/coverage-v8': - specifier: 4.0.14 - version: 4.0.14(vitest@4.1.4) - vite: - specifier: ^7.3.3 - version: 7.3.3(@types/node@24.10.3)(jiti@2.6.1)(less@4.6.6)(lightningcss@1.30.2)(sass@1.101.0)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - packages/ai-mcp: dependencies: '@modelcontextprotocol/sdk': diff --git a/testing/e2e/src/lib/feature-support.ts b/testing/e2e/src/lib/feature-support.ts index 337ec98608..cd3e2203dd 100644 --- a/testing/e2e/src/lib/feature-support.ts +++ b/testing/e2e/src/lib/feature-support.ts @@ -19,7 +19,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', 'mistral', ]), 'one-shot-text': new Set([ @@ -33,7 +32,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', 'mistral', ]), reasoning: new Set(['openai', 'anthropic', 'gemini', 'mistral']), @@ -48,7 +46,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', 'mistral', ]), 'tool-calling': new Set([ @@ -62,7 +59,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', 'mistral', ]), 'parallel-tool-calls': new Set([ @@ -75,7 +71,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', 'mistral', ]), // Gemini excluded: approval flow timing issues with Gemini's streaming format @@ -89,7 +84,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', 'mistral', ]), // Ollama excluded: aimock doesn't support content+toolCalls for /api/chat format @@ -103,7 +97,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', 'mistral', ]), 'structured-output': new Set([ @@ -117,7 +110,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', 'mistral', ]), // Streaming structured output: only providers with native streaming JSON @@ -132,7 +124,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', ]), // Multi-turn structured output: every turn produces its own typed // `structured-output` part on the assistant message, and historical @@ -162,7 +153,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', ]), 'agentic-structured': new Set([ 'openai', @@ -175,7 +165,6 @@ export const matrix: Record> = { 'bedrock-responses', 'openrouter', 'openai-compatible', - 'litellm', 'mistral', ]), // Native-combined-mode adapters only. Each provider's default test model diff --git a/testing/e2e/src/lib/types.ts b/testing/e2e/src/lib/types.ts index ff642b9fbd..0e362b5b1a 100644 --- a/testing/e2e/src/lib/types.ts +++ b/testing/e2e/src/lib/types.ts @@ -12,7 +12,6 @@ export type Provider = | 'openrouter' | 'openrouter-responses' | 'openai-compatible' - | 'litellm' | 'mistral' | 'elevenlabs' @@ -58,7 +57,6 @@ export const ALL_PROVIDERS: Provider[] = [ 'openrouter', 'openrouter-responses', 'openai-compatible', - 'litellm', 'mistral', 'elevenlabs', ] diff --git a/testing/e2e/tests/test-matrix.ts b/testing/e2e/tests/test-matrix.ts index ea72ed3b92..1dad0a91b7 100644 --- a/testing/e2e/tests/test-matrix.ts +++ b/testing/e2e/tests/test-matrix.ts @@ -25,7 +25,6 @@ export const providers: Provider[] = [ 'openrouter', 'openrouter-responses', 'openai-compatible', - 'litellm', 'mistral', 'elevenlabs', ]