Skip to content

feat(charity_engine): add Charity Engine provider - #23223

Merged
5 commits merged into
BerriAI:mainfrom
tristanolive:main
Mar 10, 2026
Merged

feat(charity_engine): add Charity Engine provider#23223
5 commits merged into
BerriAI:mainfrom
tristanolive:main

Conversation

@tristanolive

@tristanolive tristanolive commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

Charity Engine is a crowdsourced distributed computing platform that donates processing power to charitable causes. Its inference API provides OpenAI-compatible chat, completions, and embeddings endpoints.

Relevant issues

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/test_litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Type

🆕 New Feature

Changes

Add Charity Engine to the list of openai_like providers.

Charity Engine is a crowdsourced distributed computing platform that
donates processing power to charitable causes. Its inference API
provides OpenAI-compatible chat, completions, and embeddings endpoints.
@vercel

vercel Bot commented Mar 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Error Error Mar 10, 2026 3:37am

Request Review

@tristanolive

Copy link
Copy Markdown
Contributor Author

@greptileai

@greptile-apps

greptile-apps Bot commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR registers Charity Engine as a new JSON-backed OpenAI-compatible provider by adding its entry to providers.json, the CHARITY_ENGINE enum member to LlmProviders, and a suite of configuration/resolution tests.

Key changes:

  • providers.json: Adds charity_engine with base_url, api_key_env, and param_mappings (max_completion_tokensmax_tokens). The base_url correctly omits a trailing slash.
  • litellm/types/utils.py: Adds CHARITY_ENGINE = "charity_engine" to LlmProviders, ensuring the provider appears in litellm.provider_list and passes enum-based assertions.
  • tests/test_litellm/llms/openai_like/test_charity_engine.py: Mirrors the test_xiaomi_mimo.py pattern with four configuration/resolution tests. None of them make real network calls. The Router construction test is in-memory only.

All three files follow established patterns and are additive-only.

Confidence Score: 5/5

  • PR is safe to merge; all three changed files are additive-only and follow established patterns.
  • The provider registration is correct and consistent with other JSON-backed providers. The LlmProviders enum entry is present, the base_url has no trailing slash, and the tests comprehensively cover provider configuration and resolution paths without making real network calls. The implementation follows the exact pattern established by existing providers like xiaomi_mimo and assemblyai.
  • No files require special attention.

Sequence Diagram

sequenceDiagram
    participant User
    participant litellm
    participant get_llm_provider
    participant JSONProviderRegistry
    participant JSONProviderConfig
    participant CharityEngineAPI

    User->>litellm: completion("charity_engine/gemma3:270m", ...)
    litellm->>get_llm_provider: model="charity_engine/gemma3:270m"
    get_llm_provider->>JSONProviderRegistry: exists("charity_engine")
    JSONProviderRegistry-->>get_llm_provider: true
    get_llm_provider->>JSONProviderRegistry: get("charity_engine")
    JSONProviderRegistry-->>get_llm_provider: SimpleProviderConfig(base_url, api_key_env, param_mappings)
    get_llm_provider->>JSONProviderConfig: _get_openai_compatible_provider_info()
    JSONProviderConfig-->>get_llm_provider: resolved base_url and api_key from env
    get_llm_provider-->>litellm: ("gemma3:270m", "charity_engine", resolved_key, base_url)
    litellm->>JSONProviderConfig: get_complete_url(api_base)
    JSONProviderConfig-->>litellm: base_url + "/chat/completions"
    litellm->>JSONProviderConfig: map_openai_params(max_completion_tokens → max_tokens)
    litellm->>CharityEngineAPI: POST /remotejobs/v2/inference/chat/completions
    CharityEngineAPI-->>litellm: OpenAI-compatible response
    litellm-->>User: ModelResponse
Loading

Last reviewed commit: 6721c20

Comment on lines +98 to 105
"charity_engine": {
"base_url": "https://api.charityengine.services/remotejobs/v2/inference/",
"api_key_env": "CHARITY_ENGINE_API_KEY",
"api_base_env": "CHARITY_ENGINE_API_BASE",
"param_mappings": {
"max_completion_tokens": "max_tokens"
}
}

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.

The PR submission checklist explicitly requires at least one test to be added for new providers (see the contributing guide and other providers like xiaomi_mimo which have a dedicated test file). No test file (e.g., tests/test_litellm/llms/openai_like/test_charity_engine.py) was added in this PR, which means the provider registration, config loading, and provider resolution are untested.

Following the pattern established by test_xiaomi_mimo.py and test_assemblyai_provider.py, a test should at minimum verify:

  1. JSONProviderRegistry.exists("charity_engine") is True
  2. The loaded config has the expected base_url, api_key_env, api_base_env, and param_mappings
  3. Provider resolution routes charity_engine/<model> correctly

@CLAassistant

CLAassistant commented Mar 10, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Verify JSONProviderRegistry config, provider list membership,
model routing for charity_engine/<model>, and Router compatibility.
Comment on lines +98 to 105
"charity_engine": {
"base_url": "https://api.charityengine.services/remotejobs/v2/inference/",
"api_key_env": "CHARITY_ENGINE_API_KEY",
"api_base_env": "CHARITY_ENGINE_API_BASE",
"param_mappings": {
"max_completion_tokens": "max_tokens"
}
}

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.

The charity_engine provider is registered in providers.json, but the corresponding CHARITY_ENGINE = "charity_engine" enum entry is missing from LlmProviders in litellm/types/utils.py.

This causes two concrete test failures:

  1. Line 27 of test_charity_engine.py will fail with AttributeError: The test asserts hasattr(LlmProviders, "CHARITY_ENGINE"), which will raise an error because the enum member does not exist.
  2. Line 29 of test_charity_engine.py will fail: The test asserts "charity_engine" in litellm.provider_list, but provider_list is built from list(LlmProviders) in litellm/__init__.py (line 1752), so the provider will be absent.

Every other JSON-backed provider in this pattern added the enum entry — for example XIAOMI_MIMO = "xiaomi_mimo" (line 3212), ASSEMBLYAI = "assemblyai" (line 3179), and SYNTHETIC = "synthetic" (line 3207) in litellm/types/utils.py.

Fix: Add the following line to class LlmProviders in litellm/types/utils.py:

CHARITY_ENGINE = "charity_engine"

Enables provider_list membership and LlmProviders.CHARITY_ENGINE
resolution required by the provider and test suite.
Comment on lines +44 to +57
def test_charity_engine_provider_resolution(self):
"""Test that provider resolution finds charity_engine"""
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider

model, provider, api_key, api_base = get_llm_provider(
model="charity_engine/gemma3:270m",
custom_llm_provider=None,
api_base=None,
api_key=None,
)

assert model == "gemma3:270m"
assert provider == "charity_engine"
assert api_base == "https://api.charityengine.services/remotejobs/v2/inference/"

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.

Test non-deterministic when API base env var is set

charity_engine is the only provider in this test suite that declares an api_base_env override in providers.json. The _get_openai_compatible_provider_info method in dynamic_config.py resolves the base URL with this priority:

if not resolved_base and provider.api_base_env:
    resolved_base = get_secret_str(provider.api_base_env)  # reads env var first
if not resolved_base:
    resolved_base = provider.base_url  # fallback default

If the environment variable for the API base is present in the runner's environment (e.g., a developer who has tested against a self-hosted instance), get_llm_provider returns the env var value instead of the default base_url, causing the assertion on line 57 to fail. The analogous test_xiaomi_mimo_provider_resolution is unaffected because xiaomi_mimo does not define api_base_env.

Fix: pop the env var inside the test using mock.patch.dict before calling get_llm_provider, so the assertion always tests against the static default URL regardless of what is configured in the environment.

The CHARITY_ENGINE_API_BASE env var could override the base_url in CI,
causing test_charity_engine_provider_resolution to fail intermittently.
Comment thread litellm/llms/openai_like/providers.json Outdated
"api_key_env": "ASSEMBLYAI_API_KEY"
},
"charity_engine": {
"base_url": "https://api.charityengine.services/remotejobs/v2/inference/",

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.

Trailing slash in base_url produces double-slash endpoint

The base_url value ends with /. In dynamic_config.py (line 94-95), the get_complete_url method constructs the final endpoint like this:

if not api_base.endswith("/chat/completions"):
    api_base = f"{api_base}/chat/completions"

Because the value ends with / (not /chat/completions), the constructed URL becomes:

https://api.charityengine.services/remotejobs/v2/inference//chat/completions

The double slash // in the path could cause routing issues on strict server implementations, even though most servers normalize it. The same pattern exists in the chutes entry and may work in practice, but it is cleaner to remove the trailing slash to match the majority of providers:

Suggested change
"base_url": "https://api.charityengine.services/remotejobs/v2/inference/",
"base_url": "https://api.charityengine.services/remotejobs/v2/inference",

The corresponding assertion in test_charity_engine_provider_resolution (line 56) would also need updating to match.

@ghost
ghost merged commit 30b82c3 into BerriAI:main Mar 10, 2026
33 of 37 checks passed
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
* feat(charity_engine): add Charity Engine provider

Charity Engine is a crowdsourced distributed computing platform that
donates processing power to charitable causes. Its inference API
provides OpenAI-compatible chat, completions, and embeddings endpoints.

* test(charity_engine): add provider config and resolution tests

Verify JSONProviderRegistry config, provider list membership,
model routing for charity_engine/<model>, and Router compatibility.

* feat(charity_engine): add Charity Engine to LlmProviders enum

Enables provider_list membership and LlmProviders.CHARITY_ENGINE
resolution required by the provider and test suite.

* fix(charity_engine): remove api_base_env to fix non-deterministic test

The CHARITY_ENGINE_API_BASE env var could override the base_url in CI,
causing test_charity_engine_provider_resolution to fail intermittently.

* fix(charity_engine): remove trailing slash from base_url
This pull request was closed.
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