Skip to content

feat: add LiteLLM AI gateway adapter#729

Merged
tombeckenham merged 4 commits into
TanStack:mainfrom
RheagalFire:feat/add-litellm-provider
Jul 20, 2026
Merged

feat: add LiteLLM AI gateway adapter#729
tombeckenham merged 4 commits into
TanStack:mainfrom
RheagalFire:feat/add-litellm-provider

Conversation

@RheagalFire

@RheagalFire RheagalFire commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

🎯 Changes

Adds @tanstack/ai-litellm, a tree-shakeable adapter for the LiteLLM AI gateway proxy. Gives users access to 100+ LLM providers (OpenAI, Anthropic, Google, Azure, AWS Bedrock, Ollama, Groq, Mistral, and more) through a single adapter.

Follows the same pattern as ai-groq and ai-grok: extends OpenAIBaseChatCompletionsTextAdapter with a baseURL override pointing at the LiteLLM proxy. New package at packages/ai-litellm/ with LiteLLMTextAdapter, createLitellmText(), and litellmText() factory functions. Reads LITELLM_API_KEY from env, defaults proxy URL to http://localhost:4000/v1.

LiteLLM added to E2E feature-support matrix and test-matrix for all OpenAI-compatible features (chat, tool-calling, structured output, etc.).

Example usage:

import { createLitellmText } from '@tanstack/ai-litellm'

const adapter = createLitellmText('anthropic/claude-sonnet-4-6', 'sk-litellm-key', {
  baseURL: 'http://localhost:4000/v1',
})

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr. (pnpm install blocked by upstream chokidar@4.0.3 trust downgrade in the svelte example, unrelated to this change.)

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • Documentation
    • Added guidance for connecting the OpenAI-Compatible Adapter to a self-hosted LiteLLM Proxy.
    • Documented default proxy settings, configuration examples, model routing, and API key requirements.
    • Updated the OpenAI-Compatible adapter metadata timestamp.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0f9f7b67-bd2f-4b10-a923-b665734e2fc9

📥 Commits

Reviewing files that changed from the base of the PR and between 46c67ec and c55c423.

📒 Files selected for processing (2)
  • docs/adapters/openai-compatible.md
  • docs/config.json

📝 Walkthrough

Walkthrough

The OpenAI-Compatible adapter documentation now recognizes LiteLLM, explains self-hosted LiteLLM Proxy configuration and model routing, and refreshes the adapter metadata timestamp.

Changes

OpenAI-Compatible LiteLLM Documentation

Layer / File(s) Summary
LiteLLM documentation and adapter metadata
docs/adapters/openai-compatible.md, docs/config.json
Adds LiteLLM keywords and proxy configuration guidance, including routing and virtual API key details, and updates the adapter metadata timestamp.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Suggested reviewers: alemtuzlak

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title says a new LiteLLM adapter was added, but the PR only updates docs for the existing OpenAI-compatible adapter. Rename it to reflect the actual docs-only change, e.g. "docs: add LiteLLM guidance for OpenAI-compatible adapter".
Description check ⚠️ Warning The template is filled out, but the content describes a new package and matrix changes that are not in this PR. Rewrite the Changes section to match the docs-only LiteLLM/OpenAI-compatible update and correct the checklist/release impact to reflect that.
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
packages/ai-litellm/package.json (1)

52-52: ⚡ Quick win

Inconsistent workspace protocol for internal peer dependency.

The guideline specifies using workspace:* for internal package dependencies, but this peer dependency uses workspace:^. For consistency with the regular dependencies (lines 56-57) and the coding guidelines, consider using workspace:* here as well.

📝 Suggested change for consistency
-    "`@tanstack/ai`": "workspace:^",
+    "`@tanstack/ai`": "workspace:*",

As per coding guidelines, "Use the workspace:* protocol for internal package dependencies in package.json".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ai-litellm/package.json` at line 52, The peer dependency entry
"`@tanstack/ai`": "workspace:^" is using the wrong workspace protocol; update this
dependency to use the internal workspace protocol "workspace:*" so it matches
the other internal dependencies and the project guideline (look for the
"`@tanstack/ai`" key in packages/ai-litellm/package.json and replace the version
string).

Source: Coding guidelines

packages/ai-litellm/src/adapters/text.ts (1)

24-26: 💤 Low value

Consider using unknown instead of any for provider options.

Line 26 uses Record<string, any> as a type parameter. While this provides maximum flexibility, using Record<string, unknown> would provide better type safety by requiring explicit type assertions when accessing provider options, without losing functionality.

💡 Suggested type safety improvement
 export class LiteLLMTextAdapter extends OpenAIBaseChatCompletionsTextAdapter<
   string,
-  Record<string, any>,
+  Record<string, unknown>,
   readonly [],
   Record<string, never>,
   readonly []
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ai-litellm/src/adapters/text.ts` around lines 24 - 26, The generic
parameter on LiteLLMTextAdapter uses Record<string, any> which weakens type
safety; update the adapter declaration that extends
OpenAIBaseChatCompletionsTextAdapter (the type parameter currently written as
Record<string, any>) to use Record<string, unknown> so provider options are
typed as unknown and require explicit assertions or narrowing when accessed.
packages/ai-litellm/src/utils/client.ts (1)

15-21: 💤 Low value

Consider narrowing the catch clause or re-throwing unexpected errors.

The empty catch clause catches all errors from getApiKeyFromEnv, not just the expected missing environment variable error. While this is unlikely to cause issues in practice (since getApiKeyFromEnv has a single failure mode), catching all errors without inspection can mask unexpected failures.

Consider either checking the error type before re-throwing, or documenting that all errors from getApiKeyFromEnv are treated as missing API key errors.

🛡️ Alternative approach with error inspection
 export function getLiteLLMApiKeyFromEnv(): string {
   try {
     return getApiKeyFromEnv('LITELLM_API_KEY')
-  } catch {
+  } catch (error) {
+    // getApiKeyFromEnv only throws when env var is missing, but be explicit
     throw new Error(
       'LITELLM_API_KEY is required. Please set it in your environment variables or use createLitellmText() with an explicit API key.',
     )
   }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ai-litellm/src/utils/client.ts` around lines 15 - 21, The current
catch block around getApiKeyFromEnv('LITELLM_API_KEY') swallows all errors;
change it to catch the error as a variable, inspect it (e.g., check instanceof
or error.message content that indicates "missing API key" from
getApiKeyFromEnv), and only convert that specific case to the user-facing Error
about LITELLM_API_KEY; for any other unexpected error re-throw the original
error so failures in getApiKeyFromEnv are not masked. Ensure references to
getApiKeyFromEnv and the existing message mentioning createLitellmText() remain
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/ai-litellm/package.json`:
- Line 52: The peer dependency entry "`@tanstack/ai`": "workspace:^" is using the
wrong workspace protocol; update this dependency to use the internal workspace
protocol "workspace:*" so it matches the other internal dependencies and the
project guideline (look for the "`@tanstack/ai`" key in
packages/ai-litellm/package.json and replace the version string).

In `@packages/ai-litellm/src/adapters/text.ts`:
- Around line 24-26: The generic parameter on LiteLLMTextAdapter uses
Record<string, any> which weakens type safety; update the adapter declaration
that extends OpenAIBaseChatCompletionsTextAdapter (the type parameter currently
written as Record<string, any>) to use Record<string, unknown> so provider
options are typed as unknown and require explicit assertions or narrowing when
accessed.

In `@packages/ai-litellm/src/utils/client.ts`:
- Around line 15-21: The current catch block around
getApiKeyFromEnv('LITELLM_API_KEY') swallows all errors; change it to catch the
error as a variable, inspect it (e.g., check instanceof or error.message content
that indicates "missing API key" from getApiKeyFromEnv), and only convert that
specific case to the user-facing Error about LITELLM_API_KEY; for any other
unexpected error re-throw the original error so failures in getApiKeyFromEnv are
not masked. Ensure references to getApiKeyFromEnv and the existing message
mentioning createLitellmText() remain unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 60ddb427-349a-40ad-b1f4-0a7e5b16d8db

📥 Commits

Reviewing files that changed from the base of the PR and between 22c9b42 and e33ee4a.

📒 Files selected for processing (7)
  • packages/ai-litellm/package.json
  • packages/ai-litellm/src/adapters/text.ts
  • packages/ai-litellm/src/index.ts
  • packages/ai-litellm/src/utils/client.ts
  • packages/ai-litellm/src/utils/index.ts
  • packages/ai-litellm/tsconfig.json
  • packages/ai-litellm/vite.config.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
testing/e2e/src/lib/feature-support.ts (1)

11-149: ⚠️ Potential issue | 🔴 Critical

Fix LiteLLM E2E wiring: provider: 'litellm' is marked supported, but the harness has no LiteLLM adapter.

  • testing/e2e/src/lib/feature-support.ts + testing/e2e/tests/test-matrix.ts include litellm for the added feature keys, but testing/e2e/src/lib/providers.ts’s createTextAdapter() has no litellm entry in defaultModels or the factories map; testing/e2e/src/routes/api.chat.ts always calls createTextAdapter(provider, ...), so this will fail at runtime for provider === 'litellm'.
  • testing/e2e/src/lib/llmock-server.ts’s LLMock record config doesn’t include litellm, so recording/fixture generation for LiteLLM can’t work either.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@testing/e2e/src/lib/feature-support.ts` around lines 11 - 149, The test
harness marks provider 'litellm' supported but the runtime wiring is missing;
add a LiteLLM adapter and fixtures: update createTextAdapter (in
testing/e2e/src/lib/providers.ts) by adding 'litellm' to defaultModels and the
factories map (implement or reference a LiteLLM TextAdapter factory) so
createTextAdapter(provider, ...) in routes/api.chat.ts can instantiate it, and
update the LLMock record config (in testing/e2e/src/lib/llmock-server.ts) to
include a 'litellm' entry so recording/fixture generation works for LiteLLM;
ensure the adapter follows the same interface used by other providers and reuse
existing adapter patterns for naming and behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@testing/e2e/src/lib/feature-support.ts`:
- Around line 11-149: The test harness marks provider 'litellm' supported but
the runtime wiring is missing; add a LiteLLM adapter and fixtures: update
createTextAdapter (in testing/e2e/src/lib/providers.ts) by adding 'litellm' to
defaultModels and the factories map (implement or reference a LiteLLM
TextAdapter factory) so createTextAdapter(provider, ...) in routes/api.chat.ts
can instantiate it, and update the LLMock record config (in
testing/e2e/src/lib/llmock-server.ts) to include a 'litellm' entry so
recording/fixture generation works for LiteLLM; ensure the adapter follows the
same interface used by other providers and reuse existing adapter patterns for
naming and behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f15d9991-7dff-4f86-98ea-d2a7d90976cb

📥 Commits

Reviewing files that changed from the base of the PR and between e33ee4a and 46c67ec.

📒 Files selected for processing (4)
  • .changeset/add-litellm-adapter.md
  • testing/e2e/src/lib/feature-support.ts
  • testing/e2e/src/lib/types.ts
  • testing/e2e/tests/test-matrix.ts
✅ Files skipped from review due to trivial changes (1)
  • testing/e2e/tests/test-matrix.ts

@tombeckenham tombeckenham self-assigned this Jun 16, 2026
tombeckenham and others added 2 commits July 20, 2026 17:19
…ider

# Conflicts:
#	testing/e2e/src/lib/feature-support.ts
#	testing/e2e/src/lib/types.ts
#	testing/e2e/tests/test-matrix.ts
LiteLLM exposes an OpenAI Chat Completions endpoint, so it is already
usable through the existing @tanstack/ai-openai/compatible adapter (added
in TanStack#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) <noreply@anthropic.com>
@tombeckenham

Copy link
Copy Markdown
Contributor

Sorry for the delay in looking at this. We now support LiteLLM through the openaiCompatible. I've changed this into a docs only update rather than add a new adapter. If things change and something specific is needed, please feel free to raise again

@tombeckenham
tombeckenham self-requested a review July 20, 2026 07:35
@nx-cloud

nx-cloud Bot commented Jul 20, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit c55c423

Command Status Duration Result
nx run-many --targets=build --exclude=examples/... ✅ Succeeded 1s View ↗

☁️ Nx Cloud last updated this comment at 2026-07-20 07:35:57 UTC

@tombeckenham tombeckenham left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Altered to docs only to mention LiteLLM

@pkg-pr-new

pkg-pr-new Bot commented Jul 20, 2026

Copy link
Copy Markdown

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@729

@tanstack/ai-acp

npm i https://pkg.pr.new/@tanstack/ai-acp@729

@tanstack/ai-angular

npm i https://pkg.pr.new/@tanstack/ai-angular@729

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@729

@tanstack/ai-bedrock

npm i https://pkg.pr.new/@tanstack/ai-bedrock@729

@tanstack/ai-claude-code

npm i https://pkg.pr.new/@tanstack/ai-claude-code@729

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@729

@tanstack/ai-code-mode

npm i https://pkg.pr.new/@tanstack/ai-code-mode@729

@tanstack/ai-code-mode-skills

npm i https://pkg.pr.new/@tanstack/ai-code-mode-skills@729

@tanstack/ai-codex

npm i https://pkg.pr.new/@tanstack/ai-codex@729

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@729

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@729

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@729

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@729

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@729

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@729

@tanstack/ai-grok-build

npm i https://pkg.pr.new/@tanstack/ai-grok-build@729

@tanstack/ai-groq

npm i https://pkg.pr.new/@tanstack/ai-groq@729

@tanstack/ai-isolate-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-isolate-cloudflare@729

@tanstack/ai-isolate-node

npm i https://pkg.pr.new/@tanstack/ai-isolate-node@729

@tanstack/ai-isolate-quickjs

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs@729

@tanstack/ai-mcp

npm i https://pkg.pr.new/@tanstack/ai-mcp@729

@tanstack/ai-mistral

npm i https://pkg.pr.new/@tanstack/ai-mistral@729

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@729

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@729

@tanstack/ai-opencode

npm i https://pkg.pr.new/@tanstack/ai-opencode@729

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@729

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@729

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@729

@tanstack/ai-react-ui

npm i https://pkg.pr.new/@tanstack/ai-react-ui@729

@tanstack/ai-sandbox

npm i https://pkg.pr.new/@tanstack/ai-sandbox@729

@tanstack/ai-sandbox-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-sandbox-cloudflare@729

@tanstack/ai-sandbox-daytona

npm i https://pkg.pr.new/@tanstack/ai-sandbox-daytona@729

@tanstack/ai-sandbox-docker

npm i https://pkg.pr.new/@tanstack/ai-sandbox-docker@729

@tanstack/ai-sandbox-local-process

npm i https://pkg.pr.new/@tanstack/ai-sandbox-local-process@729

@tanstack/ai-sandbox-sprites

npm i https://pkg.pr.new/@tanstack/ai-sandbox-sprites@729

@tanstack/ai-sandbox-vercel

npm i https://pkg.pr.new/@tanstack/ai-sandbox-vercel@729

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@729

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/@tanstack/ai-solid-ui@729

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@729

@tanstack/ai-utils

npm i https://pkg.pr.new/@tanstack/ai-utils@729

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@729

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/@tanstack/ai-vue-ui@729

@tanstack/openai-base

npm i https://pkg.pr.new/@tanstack/openai-base@729

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@729

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@729

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@729

commit: c55c423

@tombeckenham
tombeckenham merged commit 7ee6415 into TanStack:main Jul 20, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants