Skip to content

feat: add LiteLLM as AI gateway provider#196

Merged
tsingfei merged 4 commits into
bitsky-tech:devfrom
RheagalFire:feature/add-litellm-provider
Jun 4, 2026
Merged

feat: add LiteLLM as AI gateway provider#196
tsingfei merged 4 commits into
bitsky-tech:devfrom
RheagalFire:feature/add-litellm-provider

Conversation

@RheagalFire

@RheagalFire RheagalFire commented May 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds LiteLLM as a new LLM provider package (bridgic-llms-litellm), giving Bridgic users access to 100+ LLM providers (OpenAI, Anthropic, Google, Groq, Together AI, AWS Bedrock, Azure, Mistral, etc.) through a single unified interface
  • Follows the existing provider pattern exactly — new sub-package under packages/bridgic-integration/llms/ implementing BaseLlm

Motivation

Bridgic currently supports OpenAI (native), OpenAI-compatible endpoints, and vLLM. Users who want to use Anthropic, Google, Groq, Together AI, AWS Bedrock, or other providers need to either:

  1. Set up an OpenAI-compatible proxy themselves, or
  2. Wait for dedicated provider packages to be built one at a time

LiteLLM solves this by providing a single litellm.completion() / litellm.acompletion() interface that routes to any of 100+ providers using provider-prefixed model strings (e.g. openai/gpt-4o, anthropic/claude-sonnet-4-6, groq/llama-3.3-70b-versatile). This PR ships it as a first-class Bridgic provider.

Changes

  • packages/bridgic-integration/llms/bridgic-llms-litellm/ — new LiteLLM provider package
    • bridgic/llms/litellm/_litellm_llm.pyLiteLLM(BaseLlm) with chat, stream, achat, astream, serialization
    • bridgic/llms/litellm/__init__.py — public exports
    • pyproject.toml — package config with litellm>=1.80.0,<1.87 pinned dependency
    • Makefile — matches existing sub-package pattern
    • tests/test_litellm.py — 24 unit tests + 4 integration tests
  • pyproject.toml (root) — registered bridgic-llms-litellm as workspace member + dependency

Key design decisions

  • drop_params=True always set — LiteLLM silently drops per-provider-unsupported kwargs (e.g. frequency_penalty on Anthropic, strict:true on non-OpenAI). This prevents cross-provider errors when users switch models
  • Lazy importimport litellm inside method bodies so users who don't install bridgic-llms-litellm aren't affected
  • API key optional — when api_key=None, LiteLLM reads from provider env vars (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.)
  • Message conversion matches OpenAILikeLlm._convert_message_normal pattern — plain dict format compatible with LiteLLM
  • Pinned dependencylitellm>=1.80.0,<1.87 (tight range, not unpinned)

Tests

1. Unit + edge case tests (24 passed):

test_chat_basic PASSED
test_chat_model_override PASSED
test_api_key_forwarded PASSED
test_api_key_omitted_when_none PASSED
test_api_base_forwarded PASSED
test_timeout_forwarded PASSED
test_drop_params_default_true PASSED
test_message_conversion_roles PASSED
test_message_conversion_tool_blocks PASSED
test_configuration_defaults_merge PASSED
test_call_time_overrides_config PASSED
test_achat_basic PASSED
test_serialization_roundtrip PASSED
test_auth_error_raises_unrecoverable PASSED
test_rate_limit_retried PASSED
test_timeout_retried PASSED
test_empty_response_content PASSED
test_no_usage_in_response PASSED
test_refusal_emits_warning PASSED
test_stream_partial_chunks PASSED
test_astream_partial_chunks PASSED
test_provider_prefixed_model_string PASSED
test_missing_model_raises PASSED
test_extra_kwargs_forwarded PASSED
======================== 24 passed, 4 skipped in 1.28s

Edge cases covered:

  • Auth error (invalid key) → ModelUnrecoverableError, not retried (1 call)
  • Rate limit (429) → retried 3x, then ModelRetryLimitError
  • Timeout → retried 3x, then ModelRetryLimitError
  • Empty/null response content → graceful empty string
  • Missing usage data → usage=None, no crash
  • Provider refusal → RuntimeWarning emitted
  • Stream partial chunks (empty deltas, empty choices) → handled
  • Async stream partial chunks → handled
  • Missing model → validation error
  • Extra kwargs (seed, user) → forwarded to litellm

2. Import + smoke test:

from bridgic.llms.litellm import LiteLLM, LiteLLMConfiguration
from bridgic.core.model.types import Message, Role

llm = LiteLLM(api_key="test", api_base="http://localhost:4000", timeout=30.0)
state = llm.dump_to_dict()
# roundtrip: dump → load → verify all fields preserved ✓

LiteLLM._convert_message(Message.from_text("Hello", role=Role.USER))
# → {'role': 'user', 'content': 'Hello'} ✓

3. Pin resolution verified:

uv pip install -e packages/bridgic-integration/llms/bridgic-llms-litellm
# Resolved and installed successfully with litellm 1.82.x

Risk / Compatibility

  • Additive only — no existing provider code modified
  • litellm is a regular dependency of the new package, not the root — users who don't install bridgic-llms-litellm are unaffected
  • Workspace glob packages/bridgic-integration/llms/* automatically picks up the new package

Example usage

from bridgic.llms.litellm import LiteLLM, LiteLLMConfiguration
from bridgic.core.model.types import Message, Role

# API keys from env vars (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.)
llm = LiteLLM()

# Chat with any provider
response = llm.chat(
    model="openai/gpt-4o",
    messages=[Message.from_text("Hello!", role=Role.USER)],
)
print(response.message.content)

# Stream with Anthropic
for chunk in llm.stream(
    model="anthropic/claude-sonnet-4-6",
    messages=[Message.from_text("Tell me a story.", role=Role.USER)],
):
    print(chunk.delta, end="")

# Async with Groq
import asyncio
async def main():
    response = await llm.achat(
        model="groq/llama-3.3-70b-versatile",
        messages=[Message.from_text("Hello!", role=Role.USER)],
    )
    print(response.message.content)
asyncio.run(main())

@RheagalFire

Copy link
Copy Markdown
Contributor Author

cc @tsingfei @tielei

@tsingfei tsingfei changed the base branch from main to dev May 28, 2026 06:12
readme = "README.md"
requires-python = ">=3.9"
authors = [
{ name = "Tielei Zhang", email = "zhangtl04@gmail.com" },

@tsingfei tsingfei May 28, 2026

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.

You can change the package author to your name, and the same goes for the email address.

@tsingfei

tsingfei commented May 28, 2026

Copy link
Copy Markdown
Contributor

@RheagalFire Thank you for your contribution! Here are two points for your consideration in improving:

  1. Change the package author to yourself.
  2. Modify the documentation regarding model integration to introduce your LLM provider; the path is bridgic/docs/docs/tutorials/items/model_integration/llm_integration.ipynb.

To meet the CI/CD requirements, I changed the target branch to the dev branch, and will continue to merge it into the main branch later.

@RheagalFire

RheagalFire commented Jun 3, 2026

Copy link
Copy Markdown
Contributor Author

@tsingfei Addressed both items:

  1. Changed package author to myself in pyproject.toml
  2. Added LiteLLM to the model integration docs (installation table + usage example in llm_integration.ipynb)

Removed redundant markdown cells and code examples to streamline the tutorial on LLM integration.
@tsingfei tsingfei merged commit b6a2244 into bitsky-tech:dev Jun 4, 2026
48 checks passed
@tsingfei

tsingfei commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

@RheagalFire Have released your integration: https://pypi.org/project/bridgic-llms-litellm/

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.

3 participants