mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-14 09:03:16 +00:00
Merge 8c3e70f1cb into 9ffb82e139
This commit is contained in:
commit
dc9ff8e253
7 changed files with 172 additions and 1 deletions
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
74
tests/unit/llms/openai_like/test_apiko_provider.py
Normal file
74
tests/unit/llms/openai_like/test_apiko_provider.py
Normal 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"}],
|
||||
)
|
||||
Loading…
Add table
Reference in a new issue