Skip to content

feat: add LiteLLM AI gateway adapter#729

Open
RheagalFire wants to merge 2 commits into
TanStack:mainfrom
RheagalFire:feat/add-litellm-provider
Open

feat: add LiteLLM AI gateway adapter#729
RheagalFire wants to merge 2 commits into
TanStack:mainfrom
RheagalFire:feat/add-litellm-provider

Conversation

@RheagalFire

@RheagalFire RheagalFire commented Jun 8, 2026

Copy link
Copy Markdown

🎯 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).

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new @tanstack/ai-litellm package: package config and build tooling, LiteLLM client utilities, a text/chat adapter with factory helpers, public re-exports, a changeset, and E2E test matrix/type updates to include the 'litellm' provider.

Changes

LiteLLM Integration Package

Layer / File(s) Summary
Package configuration and build setup
packages/ai-litellm/package.json, packages/ai-litellm/tsconfig.json, packages/ai-litellm/vite.config.ts
Package manifest defines entry points, publish files, scripts, and dependencies; TypeScript config extends the base and targets dist; Vite/Vitest config sets Node test environment, globals, test discovery, and V8 coverage.
LiteLLM client utilities
packages/ai-litellm/src/utils/client.ts, packages/ai-litellm/src/utils/index.ts
Exports LiteLLMClientConfig, getLiteLLMApiKeyFromEnv() (reads LITELLM_API_KEY with clearer error) and withLiteLLMDefaults() (adds default LiteLLM baseURL).
LiteLLM text adapter implementation
packages/ai-litellm/src/adapters/text.ts
Adds LiteLLMTextAdapter extending OpenAIBaseChatCompletionsTextAdapter, createLitellmText() factory (explicit apiKey) and litellmText() factory (reads env apiKey).
Package public API
packages/ai-litellm/src/index.ts
Re-exports adapter, factory helpers, and client utilities/types for tree-shakeable consumption.
Changeset
.changeset/add-litellm-adapter.md
New changeset documenting the minor release for @tanstack/ai-litellm.
E2E test matrix and types updates
testing/e2e/src/lib/feature-support.ts, testing/e2e/src/lib/types.ts, testing/e2e/tests/test-matrix.ts
Adds 'litellm' to the Provider union, ALL_PROVIDERS, the Playwright providers iteration list, and the feature-support matrix so relevant E2E specs include litellm.

Sequence Diagram

sequenceDiagram
  participant User
  participant litellmText as litellmText()
  participant getLiteLLMApiKeyFromEnv as getLiteLLMApiKeyFromEnv()
  participant createLitellmText as createLitellmText()
  participant withLiteLLMDefaults as withLiteLLMDefaults()
  participant LiteLLMTextAdapter as LiteLLMTextAdapter

  User->>litellmText: litellmText(model, config?)
  litellmText->>getLiteLLMApiKeyFromEnv: read LITELLM_API_KEY
  getLiteLLMApiKeyFromEnv-->>litellmText: apiKey
  litellmText->>createLitellmText: createLitellmText(model, apiKey, config)
  createLitellmText->>withLiteLLMDefaults: withLiteLLMDefaults(config)
  withLiteLLMDefaults-->>createLitellmText: config with baseURL
  createLitellmText->>LiteLLMTextAdapter: new LiteLLMTextAdapter(config, model)
  LiteLLMTextAdapter-->>createLitellmText: adapter instance
  createLitellmText-->>litellmText: LiteLLMTextAdapter
  litellmText-->>User: LiteLLMTextAdapter
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • crutchcorn
  • tombeckenham
  • schiller-manuel

Poem

🐰 I stitched a gateway neat and small,
LiteLLM listens, answers all—
Factories hum, defaults align,
Adapters wire, exports shine,
TanStack hops to meet the call.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding a LiteLLM AI gateway adapter package.
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.
Description check ✅ Passed The PR description covers all required template sections with comprehensive details about changes, checklist completion, and release impact.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@socket-security

socket-security Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedopenai@​6.42.078100100100100
Addedzod@​4.4.310010010093100

View full report

@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

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.

1 participant