This commit is contained in:
APIKO 2026-11-06 05:03:41 +00:00 • committed by GitHub
commit dc9ff8e253
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 172 additions and 1 deletions

View file

@ -290,6 +290,14 @@
"supports_function_calling": true
}
},
"apiko": {
"base_url": "https://api.apiko.app/v1",
"api_key_env": "APIKO_API_KEY",
"api_base_env": "APIKO_API_BASE",
"supported_endpoints": [
"/v1/chat/completions"
]
},
"streamlake": {
"base_url": "https://vanchin.streamlake.ai/api/gateway/v1/endpoints",
"api_key_env": "STREAMLAKE_API_KEY",

View file

@ -2792,9 +2792,17 @@ def _complete_custom_openai(
raise litellm.AuthenticationError(
message="Set BIGMODEL_API_KEY or pass api_key", llm_provider="bigmodel", model=model
)
if custom_llm_provider == "apiko" and not api_key:
raise litellm.AuthenticationError(
message="Set APIKO_API_KEY or pass api_key", llm_provider="apiko", model=model
)
organization = (
organization
or (None if custom_llm_provider == "bigmodel" else litellm.organization or get_secret("OPENAI_ORGANIZATION"))
or (
None
if custom_llm_provider in ("bigmodel", "apiko")
else litellm.organization or get_secret("OPENAI_ORGANIZATION")
)
or None # default - https://github.com/openai/openai-python/blob/284c1799070c723c6a553337134148a7ab088dd8/openai/util.py#L105
)
openai.organization = organization

View file

@ -5484,6 +5484,32 @@
"generateContent": true
}
},
"apiko": {
"display_name": "APIKO (`apiko`)",
"url": "https://docs.litellm.ai/docs/providers/apiko",
"endpoints": {
"chat_completions": true,
"responses": false,
"text_completion": false,
"embeddings": false,
"image_generations": false,
"image_edits": false,
"audio_transcriptions": false,
"audio_speech": false,
"rerank": false,
"ocr": false,
"search": false,
"moderations": false,
"realtime": false,
"video_generations": false,
"batches": false,
"messages": false,
"interactions": false,
"systemone": false,
"a2a": false,
"generateContent": false
}
},
"bigmodel": {
"display_name": "BigModel (Zhipu AI) (`bigmodel`)",
"url": "https://docs.bigmodel.cn/cn/guide/develop/responses/introduction",

View file

@ -535,6 +535,34 @@
],
"default_model_placeholder": "gpt-3.5-turbo"
},
{
"provider": "APIKO",
"provider_display_name": "APIKO",
"litellm_provider": "apiko",
"credential_fields": [
{
"key": "api_base",
"label": "API Base",
"placeholder": "https://api.apiko.app/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": "apiko/deepseek-v4-pro"
},
{
"provider": "AssemblyAI",
"provider_display_name": "AssemblyAI",

View file

@ -4761,6 +4761,7 @@ class LlmProviders(str, Enum):
MICROSOFT_365_COPILOT = "microsoft_365_copilot"
MINIMAX = "minimax"
SYNTHETIC = "synthetic"
APIKO = "apiko"
APERTIS = "apertis"
NANOGPT = "nano-gpt"
POE = "poe"

View file

@ -5484,6 +5484,32 @@
"generateContent": true
}
},
"apiko": {
"display_name": "APIKO (`apiko`)",
"url": "https://docs.litellm.ai/docs/providers/apiko",
"endpoints": {
"chat_completions": true,
"responses": false,
"text_completion": false,
"embeddings": false,
"image_generations": false,
"image_edits": false,
"audio_transcriptions": false,
"audio_speech": false,
"rerank": false,
"ocr": false,
"search": false,
"moderations": false,
"realtime": false,
"video_generations": false,
"batches": false,
"messages": false,
"interactions": false,
"systemone": false,
"a2a": false,
"generateContent": false
}
},
"bigmodel": {
"display_name": "BigModel (Zhipu AI) (`bigmodel`)",
"url": "https://docs.bigmodel.cn/cn/guide/develop/responses/introduction",

View file

@ -0,0 +1,74 @@
"""
Unit tests for the APIKO OpenAI-compatible provider.
"""
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../..")))
import pytest
import litellm
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
from litellm.llms.openai_like.dynamic_config import create_config_class
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
APIKO_BASE_URL = "https://api.apiko.app/v1"
def _get_config():
provider = JSONProviderRegistry.get("apiko")
assert provider is not None
return create_config_class(provider)()
def test_apiko_provider_registered():
provider = JSONProviderRegistry.get("apiko")
assert provider is not None
assert provider.base_url == APIKO_BASE_URL
assert provider.api_key_env == "APIKO_API_KEY"
assert provider.api_base_env == "APIKO_API_BASE"
assert litellm.LlmProviders.APIKO.value == "apiko"
def test_apiko_resolves_env_api_key(monkeypatch):
monkeypatch.delenv("APIKO_API_BASE", raising=False)
monkeypatch.setenv("APIKO_API_KEY", "test-key")
api_base, api_key = _get_config().get_openai_compatible_provider_info(None, None)
assert api_base == APIKO_BASE_URL
assert api_key == "test-key"
def test_apiko_model_prefix_routes_to_provider(monkeypatch):
monkeypatch.delenv("APIKO_API_BASE", raising=False)
monkeypatch.setenv("APIKO_API_KEY", "test-key")
model, provider, api_key, api_base = get_llm_provider("apiko/deepseek-v4-pro")
assert model == "deepseek-v4-pro"
assert provider == "apiko"
assert api_key == "test-key"
assert api_base == APIKO_BASE_URL
def test_apiko_complete_url_appends_endpoint():
url = _get_config().get_complete_url(
api_base=APIKO_BASE_URL,
api_key="test-key",
model="apiko/deepseek-v4-pro",
optional_params={},
litellm_params={},
stream=False,
)
assert url == f"{APIKO_BASE_URL}/chat/completions"
def test_apiko_does_not_fall_back_to_openai_key(monkeypatch):
monkeypatch.delenv("APIKO_API_KEY", raising=False)
monkeypatch.setenv("OPENAI_API_KEY", "sk-unrelated-openai-key")
monkeypatch.setattr(litellm, "api_key", None)
monkeypatch.setattr(litellm, "openai_key", None)
with pytest.raises(litellm.AuthenticationError, match="Set APIKO_API_KEY"):
litellm.completion(
model="apiko/deepseek-v4-pro",
messages=[{"role": "user", "content": "hi"}],
)