mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
Merge de23d4175b into 76bf280d0a
This commit is contained in:
commit
d24affbd05
9 changed files with 190 additions and 0 deletions
|
|
@ -615,6 +615,7 @@ LITELLM_CHAT_PROVIDERS = [
|
|||
"dashscope",
|
||||
"moonshot",
|
||||
"publicai",
|
||||
"skypool",
|
||||
"v0",
|
||||
"heroku",
|
||||
"oci",
|
||||
|
|
@ -775,6 +776,7 @@ openai_compatible_endpoints: List = [
|
|||
"https://nano-gpt.com/api/v1",
|
||||
"https://api.poe.com/v1",
|
||||
"https://llm.chutes.ai/v1/",
|
||||
"https://a.skypool.xyz/v1",
|
||||
"https://api.v0.dev/v1",
|
||||
"https://api.morphllm.com/v1",
|
||||
"https://api.lambda.ai/v1",
|
||||
|
|
@ -824,6 +826,7 @@ openai_compatible_providers: List = [
|
|||
"nano-gpt", # Nano-GPT - JSON-configured provider
|
||||
"poe", # Poe - JSON-configured provider
|
||||
"chutes", # Chutes - JSON-configured provider
|
||||
"skypool", # Skypool - JSON-configured provider
|
||||
"featherless_ai",
|
||||
"nscale",
|
||||
"nebius",
|
||||
|
|
|
|||
|
|
@ -114,5 +114,13 @@
|
|||
"param_mappings": {
|
||||
"max_completion_tokens": "max_tokens"
|
||||
}
|
||||
},
|
||||
"skypool": {
|
||||
"base_url": "https://a.skypool.xyz/v1",
|
||||
"api_key_env": "SKYPOOL_API_KEY",
|
||||
"api_base_env": "SKYPOOL_API_BASE",
|
||||
"param_mappings": {
|
||||
"max_completion_tokens": "max_tokens"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3363,6 +3363,7 @@ class LlmProviders(str, Enum):
|
|||
NANOGPT = "nano-gpt"
|
||||
POE = "poe"
|
||||
CHUTES = "chutes"
|
||||
SKYPOOL = "skypool"
|
||||
XIAOMI_MIMO = "xiaomi_mimo"
|
||||
LITELLM_AGENT = "litellm_agent"
|
||||
CURSOR = "cursor"
|
||||
|
|
|
|||
|
|
@ -30477,6 +30477,66 @@
|
|||
"max_tokens": 8192,
|
||||
"mode": "chat"
|
||||
},
|
||||
"skypool/qwen3.5:122b": {
|
||||
"input_cost_per_token": 2.207565e-07,
|
||||
"litellm_provider": "skypool",
|
||||
"max_input_tokens": 131072,
|
||||
"max_output_tokens": 65536,
|
||||
"max_tokens": 65536,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.766052e-06,
|
||||
"source": "https://a.skypool.xyz/v1/models",
|
||||
"supports_function_calling": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"skypool/qwen3.5:9b": {
|
||||
"input_cost_per_token": 8.83026e-08,
|
||||
"litellm_provider": "skypool",
|
||||
"max_input_tokens": 131072,
|
||||
"max_output_tokens": 65536,
|
||||
"max_tokens": 65536,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.324539e-07,
|
||||
"source": "https://a.skypool.xyz/v1/models",
|
||||
"supports_function_calling": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"skypool/qwen3.6:35b": {
|
||||
"input_cost_per_token": 1.324539e-07,
|
||||
"litellm_provider": "skypool",
|
||||
"max_input_tokens": 65536,
|
||||
"max_output_tokens": 65536,
|
||||
"max_tokens": 65536,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 7.064208e-07,
|
||||
"source": "https://a.skypool.xyz/v1/models",
|
||||
"supports_function_calling": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"skypool/gemma4:26b": {
|
||||
"input_cost_per_token": 6.622695e-08,
|
||||
"litellm_provider": "skypool",
|
||||
"max_input_tokens": 131072,
|
||||
"max_output_tokens": 65536,
|
||||
"max_tokens": 65536,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 3.090591e-07,
|
||||
"source": "https://a.skypool.xyz/v1/models",
|
||||
"supports_function_calling": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"stability/sd3": {
|
||||
"litellm_provider": "stability",
|
||||
"mode": "image_generation",
|
||||
|
|
|
|||
|
|
@ -2063,6 +2063,22 @@
|
|||
"interactions": true
|
||||
}
|
||||
},
|
||||
"skypool": {
|
||||
"display_name": "Skypool (`skypool`)",
|
||||
"endpoints": {
|
||||
"chat_completions": true,
|
||||
"messages": false,
|
||||
"responses": false,
|
||||
"embeddings": false,
|
||||
"image_generations": false,
|
||||
"audio_transcriptions": false,
|
||||
"audio_speech": false,
|
||||
"moderations": false,
|
||||
"batches": false,
|
||||
"rerank": false,
|
||||
"a2a": false
|
||||
}
|
||||
},
|
||||
"synthetic": {
|
||||
"display_name": "Synthetic (`synthetic`)",
|
||||
"endpoints": {
|
||||
|
|
|
|||
87
tests/litellm/llms/openai_like/test_skypool_provider.py
Normal file
87
tests/litellm/llms/openai_like/test_skypool_provider.py
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
"""
|
||||
Unit tests for the Skypool OpenAI-compatible provider.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(
|
||||
0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../.."))
|
||||
)
|
||||
|
||||
from litellm.llms.openai_like.dynamic_config import create_config_class
|
||||
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
|
||||
|
||||
SKYPOOL_BASE_URL = "https://a.skypool.xyz/v1"
|
||||
|
||||
|
||||
def _get_config():
|
||||
provider = JSONProviderRegistry.get("skypool")
|
||||
assert provider is not None
|
||||
config_class = create_config_class(provider)
|
||||
return config_class()
|
||||
|
||||
|
||||
def test_skypool_provider_registered():
|
||||
provider = JSONProviderRegistry.get("skypool")
|
||||
assert provider is not None
|
||||
assert provider.base_url == SKYPOOL_BASE_URL
|
||||
assert provider.api_key_env == "SKYPOOL_API_KEY"
|
||||
assert provider.api_base_env == "SKYPOOL_API_BASE"
|
||||
assert provider.param_mappings["max_completion_tokens"] == "max_tokens"
|
||||
|
||||
|
||||
def test_skypool_resolves_env_api_key(monkeypatch):
|
||||
config = _get_config()
|
||||
monkeypatch.setenv("SKYPOOL_API_KEY", "test-key")
|
||||
api_base, api_key = config._get_openai_compatible_provider_info(None, None)
|
||||
assert api_base == SKYPOOL_BASE_URL
|
||||
assert api_key == "test-key"
|
||||
|
||||
|
||||
def test_skypool_resolves_env_api_base(monkeypatch):
|
||||
config = _get_config()
|
||||
monkeypatch.setenv("SKYPOOL_API_BASE", "https://example.com/v1")
|
||||
api_base, api_key = config._get_openai_compatible_provider_info(None, "test-key")
|
||||
assert api_base == "https://example.com/v1"
|
||||
assert api_key == "test-key"
|
||||
|
||||
|
||||
def test_skypool_complete_url_appends_endpoint():
|
||||
config = _get_config()
|
||||
url = config.get_complete_url(
|
||||
api_base=SKYPOOL_BASE_URL,
|
||||
api_key="test-key",
|
||||
model="skypool/gemma4:26b",
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
stream=False,
|
||||
)
|
||||
assert url == f"{SKYPOOL_BASE_URL}/chat/completions"
|
||||
|
||||
|
||||
def test_skypool_provider_resolution():
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
|
||||
|
||||
model, provider, api_key, api_base = get_llm_provider(
|
||||
model="skypool/gemma4:26b",
|
||||
custom_llm_provider=None,
|
||||
api_base=None,
|
||||
api_key=None,
|
||||
)
|
||||
|
||||
assert model == "gemma4:26b"
|
||||
assert provider == "skypool"
|
||||
assert api_base == SKYPOOL_BASE_URL
|
||||
|
||||
|
||||
def test_skypool_provider_config_manager():
|
||||
from litellm import LlmProviders
|
||||
from litellm.utils import ProviderConfigManager
|
||||
|
||||
config = ProviderConfigManager.get_provider_chat_config(
|
||||
model="gemma4:26b", provider=LlmProviders.SKYPOOL
|
||||
)
|
||||
|
||||
assert config is not None
|
||||
assert config.custom_llm_provider == "skypool"
|
||||
BIN
ui/litellm-dashboard/public/assets/logos/skypool.png
Normal file
BIN
ui/litellm-dashboard/public/assets/logos/skypool.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
|
|
@ -62,6 +62,12 @@ describe("provider_info_helpers", () => {
|
|||
expect(result.logo).toBe(providerLogoMap[Providers.Groq]);
|
||||
});
|
||||
|
||||
it("should map skypool provider value to Skypool display name and logo", () => {
|
||||
const result = getProviderLogoAndName("skypool");
|
||||
expect(result.displayName).toBe(Providers.Skypool);
|
||||
expect(result.logo).toBe(providerLogoMap[Providers.Skypool]);
|
||||
});
|
||||
|
||||
it("should handle provider values case-insensitively", () => {
|
||||
const result = getProviderLogoAndName("OPENAI");
|
||||
expect(result.displayName).toBe(Providers.OpenAI);
|
||||
|
|
@ -138,6 +144,10 @@ describe("provider_info_helpers", () => {
|
|||
expect(getPlaceholder(Providers.Snowflake)).toBe("snowflake/mistral-7b");
|
||||
});
|
||||
|
||||
it("should return skypool placeholder for Skypool provider", () => {
|
||||
expect(getPlaceholder(Providers.Skypool)).toBe("skypool/gemma4:26b");
|
||||
});
|
||||
|
||||
it("should return voyage placeholder for Voyage provider", () => {
|
||||
expect(getPlaceholder(Providers.Voyage)).toBe("voyage/");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ export enum Providers {
|
|||
Sambanova = "Sambanova",
|
||||
SAP = "SAP Generative AI Hub",
|
||||
Snowflake = "Snowflake",
|
||||
Skypool = "Skypool",
|
||||
TEXT_COMPLETION_CODESTRAL = "Text-Completion-Codestral",
|
||||
TogetherAI = "TogetherAI",
|
||||
TOPAZ = "Topaz",
|
||||
|
|
@ -195,6 +196,7 @@ export const provider_map: Record<string, string> = {
|
|||
Sambanova: "sambanova",
|
||||
SAP: "sap",
|
||||
Snowflake: "snowflake",
|
||||
Skypool: "skypool",
|
||||
TEXT_COMPLETION_CODESTRAL: "text-completion-codestral",
|
||||
TogetherAI: "together_ai",
|
||||
TOPAZ: "topaz",
|
||||
|
|
@ -286,6 +288,7 @@ export const providerLogoMap: Record<string, string> = {
|
|||
[Providers.Sambanova]: `${asset_logos_folder}sambanova.svg`,
|
||||
[Providers.SAP]: `${asset_logos_folder}sap.png`,
|
||||
[Providers.Snowflake]: `${asset_logos_folder}snowflake.svg`,
|
||||
[Providers.Skypool]: `${asset_logos_folder}skypool.png`,
|
||||
[Providers.TEXT_COMPLETION_CODESTRAL]: `${asset_logos_folder}mistral.svg`,
|
||||
[Providers.TogetherAI]: `${asset_logos_folder}togetherai.svg`,
|
||||
[Providers.TOPAZ]: `${asset_logos_folder}topaz.svg`,
|
||||
|
|
@ -352,6 +355,8 @@ export const getPlaceholder = (selectedProvider: string): string => {
|
|||
return "oci/xai.grok-4";
|
||||
} else if (selectedProvider == Providers.Snowflake) {
|
||||
return "snowflake/mistral-7b";
|
||||
} else if (selectedProvider == Providers.Skypool) {
|
||||
return "skypool/gemma4:26b";
|
||||
} else if (selectedProvider == Providers.Voyage) {
|
||||
return "voyage/";
|
||||
} else if (selectedProvider == Providers.JinaAI) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue