This commit is contained in:
hedging8563 2026-10-06 18:24:12 +00:00 • committed by GitHub
commit 859a25cd24
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 8054 additions and 0 deletions

View file

@ -394,6 +394,7 @@ Set `LITELLM_PROXY_API_BASE` and `LITELLM_PROXY_API_KEY` and every model call th
| [Text Completion Codestral (`text-completion-codestral`)](https://docs.litellm.ai/docs/providers/codestral) | ✅ | ✅ | ✅ | | | | | | | |
| [Text Completion OpenAI (`text-completion-openai`)](https://docs.litellm.ai/docs/providers/text_completion_openai) | ✅ | ✅ | ✅ | | | ✅ | ✅ | ✅ | ✅ | |
| [Together AI (`together_ai`)](https://docs.litellm.ai/docs/providers/togetherai) | ✅ | ✅ | ✅ | | | | | | | |
| [TokenLab (`tokenlab`)](https://tokenlab.sh/docs/en/integrations/litellm) | ✅ | ✅ | ✅ | ✅ | | | | | | |
| [Topaz (`topaz`)](https://docs.litellm.ai/docs/providers/topaz) | ✅ | ✅ | ✅ | | | | | | | |
| [Triton (`triton`)](https://docs.litellm.ai/docs/providers/triton-inference-server) | ✅ | ✅ | ✅ | | | | | | | |
| [Typesafe Decisions API (`typesafe`)](https://docs.litellm.ai/docs/providers) | | | | | | | | | | |

View file

@ -690,6 +690,7 @@ qwen_ai_platform_models: Set = set()
moonshot_models: Set = set()
publicai_models: Set = set()
darkbloom_models: Set = set()
tokenlab_models: Set[str] = set()
v0_models: Set = set()
morph_models: Set = set()
lambda_ai_models: Set = set()
@ -955,6 +956,8 @@ def _populate_provider_model_sets(model_cost_map: Dict) -> None:
publicai_models.add(key)
elif value.get("litellm_provider") == "darkbloom":
darkbloom_models.add(key)
elif value.get("litellm_provider") == "tokenlab" and isinstance(key, str):
tokenlab_models.add(key)
elif value.get("litellm_provider") == "v0":
v0_models.add(key)
elif value.get("litellm_provider") == "morph":
@ -1118,6 +1121,7 @@ model_list = list(
| moonshot_models
| publicai_models
| darkbloom_models
| tokenlab_models
| v0_models
| morph_models
| lambda_ai_models
@ -1230,6 +1234,7 @@ def _build_models_by_provider() -> dict:
"moonshot": moonshot_models,
"publicai": publicai_models,
"darkbloom": darkbloom_models,
"tokenlab": tokenlab_models,
"v0": v0_models,
"morph": morph_models,
"lambda_ai": lambda_ai_models,

View file

@ -960,6 +960,7 @@ openai_compatible_endpoints: Final[list] = [
"https://api.inference.wandb.ai/v1",
"https://api.clarifai.com/v2/ext/openai/v1",
"https://api.libertai.io/v1",
"https://api.tokenlab.sh/v1",
"https://pinstripes.io/v1",
"https://api.meta.ai/v1",
"https://api.sailresearch.com/v1",
@ -1037,6 +1038,7 @@ openai_compatible_providers: Final[list] = [
"docker_model_runner",
"ragflow",
"pinstripes", # Pinstripes - JSON-configured provider
"tokenlab", # TokenLab - JSON-configured provider
"darkbloom",
"meta", # Meta Model API (Muse Spark) - JSON-configured provider
"cognition",

View file

@ -78,6 +78,14 @@ class JSONProviderRegistry:
return False
return "/v1/responses" in provider.supported_endpoints
@classmethod
def supports_anthropic_messages_api(cls, slug: str) -> bool:
"""Check if a JSON provider supports the Anthropic Messages API"""
provider = cls._providers.get(slug)
if provider is None:
return False
return "/v1/messages" in provider.supported_endpoints
@classmethod
def list_providers(cls) -> list:
"""List all registered provider slugs"""

View file

@ -186,6 +186,15 @@
"api_base_env": "CORTECS_API_BASE",
"supported_endpoints": ["/v1/chat/completions", "/v1/responses", "/v1/messages"]
},
"tokenlab": {
"base_url": "https://api.tokenlab.sh/v1",
"api_key_env": "TOKENLAB_API_KEY",
"api_base_env": "TOKENLAB_API_BASE",
"param_mappings": {
"max_completion_tokens": "max_tokens"
},
"supported_endpoints": ["/v1/chat/completions", "/v1/messages", "/v1/responses", "/v1/embeddings"]
},
"pinstripes": {
"base_url": "https://pinstripes.io/v1",
"api_key_env": "PINSTRIPES_API_KEY",

File diff suppressed because it is too large Load diff

View file

@ -1664,6 +1664,23 @@
"a2a": false
}
},
"tokenlab": {
"display_name": "TokenLab (`tokenlab`)",
"url": "https://tokenlab.sh/docs/en/integrations/litellm",
"endpoints": {
"chat_completions": true,
"messages": true,
"responses": true,
"embeddings": true,
"image_generations": false,
"audio_transcriptions": false,
"audio_speech": false,
"moderations": false,
"batches": false,
"rerank": false,
"a2a": false
}
},
"nvidia_nim": {
"display_name": "Nvidia NIM (`nvidia_nim`)",
"url": "https://docs.litellm.ai/docs/providers/nvidia_nim",

View file

@ -3263,6 +3263,34 @@
],
"default_model_placeholder": "gpt-3.5-turbo"
},
{
"provider": "TOKENLAB",
"provider_display_name": "TokenLab",
"litellm_provider": "tokenlab",
"credential_fields": [
{
"key": "api_base",
"label": "API Base",
"placeholder": "https://api.tokenlab.sh/v1",
"tooltip": null,
"required": false,
"field_type": "text",
"options": null,
"default_value": null
},
{
"key": "api_key",
"label": "API Key",
"placeholder": null,
"tooltip": null,
"required": true,
"field_type": "password",
"options": null,
"default_value": null
}
],
"default_model_placeholder": "tokenlab/gpt-5.5"
},
{
"provider": "TOPAZ",
"provider_display_name": "Topaz",

View file

@ -4172,6 +4172,7 @@ class LlmProviders(str, Enum):
PARASAIL = "parasail"
XIAOMI_MIMO = "xiaomi_mimo"
TENSORMESH = "tensormesh"
TOKENLAB = "tokenlab"
LIBERTAI = "libertai"
PINSTRIPES = "pinstripes"
COGNITION = "cognition"

File diff suppressed because it is too large Load diff

View file

@ -2469,6 +2469,23 @@
"a2a": false
}
},
"tokenlab": {
"display_name": "TokenLab (`tokenlab`)",
"url": "https://tokenlab.sh/docs/en/integrations/litellm",
"endpoints": {
"chat_completions": true,
"messages": true,
"responses": true,
"embeddings": true,
"image_generations": false,
"audio_transcriptions": false,
"audio_speech": false,
"moderations": false,
"batches": false,
"rerank": false,
"a2a": false
}
},
"tensormesh": {
"display_name": "Tensormesh (`tensormesh`)",
"url": "https://docs.litellm.ai/docs/providers/tensormesh",

View file

@ -0,0 +1,200 @@
import pytest
import litellm
TOKENLAB_API_BASE = "https://api.tokenlab.sh/v1"
TOKENLAB_SAMPLE_MODELS = [
"tokenlab/gpt-5.5",
"tokenlab/claude-opus-4-8",
"tokenlab/gemini-3.5-flash",
"tokenlab/deepseek-v4-pro",
"tokenlab/qwen3.7-max",
"tokenlab/text-embedding-3-small",
]
def test_tokenlab_json_registry():
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
assert litellm.LlmProviders.TOKENLAB.value == "tokenlab"
assert litellm.LlmProviders("tokenlab") == litellm.LlmProviders.TOKENLAB
assert JSONProviderRegistry.exists("tokenlab")
config = JSONProviderRegistry.get("tokenlab")
assert config is not None
assert config.base_url == TOKENLAB_API_BASE
assert config.api_key_env == "TOKENLAB_API_KEY"
assert config.api_base_env == "TOKENLAB_API_BASE"
assert config.param_mappings["max_completion_tokens"] == "max_tokens"
assert config.supported_endpoints == [
"/v1/chat/completions",
"/v1/messages",
"/v1/responses",
"/v1/embeddings",
]
assert JSONProviderRegistry.supports_responses_api("tokenlab") is True
assert JSONProviderRegistry.supports_anthropic_messages_api("tokenlab") is True
def test_tokenlab_provider_detection_by_prefix():
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
model, provider, _, api_base = get_llm_provider("tokenlab/gpt-5.5")
assert model == "gpt-5.5"
assert provider == "tokenlab"
assert api_base == TOKENLAB_API_BASE
def test_tokenlab_api_base_override():
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
_, provider, api_key, api_base = get_llm_provider(
model="tokenlab/gpt-5.5",
api_base="https://custom.tokenlab.example/v1",
api_key="sk-test",
)
assert provider == "tokenlab"
assert api_base == "https://custom.tokenlab.example/v1"
assert api_key == "sk-test"
def test_tokenlab_url_autodetection():
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
_, provider, _, api_base = get_llm_provider(
model="gpt-5.5",
api_base=TOKENLAB_API_BASE,
)
assert provider == "tokenlab"
assert api_base == TOKENLAB_API_BASE
def test_tokenlab_chat_complete_url():
from litellm.llms.openai_like.dynamic_config import create_config_class
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
config = create_config_class(JSONProviderRegistry.get("tokenlab"))()
assert (
config.get_complete_url(
api_base=None,
api_key=None,
model="gpt-5.5",
optional_params={},
litellm_params={},
)
== "https://api.tokenlab.sh/v1/chat/completions"
)
def test_tokenlab_responses_api_config():
from litellm.llms.openai.responses.transformation import OpenAIResponsesAPIConfig
from litellm.utils import ProviderConfigManager
config = ProviderConfigManager.get_provider_responses_api_config(
provider="tokenlab",
model="tokenlab/gpt-5.5",
)
assert isinstance(config, OpenAIResponsesAPIConfig)
assert config.custom_llm_provider == "tokenlab"
assert config.get_complete_url(api_base=None, litellm_params={}) == "https://api.tokenlab.sh/v1/responses"
def test_tokenlab_anthropic_messages_config():
from litellm.llms.openai_like.messages.transformation import (
OpenAILikeAnthropicMessagesConfig,
)
from litellm.utils import ProviderConfigManager
config = ProviderConfigManager.get_provider_anthropic_messages_config(
provider=litellm.LlmProviders.TOKENLAB,
model="claude-opus-4-8",
)
assert isinstance(config, OpenAILikeAnthropicMessagesConfig)
assert (
config.get_complete_url(
api_base=TOKENLAB_API_BASE,
api_key="sk-test",
model="claude-opus-4-8",
optional_params={},
litellm_params={},
)
== "https://api.tokenlab.sh/v1/messages"
)
class TestTokenLabCostMap:
@pytest.fixture(autouse=True)
def _use_local_model_cost_map(self, monkeypatch):
original_model_cost = litellm.model_cost
monkeypatch.setenv("LITELLM_LOCAL_MODEL_COST_MAP", "True")
litellm.model_cost = litellm.get_model_cost_map(url="")
litellm.get_model_info.cache_clear()
try:
yield
finally:
litellm.model_cost = original_model_cost
litellm.get_model_info.cache_clear()
def test_sample_models_registered(self):
for model in TOKENLAB_SAMPLE_MODELS:
info = litellm.get_model_info(model)
assert info["litellm_provider"] == "tokenlab"
assert info["mode"] in {"chat", "embedding"}
def test_claude_model_cost_map_keeps_schema_supported_endpoints(self):
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
endpoints = litellm.model_cost["tokenlab/claude-opus-4-8"]["supported_endpoints"]
assert endpoints == ["/v1/chat/completions", "/v1/responses"]
provider_config = JSONProviderRegistry.get("tokenlab")
assert provider_config is not None
assert "/v1/messages" in provider_config.supported_endpoints
def test_chat_cost_is_wired(self):
prompt_cost, completion_cost = litellm.cost_per_token(
model="tokenlab/gpt-5.5",
prompt_tokens=100_000,
completion_tokens=100_000,
)
assert prompt_cost == pytest.approx(litellm.model_cost["tokenlab/gpt-5.5"]["input_cost_per_token"] * 100_000)
assert completion_cost == pytest.approx(
litellm.model_cost["tokenlab/gpt-5.5"]["output_cost_per_token"] * 100_000
)
assert prompt_cost > 0 and completion_cost > 0
def test_chat_cost_uses_the_long_context_tier(self):
assert (
litellm.model_cost["tokenlab/gpt-5.5"]["input_cost_per_token_above_272k_tokens"]
> litellm.model_cost["tokenlab/gpt-5.5"]["input_cost_per_token"]
)
prompt_cost, completion_cost = litellm.cost_per_token(
model="tokenlab/gpt-5.5",
prompt_tokens=300_000,
completion_tokens=100_000,
)
assert prompt_cost == pytest.approx(
litellm.model_cost["tokenlab/gpt-5.5"]["input_cost_per_token_above_272k_tokens"] * 300_000
)
assert completion_cost == pytest.approx(
litellm.model_cost["tokenlab/gpt-5.5"]["output_cost_per_token_above_272k_tokens"] * 100_000
)
def test_embedding_cost_is_wired(self):
prompt_cost, completion_cost = litellm.cost_per_token(
model="tokenlab/text-embedding-3-small",
prompt_tokens=1_000_000,
completion_tokens=0,
)
assert prompt_cost == pytest.approx(
litellm.model_cost["tokenlab/text-embedding-3-small"]["input_cost_per_token"] * 1_000_000
)
assert prompt_cost > 0
assert completion_cost == 0