mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-14 09:03:16 +00:00
Merge 24f852a77b into 3f4dc93b40
This commit is contained in:
commit
ee49ad15b4
13 changed files with 481 additions and 0 deletions
|
|
@ -1090,6 +1090,7 @@ openai_compatible_endpoints: Final[list[str]] = [
|
|||
"https://api.cognition.ai/v1",
|
||||
"https://inference.coralbricks.ai/v1",
|
||||
"https://api.cortecs.ai/v1",
|
||||
"https://ai.eu.corti.app/v1",
|
||||
"https://api.scx.ai/v1",
|
||||
"https://api.prisminference.com/v1",
|
||||
"https://api.reka.ai/v1",
|
||||
|
|
@ -1175,6 +1176,7 @@ openai_compatible_providers: Final[list[str]] = [
|
|||
"cognition",
|
||||
"coralbricks",
|
||||
"cortecs",
|
||||
"corti",
|
||||
"scx-ai",
|
||||
"prism",
|
||||
"hostinger_router",
|
||||
|
|
|
|||
|
|
@ -216,6 +216,18 @@
|
|||
},
|
||||
"supported_endpoints": ["/v1/chat/completions", "/v1/responses"]
|
||||
},
|
||||
"corti": {
|
||||
"base_url": "https://ai.eu.corti.app/v1",
|
||||
"api_key_env": "CORTI_API_KEY",
|
||||
"api_base_env": "CORTI_API_BASE",
|
||||
"param_mappings": {
|
||||
"max_completion_tokens": "max_tokens"
|
||||
},
|
||||
"constraints": {
|
||||
"temperature_max": 1.0
|
||||
},
|
||||
"supported_endpoints": ["/v1/chat/completions", "/v1/responses"]
|
||||
},
|
||||
"scx-ai": {
|
||||
"base_url": "https://api.scx.ai/v1",
|
||||
"api_key_env": "SCX_API_KEY",
|
||||
|
|
|
|||
|
|
@ -48993,6 +48993,66 @@
|
|||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"corti/corti-s1": {
|
||||
"cache_read_input_token_cost": 2e-07,
|
||||
"input_cost_per_token": 2e-06,
|
||||
"litellm_provider": "corti",
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 8e-06,
|
||||
"source": "https://docs.corti.ai/models/models#pricing",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": false,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": false
|
||||
},
|
||||
"corti/corti-s1-instant": {
|
||||
"cache_read_input_token_cost": 2e-07,
|
||||
"input_cost_per_token": 2e-06,
|
||||
"litellm_provider": "corti",
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 8e-06,
|
||||
"source": "https://docs.corti.ai/models/models#pricing",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": false,
|
||||
"supports_response_schema": false,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": false
|
||||
},
|
||||
"corti/corti-s1-mini": {
|
||||
"cache_read_input_token_cost": 1e-07,
|
||||
"input_cost_per_token": 1e-06,
|
||||
"litellm_provider": "corti",
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4e-06,
|
||||
"source": "https://docs.corti.ai/models/models#pricing",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": false,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"corti/corti-s1-mini-instant": {
|
||||
"cache_read_input_token_cost": 1e-07,
|
||||
"input_cost_per_token": 1e-06,
|
||||
"litellm_provider": "corti",
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4e-06,
|
||||
"source": "https://docs.corti.ai/models/models#pricing",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": false,
|
||||
"supports_response_schema": false,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"snowflake/claude-3-5-sonnet": {
|
||||
"litellm_provider": "snowflake",
|
||||
"max_input_tokens": 200000,
|
||||
|
|
|
|||
|
|
@ -1139,6 +1139,24 @@
|
|||
"generateContent": true
|
||||
}
|
||||
},
|
||||
"corti": {
|
||||
"display_name": "Corti (`corti`)",
|
||||
"url": "https://docs.litellm.ai/docs/providers/corti",
|
||||
"endpoints": {
|
||||
"chat_completions": true,
|
||||
"messages": true,
|
||||
"responses": true,
|
||||
"embeddings": false,
|
||||
"image_generations": false,
|
||||
"audio_transcriptions": false,
|
||||
"audio_speech": false,
|
||||
"moderations": false,
|
||||
"batches": false,
|
||||
"rerank": false,
|
||||
"a2a": false,
|
||||
"interactions": false
|
||||
}
|
||||
},
|
||||
"custom": {
|
||||
"display_name": "Custom (`custom`)",
|
||||
"url": "https://docs.litellm.ai/docs/providers/custom_llm_server",
|
||||
|
|
|
|||
|
|
@ -1201,6 +1201,34 @@
|
|||
],
|
||||
"default_model_placeholder": "cortecs/gpt-6-sol"
|
||||
},
|
||||
{
|
||||
"provider": "CORTI",
|
||||
"provider_display_name": "Corti",
|
||||
"litellm_provider": "corti",
|
||||
"credential_fields": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "https://ai.eu.corti.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": "corti/corti-s1"
|
||||
},
|
||||
{
|
||||
"provider": "CUSTOM",
|
||||
"provider_display_name": "Custom",
|
||||
|
|
|
|||
|
|
@ -4769,6 +4769,7 @@ class LlmProviders(str, Enum):
|
|||
COGNITION = "cognition"
|
||||
CORALBRICKS = "coralbricks"
|
||||
CORTECS = "cortecs"
|
||||
CORTI = "corti"
|
||||
SCX_AI = "scx-ai"
|
||||
PRISM = "prism"
|
||||
OPENINFER = "openinfer"
|
||||
|
|
|
|||
|
|
@ -48993,6 +48993,66 @@
|
|||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"corti/corti-s1": {
|
||||
"cache_read_input_token_cost": 2e-07,
|
||||
"input_cost_per_token": 2e-06,
|
||||
"litellm_provider": "corti",
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 8e-06,
|
||||
"source": "https://docs.corti.ai/models/models#pricing",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": false,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": false
|
||||
},
|
||||
"corti/corti-s1-instant": {
|
||||
"cache_read_input_token_cost": 2e-07,
|
||||
"input_cost_per_token": 2e-06,
|
||||
"litellm_provider": "corti",
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 8e-06,
|
||||
"source": "https://docs.corti.ai/models/models#pricing",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": false,
|
||||
"supports_response_schema": false,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": false
|
||||
},
|
||||
"corti/corti-s1-mini": {
|
||||
"cache_read_input_token_cost": 1e-07,
|
||||
"input_cost_per_token": 1e-06,
|
||||
"litellm_provider": "corti",
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4e-06,
|
||||
"source": "https://docs.corti.ai/models/models#pricing",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": false,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"corti/corti-s1-mini-instant": {
|
||||
"cache_read_input_token_cost": 1e-07,
|
||||
"input_cost_per_token": 1e-06,
|
||||
"litellm_provider": "corti",
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4e-06,
|
||||
"source": "https://docs.corti.ai/models/models#pricing",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": false,
|
||||
"supports_response_schema": false,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"snowflake/claude-3-5-sonnet": {
|
||||
"litellm_provider": "snowflake",
|
||||
"max_input_tokens": 200000,
|
||||
|
|
|
|||
|
|
@ -1113,6 +1113,24 @@
|
|||
"generateContent": true
|
||||
}
|
||||
},
|
||||
"corti": {
|
||||
"display_name": "Corti (`corti`)",
|
||||
"url": "https://docs.litellm.ai/docs/providers/corti",
|
||||
"endpoints": {
|
||||
"chat_completions": true,
|
||||
"messages": true,
|
||||
"responses": true,
|
||||
"embeddings": false,
|
||||
"image_generations": false,
|
||||
"audio_transcriptions": false,
|
||||
"audio_speech": false,
|
||||
"moderations": false,
|
||||
"batches": false,
|
||||
"rerank": false,
|
||||
"a2a": false,
|
||||
"interactions": false
|
||||
}
|
||||
},
|
||||
"crusoe": {
|
||||
"display_name": "Crusoe (`crusoe`)",
|
||||
"url": "https://docs.litellm.ai/docs/providers/crusoe",
|
||||
|
|
|
|||
247
tests/unit/llms/openai_like/test_corti_provider.py
Normal file
247
tests/unit/llms/openai_like/test_corti_provider.py
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
import json
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
import pytest
|
||||
import respx
|
||||
|
||||
import litellm
|
||||
from litellm.caching.llm_caching_handler import LLMClientCache
|
||||
|
||||
_CHAT_COMPLETION: Final = {
|
||||
"id": "chatcmpl_corti",
|
||||
"object": "chat.completion",
|
||||
"created": 1_790_000_000,
|
||||
"model": "corti-s1",
|
||||
"choices": [
|
||||
{
|
||||
"index": 0,
|
||||
"message": {"role": "assistant", "content": "Hello from Corti"},
|
||||
"finish_reason": "stop",
|
||||
}
|
||||
],
|
||||
"usage": {"prompt_tokens": 4, "completion_tokens": 3, "total_tokens": 7},
|
||||
}
|
||||
|
||||
|
||||
def test_corti_provider_resolution(monkeypatch: pytest.MonkeyPatch):
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
|
||||
|
||||
monkeypatch.setenv("CORTI_API_KEY", "corti-test-key")
|
||||
monkeypatch.delenv("CORTI_API_BASE", raising=False)
|
||||
|
||||
model, provider, api_key, api_base = get_llm_provider(
|
||||
model="corti/corti-s1",
|
||||
custom_llm_provider=None,
|
||||
api_base=None,
|
||||
api_key=None,
|
||||
)
|
||||
|
||||
assert model == "corti-s1"
|
||||
assert provider == "corti"
|
||||
assert api_key == "corti-test-key"
|
||||
assert api_base == "https://ai.eu.corti.app/v1"
|
||||
|
||||
|
||||
def test_corti_provider_keeps_explicit_credentials(monkeypatch: pytest.MonkeyPatch):
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
|
||||
|
||||
monkeypatch.setenv("CORTI_API_KEY", "corti-env-key")
|
||||
monkeypatch.setenv("CORTI_API_BASE", "https://corti.env.example/v1")
|
||||
|
||||
_, provider, api_key, api_base = get_llm_provider(
|
||||
model="corti/corti-s1",
|
||||
custom_llm_provider=None,
|
||||
api_base="https://ai.us.corti.app/v1",
|
||||
api_key="corti-explicit-key",
|
||||
)
|
||||
|
||||
assert provider == "corti"
|
||||
assert api_key == "corti-explicit-key"
|
||||
assert api_base == "https://ai.us.corti.app/v1"
|
||||
|
||||
|
||||
def test_corti_api_base_env_overrides_default(monkeypatch: pytest.MonkeyPatch):
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
|
||||
|
||||
monkeypatch.setenv("CORTI_API_KEY", "corti-env-key")
|
||||
monkeypatch.setenv("CORTI_API_BASE", "https://ai.us.corti.app/v1")
|
||||
|
||||
_, provider, _, api_base = get_llm_provider(
|
||||
model="corti/corti-s1",
|
||||
custom_llm_provider=None,
|
||||
api_base=None,
|
||||
api_key=None,
|
||||
)
|
||||
|
||||
assert provider == "corti"
|
||||
assert api_base == "https://ai.us.corti.app/v1"
|
||||
|
||||
|
||||
def test_corti_api_base_autodetects_provider(monkeypatch: pytest.MonkeyPatch):
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
|
||||
|
||||
monkeypatch.setenv("CORTI_API_KEY", "corti-env-key")
|
||||
|
||||
model, provider, api_key, api_base = get_llm_provider(
|
||||
model="corti-s1",
|
||||
custom_llm_provider=None,
|
||||
api_base="https://ai.eu.corti.app/v1",
|
||||
api_key=None,
|
||||
)
|
||||
|
||||
assert model == "corti-s1"
|
||||
assert provider == "corti"
|
||||
assert api_key == "corti-env-key"
|
||||
assert api_base == "https://ai.eu.corti.app/v1"
|
||||
|
||||
|
||||
def test_corti_is_available_in_add_model_form():
|
||||
fields_path: Final = Path(litellm.__file__).parent / "proxy" / "public_endpoints" / "provider_create_fields.json"
|
||||
providers: Final = json.loads(fields_path.read_text())
|
||||
corti: Final = next(provider for provider in providers if provider["litellm_provider"] == "corti")
|
||||
|
||||
assert corti["provider"] == "CORTI"
|
||||
assert corti["provider_display_name"] == "Corti"
|
||||
assert corti["default_model_placeholder"] == "corti/corti-s1"
|
||||
assert {field["key"]: field["required"] for field in corti["credential_fields"]} == {
|
||||
"api_base": False,
|
||||
"api_key": True,
|
||||
}
|
||||
|
||||
|
||||
def test_corti_supported_endpoints():
|
||||
expected: Final = {
|
||||
"chat_completions": True,
|
||||
"messages": True,
|
||||
"responses": True,
|
||||
"embeddings": False,
|
||||
"image_generations": False,
|
||||
"audio_transcriptions": False,
|
||||
"audio_speech": False,
|
||||
"moderations": False,
|
||||
"batches": False,
|
||||
"rerank": False,
|
||||
"a2a": False,
|
||||
"interactions": False,
|
||||
}
|
||||
backup_path: Final = Path(litellm.__file__).parent / "provider_endpoints_support_backup.json"
|
||||
root_path: Final = Path(litellm.__file__).parent.parent / "provider_endpoints_support.json"
|
||||
|
||||
assert json.loads(backup_path.read_text())["providers"]["corti"]["endpoints"] == expected
|
||||
assert json.loads(root_path.read_text())["providers"]["corti"]["endpoints"] == expected
|
||||
|
||||
|
||||
def test_corti_chat_completion_request():
|
||||
with respx.mock() as upstream:
|
||||
route: Final = upstream.post("https://ai.eu.corti.app/v1/chat/completions").respond(200, json=_CHAT_COMPLETION)
|
||||
response: Final = litellm.completion(
|
||||
model="corti/corti-s1",
|
||||
messages=[{"role": "user", "content": "Say hello"}],
|
||||
api_key="corti-test-key",
|
||||
)
|
||||
|
||||
request: Final = route.calls.last.request
|
||||
body: Final = json.loads(request.content)
|
||||
assert route.call_count == 1
|
||||
assert str(request.url) == "https://ai.eu.corti.app/v1/chat/completions"
|
||||
assert request.headers["authorization"] == "Bearer corti-test-key"
|
||||
assert body["model"] == "corti-s1"
|
||||
assert body["messages"] == [{"role": "user", "content": "Say hello"}]
|
||||
assert response.choices[0].message.content == "Hello from Corti"
|
||||
|
||||
|
||||
def test_corti_chat_completion_maps_unsupported_params():
|
||||
with respx.mock() as upstream:
|
||||
route: Final = upstream.post("https://ai.eu.corti.app/v1/chat/completions").respond(200, json=_CHAT_COMPLETION)
|
||||
litellm.completion(
|
||||
model="corti/corti-s1",
|
||||
messages=[{"role": "user", "content": "Say hello"}],
|
||||
api_key="corti-test-key",
|
||||
max_completion_tokens=64,
|
||||
temperature=1.5,
|
||||
)
|
||||
|
||||
body: Final = json.loads(route.calls.last.request.content)
|
||||
assert body["max_tokens"] == 64
|
||||
assert "max_completion_tokens" not in body
|
||||
assert body["temperature"] == 1.0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", ["corti-s1", "corti-s1-instant", "corti-s1-mini", "corti-s1-mini-instant"])
|
||||
def test_corti_chat_completion_cost_comes_from_the_price_map(model: str):
|
||||
with respx.mock() as upstream:
|
||||
upstream.post("https://ai.eu.corti.app/v1/chat/completions").respond(
|
||||
200, json={**_CHAT_COMPLETION, "model": model}
|
||||
)
|
||||
response: Final = litellm.completion(
|
||||
model=f"corti/{model}",
|
||||
messages=[{"role": "user", "content": "Say hello"}],
|
||||
api_key="corti-test-key",
|
||||
)
|
||||
|
||||
row: Final = litellm.model_cost[f"corti/{model}"]
|
||||
expected: Final = 4 * row["input_cost_per_token"] + 3 * row["output_cost_per_token"]
|
||||
assert litellm.completion_cost(completion_response=response) == pytest.approx(expected)
|
||||
assert expected > 0
|
||||
|
||||
|
||||
def test_corti_responses_request():
|
||||
with respx.mock() as upstream:
|
||||
route: Final = upstream.post("https://ai.eu.corti.app/v1/responses").respond(
|
||||
200,
|
||||
json={
|
||||
"id": "resp_corti",
|
||||
"object": "response",
|
||||
"created_at": 1_790_000_000,
|
||||
"model": "corti-s1",
|
||||
"status": "completed",
|
||||
"output": [
|
||||
{
|
||||
"id": "msg_corti",
|
||||
"type": "message",
|
||||
"role": "assistant",
|
||||
"status": "completed",
|
||||
"content": [{"type": "output_text", "text": "Hello from Corti", "annotations": []}],
|
||||
}
|
||||
],
|
||||
"usage": {"input_tokens": 4, "output_tokens": 3, "total_tokens": 7},
|
||||
},
|
||||
)
|
||||
response: Final = litellm.responses(
|
||||
model="corti/corti-s1",
|
||||
input="Say hello",
|
||||
api_key="corti-test-key",
|
||||
)
|
||||
|
||||
request: Final = route.calls.last.request
|
||||
body: Final = json.loads(request.content)
|
||||
assert route.call_count == 1
|
||||
assert str(request.url) == "https://ai.eu.corti.app/v1/responses"
|
||||
assert request.headers["authorization"] == "Bearer corti-test-key"
|
||||
assert body["model"] == "corti-s1"
|
||||
assert body["input"] == "Say hello"
|
||||
assert response.output[0].content[0].text == "Hello from Corti"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_corti_anthropic_messages_request_is_bridged_to_chat_completions(monkeypatch: pytest.MonkeyPatch):
|
||||
monkeypatch.setattr(litellm, "disable_aiohttp_transport", True)
|
||||
monkeypatch.setattr(litellm, "in_memory_llm_clients_cache", LLMClientCache())
|
||||
with respx.mock() as upstream:
|
||||
route: Final = upstream.post("https://ai.eu.corti.app/v1/chat/completions").respond(200, json=_CHAT_COMPLETION)
|
||||
response: Final = await litellm.anthropic.messages.acreate(
|
||||
model="corti/corti-s1",
|
||||
messages=[{"role": "user", "content": "Say hello"}],
|
||||
max_tokens=32,
|
||||
api_key="corti-test-key",
|
||||
)
|
||||
|
||||
request: Final = route.calls.last.request
|
||||
body: Final = json.loads(request.content)
|
||||
assert route.call_count == 1
|
||||
assert request.headers["authorization"] == "Bearer corti-test-key"
|
||||
assert body["model"] == "corti-s1"
|
||||
assert body["messages"] == [{"role": "user", "content": "Say hello"}]
|
||||
assert body["max_tokens"] == 32
|
||||
assert response["content"][0]["text"] == "Hello from Corti"
|
||||
14
ui/litellm-dashboard/public/assets/logos/corti.svg
Normal file
14
ui/litellm-dashboard/public/assets/logos/corti.svg
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<svg width="256" height="256" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_612_3664)">
|
||||
<circle cx="128" cy="128" r="128" fill="black"/>
|
||||
<path d="M126.415 53.8974C86.2057 53.9971 53.6403 86.6241 53.6403 126.857C53.6403 167.052 86.1438 199.655 126.301 199.816C126.489 204.448 126.875 209.079 127.458 213.71C127.173 213.713 126.887 213.714 126.6 213.714C78.6304 213.714 39.7432 174.827 39.7432 126.857C39.7432 78.8873 78.6304 40 126.6 40C126.993 40 127.385 40.0026 127.776 40.0078C127.125 44.6377 126.672 49.2675 126.415 53.8974Z" fill="white"/>
|
||||
<path d="M196.297 178.697C196.834 172.672 197.704 166.647 198.909 160.622C203.252 138.908 203.252 117.194 198.909 95.4794C197.526 88.5618 196.583 81.6442 196.081 74.7266C206.992 89.2459 213.458 107.296 213.458 126.857C213.458 146.287 207.077 164.228 196.297 178.697Z" fill="white"/>
|
||||
<path d="M168.161 203.144C167.295 188.97 168.28 174.797 171.115 160.623C175.457 138.909 175.457 117.194 171.115 95.4801C168.126 80.5388 167.194 65.5975 168.318 50.6562C173.099 53.2789 177.605 56.3382 181.785 59.7806C181.556 71.6804 182.632 83.5803 185.012 95.4801C189.355 117.194 189.355 138.909 185.012 160.623C182.789 171.734 181.704 182.846 181.756 193.957C177.539 197.428 172.989 200.508 168.161 203.144Z" fill="white"/>
|
||||
<path d="M141.207 212.492C139.158 195.202 139.863 177.913 143.321 160.623C147.663 138.909 147.663 117.195 143.321 95.4803C139.707 77.4114 139.1 59.3424 141.501 41.2734C146.127 42.0733 150.629 43.2393 154.974 44.7404C153.087 61.6537 153.835 78.567 157.218 95.4803C161.561 117.195 161.561 138.909 157.218 160.623C153.989 176.768 153.161 192.913 154.733 209.057C150.371 210.55 145.851 211.705 141.207 212.492Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_612_3664">
|
||||
<rect width="256" height="256" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
|
|
@ -142,6 +142,17 @@ describe("provider_info_helpers", () => {
|
|||
expect(fromEnumKey.logo).toBe(providerLogoMap[Providers.SCX_AI]);
|
||||
});
|
||||
|
||||
it("should map corti slug and CORTI enum key to the Corti display name and logo", () => {
|
||||
const fromSlug = getProviderLogoAndName("corti");
|
||||
expect(fromSlug.displayName).toBe(Providers.CORTI);
|
||||
expect(fromSlug.logo).toBe(providerLogoMap[Providers.CORTI]);
|
||||
expect(fromSlug.logo).toBeTruthy();
|
||||
|
||||
const fromEnumKey = getProviderLogoAndName("CORTI");
|
||||
expect(fromEnumKey.displayName).toBe(Providers.CORTI);
|
||||
expect(fromEnumKey.logo).toBe(providerLogoMap[Providers.CORTI]);
|
||||
});
|
||||
|
||||
it("should map bedrock_mantle slug to Bedrock Mantle display name and logo", () => {
|
||||
const result = getProviderLogoAndName("bedrock_mantle");
|
||||
expect(result.displayName).toBe(Providers.BedrockMantle);
|
||||
|
|
@ -325,6 +336,10 @@ describe("provider_info_helpers", () => {
|
|||
expect(getPlaceholder(Providers.SCX_AI)).toBe("scx-ai/GLM-5.2");
|
||||
});
|
||||
|
||||
it("should return a corti model placeholder for CORTI provider", () => {
|
||||
expect(getPlaceholder(Providers.CORTI)).toBe("corti/corti-s1");
|
||||
});
|
||||
|
||||
it("should return an edenai model placeholder for EDENAI provider", () => {
|
||||
expect(getPlaceholder(Providers.EDENAI)).toBe("edenai/openai/gpt-mini-latest");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import cerebrasLogo from "../../public/assets/logos/cerebras.svg";
|
|||
import cloudflareLogo from "../../public/assets/logos/cloudflare.svg";
|
||||
import cohereLogo from "../../public/assets/logos/cohere.svg";
|
||||
import cometapiLogo from "../../public/assets/logos/cometapi.svg";
|
||||
import cortiLogo from "../../public/assets/logos/corti.svg";
|
||||
import cursorLogo from "../../public/assets/logos/cursor.svg";
|
||||
import databricksLogo from "../../public/assets/logos/databricks.svg";
|
||||
import deepgramLogo from "../../public/assets/logos/deepgram.png";
|
||||
|
|
@ -107,6 +108,7 @@ export enum Providers {
|
|||
COMETAPI = "Cometapi",
|
||||
COMPACTIFAI = "Compactifai",
|
||||
CORALBRICKS = "CoralBricks",
|
||||
CORTI = "Corti",
|
||||
Cursor = "Cursor",
|
||||
Dashscope = "Dashscope",
|
||||
Databricks = "Databricks (Qwen API)",
|
||||
|
|
@ -242,6 +244,7 @@ export const provider_map: Record<string, string> = {
|
|||
COMETAPI: "cometapi",
|
||||
COMPACTIFAI: "compactifai",
|
||||
CORALBRICKS: "coralbricks",
|
||||
CORTI: "corti",
|
||||
Cursor: "cursor",
|
||||
Dashscope: "dashscope",
|
||||
Databricks: "databricks",
|
||||
|
|
@ -378,6 +381,7 @@ export const providerLogoMap: Partial<Record<Providers, string>> = {
|
|||
[Providers.Cohere]: cohereLogo.src,
|
||||
[Providers.COHERE_CHAT]: cohereLogo.src,
|
||||
[Providers.COMETAPI]: cometapiLogo.src,
|
||||
[Providers.CORTI]: cortiLogo.src,
|
||||
[Providers.Cursor]: cursorLogo.src,
|
||||
[Providers.Databricks]: databricksLogo.src,
|
||||
[Providers.Dashscope]: qwenLogo.src,
|
||||
|
|
@ -498,6 +502,7 @@ const providerPlaceholderMap: Partial<Record<Providers, string>> = {
|
|||
[Providers.CHATGPT]: "chatgpt/gpt-5.4",
|
||||
[Providers.Cognition]: "cognition/swe-1.7",
|
||||
[Providers.CORALBRICKS]: "coralbricks/glm-5.3-fast",
|
||||
[Providers.CORTI]: "corti/corti-s1",
|
||||
[Providers.Cursor]: "cursor/claude-4-sonnet",
|
||||
[Providers.DeepInfra]: "deepinfra/<any-model-on-deepinfra>",
|
||||
[Providers.EDENAI]: "edenai/openai/gpt-mini-latest",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ const BUNDLED_LOGO_PATH = /(?:\/assets\/logos\/|\/_next\/static\/media\/)/;
|
|||
|
||||
const TREATMENT_BY_ASSET: Readonly<Record<string, LogoTreatment>> = {
|
||||
"baseten.svg": "invert",
|
||||
"corti.svg": "invert",
|
||||
"cursor.svg": "invert",
|
||||
"edenai.svg": "invert",
|
||||
"enkrypt_ai.avif": "invert",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue