Skip to content

feat: add LiteLLM as AI gateway provider#269

Open
RheagalFire wants to merge 1 commit into
zilliztech:masterfrom
RheagalFire:feat/add-litellm-provider
Open

feat: add LiteLLM as AI gateway provider#269
RheagalFire wants to merge 1 commit into
zilliztech:masterfrom
RheagalFire:feat/add-litellm-provider

Conversation

@RheagalFire

Copy link
Copy Markdown

Summary

  • Adds LiteLLM as both an LLM and embedding provider, giving DeepSearcher users unified access to 100+ LLM providers (OpenAI, Anthropic, Google, Azure, Bedrock, Ollama, and more)
    through a single interface.
  • LiteLLM is added as an optional dependency (deepsearcher[litellm]), keeping the default install lightweight.

Motivation

DeepSearcher already supports 18 LLM providers, each requiring a separate SDK and configuration. LiteLLM provides a unified gateway that routes to any provider using a single API,
reducing the need to maintain per-provider code. Users who already run a LiteLLM proxy get instant access to all their configured models.

Changes

  • deepsearcher/llm/litellm_llm.py - New LiteLLM class implementing BaseLLM
  • deepsearcher/embedding/litellm_embedding.py - New LiteLLMEmbedding class implementing BaseEmbedding
  • deepsearcher/llm/__init__.py - Registered LiteLLM provider
  • deepsearcher/embedding/__init__.py - Registered LiteLLMEmbedding provider
  • pyproject.toml - Added litellm>=1.80.0,<1.87.0 as optional dependency
  • deepsearcher/config.yaml - Added commented configuration examples
  • tests/llm/test_litellm.py - 10 unit tests for LLM provider
  • tests/embedding/test_litellm_embedding.py - 8 unit tests for embedding provider

Proof of work

Unit tests (18/18 passing):
tests/llm/test_litellm.py::TestLiteLLM::test_chat_multiple_messages PASSED
tests/llm/test_litellm.py::TestLiteLLM::test_chat_omits_credentials_when_not_set PASSED
tests/llm/test_litellm.py::TestLiteLLM::test_chat_single_message PASSED
tests/llm/test_litellm.py::TestLiteLLM::test_chat_with_api_key PASSED
tests/llm/test_litellm.py::TestLiteLLM::test_chat_with_error PASSED
tests/llm/test_litellm.py::TestLiteLLM::test_drop_params_always_true PASSED
tests/llm/test_litellm.py::TestLiteLLM::test_init_default PASSED
tests/llm/test_litellm.py::TestLiteLLM::test_init_with_api_key_from_env PASSED
tests/llm/test_litellm.py::TestLiteLLM::test_init_with_api_key_parameter PASSED
tests/llm/test_litellm.py::TestLiteLLM::test_init_with_custom_model PASSED
tests/embedding/test_litellm_embedding.py::TestLiteLLMEmbedding::test_dimension_property PASSED
tests/embedding/test_litellm_embedding.py::TestLiteLLMEmbedding::test_embed_documents PASSED
tests/embedding/test_litellm_embedding.py::TestLiteLLMEmbedding::test_embed_query PASSED
tests/embedding/test_litellm_embedding.py::TestLiteLLMEmbedding::test_embed_query_omits_credentials_when_not_set PASSED
tests/embedding/test_litellm_embedding.py::TestLiteLLMEmbedding::test_embed_query_with_credentials PASSED
tests/embedding/test_litellm_embedding.py::TestLiteLLMEmbedding::test_init_default PASSED
tests/embedding/test_litellm_embedding.py::TestLiteLLMEmbedding::test_init_with_env_vars PASSED
tests/embedding/test_litellm_embedding.py::TestLiteLLMEmbedding::test_init_with_parameters PASSED

18 passed

Lint: ruff check and ruff format --check both pass clean.

Implementation notes

  • drop_params=True is always set so provider-unsupported kwargs (e.g., seed, frequency_penalty on Anthropic) are silently dropped instead of causing errors.
  • api_key and api_base are only forwarded when set. When omitted, LiteLLM reads provider-specific environment variables automatically (e.g., ANTHROPIC_API_KEY, OPENAI_API_KEY).
  • litellm is lazy-imported inside method bodies so users who don't install it are unaffected.

Risk / Compatibility

  • Additive only. Existing providers untouched.
  • litellm is an optional extra - base install unaffected.

Example usage

# config.yaml
provide_settings:
  llm:                                                                                                                                                                                  
    provider: "LiteLLM"
    config:                                                                                                                                                                             
      model: "anthropic/claude-sonnet-4-20250514"
      # api_key: "sk-xxxx"  # or set ANTHROPIC_API_KEY env var                                                                                                                          

  embedding:                                                                                                                                                                            
    provider: "LiteLLMEmbedding"
    config:                                                                                                                                                                             
      model: "text-embedding-ada-002"
      dimension: 1536
  from deepsearcher.llm import LiteLLM
  from deepsearcher.embedding import LiteLLMEmbedding                                                                                                                                     
  
  # LLM - uses ANTHROPIC_API_KEY from environment                                                                                                                                         
  llm = LiteLLM(model="anthropic/claude-sonnet-4-20250514")
  response = llm.chat([{"role": "user", "content": "What is 2+2?"}])                                                                                                                      
  print(response.content)                                                                                                                                                                 
  
  # Embedding - uses OPENAI_API_KEY from environment                                                                                                                                      
  embedding = LiteLLMEmbedding(model="text-embedding-ada-002")
  vector = embedding.embed_query("Hello world")                                                                                                                                           
  print(f"Dimension: {len(vector)}")

Signed-off-by: RheagalFire <arishalam121@gmail.com>
@sre-ci-robot

Copy link
Copy Markdown
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: RheagalFire
To complete the pull request process, please assign zc277584121 after the PR has been reviewed.
You can assign the PR to them by writing /assign @zc277584121 in a comment when ready.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sre-ci-robot

Copy link
Copy Markdown
Collaborator

Welcome @RheagalFire! It looks like this is your first PR to zilliztech/deep-searcher 🎉

@RheagalFire

Copy link
Copy Markdown
Author

/assign @zc277584121

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants