mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-15 09:12:18 +00:00
Merge 0ac8516056 into fc8f614a03
This commit is contained in:
commit
0d1e39b41e
5 changed files with 443 additions and 7 deletions
|
|
@ -87,15 +87,13 @@
|
|||
"api_key_env": "GMI_API_KEY"
|
||||
},
|
||||
"sarvam": {
|
||||
"base_url": "https://api.sarvam.ai/v1",
|
||||
"base_url": "https://api.sarvam.ai/v2",
|
||||
"api_key_env": "SARVAM_API_KEY",
|
||||
"base_class": "openai_gpt",
|
||||
"param_mappings": {
|
||||
"max_completion_tokens": "max_tokens"
|
||||
},
|
||||
"headers": {
|
||||
"api-subscription-key": "{api_key}"
|
||||
}
|
||||
"supported_endpoints": [
|
||||
"/v1/chat/completions",
|
||||
"/v1/responses"
|
||||
]
|
||||
},
|
||||
"assemblyai": {
|
||||
"base_url": "https://llm-gateway.assemblyai.com/v1",
|
||||
|
|
|
|||
|
|
@ -59737,14 +59737,142 @@
|
|||
"cache_creation_input_token_cost": 0,
|
||||
"cache_creation_input_token_cost_above_1hr": 0,
|
||||
"cache_read_input_token_cost": 0,
|
||||
"deprecation_date": "2026-06-05",
|
||||
"input_cost_per_token": 0,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 8192,
|
||||
"max_output_tokens": 32000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0,
|
||||
"source": "https://docs.sarvam.ai/changelog/2026/6/5.md",
|
||||
"supports_reasoning": true
|
||||
},
|
||||
"sarvam/sarvam-105b": {
|
||||
"cache_read_input_token_cost": 6e-08,
|
||||
"input_cost_per_token": 1.7e-07,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 128000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 6.7e-07,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": false
|
||||
},
|
||||
"sarvam/sarvam-105b-conversations": {
|
||||
"cache_read_input_token_cost": 6e-08,
|
||||
"input_cost_per_token": 1.7e-07,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 32000,
|
||||
"max_output_tokens": 32000,
|
||||
"max_tokens": 32000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 6.7e-07,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": false,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": false
|
||||
},
|
||||
"sarvam/glm5.3": {
|
||||
"cache_read_input_token_cost": 2.2e-07,
|
||||
"input_cost_per_token": 1.4e-06,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4.33e-06,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": false
|
||||
},
|
||||
"sarvam/glm5.3-flash": {
|
||||
"cache_read_input_token_cost": 3e-08,
|
||||
"input_cost_per_token": 1.5e-07,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 5.0e-07,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": true
|
||||
},
|
||||
"sarvam/gemma4": {
|
||||
"cache_read_input_token_cost": 1.1e-07,
|
||||
"input_cost_per_token": 3.9e-07,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 262144,
|
||||
"max_output_tokens": 262144,
|
||||
"max_tokens": 262144,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.0e-06,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": true
|
||||
},
|
||||
"sarvam/deepseekv4.1-flash-1017": {
|
||||
"cache_read_input_token_cost": 1e-08,
|
||||
"input_cost_per_token": 2.8e-07,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.17e-06,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": true
|
||||
},
|
||||
"tts-1-1106": {
|
||||
"input_cost_per_character": 1.5e-05,
|
||||
"litellm_provider": "openai",
|
||||
|
|
|
|||
|
|
@ -3687,6 +3687,34 @@
|
|||
],
|
||||
"default_model_placeholder": "sap/gpt-4"
|
||||
},
|
||||
{
|
||||
"provider": "SARVAM",
|
||||
"provider_display_name": "Sarvam",
|
||||
"litellm_provider": "sarvam",
|
||||
"credential_fields": [
|
||||
{
|
||||
"key": "api_base",
|
||||
"label": "API Base",
|
||||
"placeholder": "https://api.sarvam.ai/v2",
|
||||
"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": "sarvam/sarvam-105b"
|
||||
},
|
||||
{
|
||||
"provider": "SCX_AI",
|
||||
"provider_display_name": "SCX.ai",
|
||||
|
|
|
|||
|
|
@ -59737,14 +59737,142 @@
|
|||
"cache_creation_input_token_cost": 0,
|
||||
"cache_creation_input_token_cost_above_1hr": 0,
|
||||
"cache_read_input_token_cost": 0,
|
||||
"deprecation_date": "2026-06-05",
|
||||
"input_cost_per_token": 0,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 8192,
|
||||
"max_output_tokens": 32000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 0,
|
||||
"source": "https://docs.sarvam.ai/changelog/2026/6/5.md",
|
||||
"supports_reasoning": true
|
||||
},
|
||||
"sarvam/sarvam-105b": {
|
||||
"cache_read_input_token_cost": 6e-08,
|
||||
"input_cost_per_token": 1.7e-07,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 128000,
|
||||
"max_output_tokens": 128000,
|
||||
"max_tokens": 128000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 6.7e-07,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": false
|
||||
},
|
||||
"sarvam/sarvam-105b-conversations": {
|
||||
"cache_read_input_token_cost": 6e-08,
|
||||
"input_cost_per_token": 1.7e-07,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 32000,
|
||||
"max_output_tokens": 32000,
|
||||
"max_tokens": 32000,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 6.7e-07,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": false,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": false
|
||||
},
|
||||
"sarvam/glm5.3": {
|
||||
"cache_read_input_token_cost": 2.2e-07,
|
||||
"input_cost_per_token": 1.4e-06,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4.33e-06,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": false
|
||||
},
|
||||
"sarvam/glm5.3-flash": {
|
||||
"cache_read_input_token_cost": 3e-08,
|
||||
"input_cost_per_token": 1.5e-07,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 5.0e-07,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": true
|
||||
},
|
||||
"sarvam/gemma4": {
|
||||
"cache_read_input_token_cost": 1.1e-07,
|
||||
"input_cost_per_token": 3.9e-07,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 262144,
|
||||
"max_output_tokens": 262144,
|
||||
"max_tokens": 262144,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.0e-06,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": true
|
||||
},
|
||||
"sarvam/deepseekv4.1-flash-1017": {
|
||||
"cache_read_input_token_cost": 1e-08,
|
||||
"input_cost_per_token": 2.8e-07,
|
||||
"litellm_provider": "sarvam",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.17e-06,
|
||||
"source": "https://www.sarvam.ai/token-factory/pricing",
|
||||
"supports_audio_input": false,
|
||||
"supports_function_calling": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_video_input": false,
|
||||
"supports_vision": true
|
||||
},
|
||||
"tts-1-1106": {
|
||||
"input_cost_per_character": 1.5e-05,
|
||||
"litellm_provider": "openai",
|
||||
|
|
|
|||
154
tests/unit/llms/openai_like/test_sarvam_provider.py
Normal file
154
tests/unit/llms/openai_like/test_sarvam_provider.py
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
"""
|
||||
Tests for the Sarvam provider configuration and cost map entries.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
import respx
|
||||
|
||||
import litellm
|
||||
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
|
||||
|
||||
SARVAM_MODELS = (
|
||||
"sarvam/sarvam-105b",
|
||||
"sarvam/sarvam-105b-conversations",
|
||||
"sarvam/glm5.3",
|
||||
"sarvam/glm5.3-flash",
|
||||
"sarvam/gemma4",
|
||||
"sarvam/deepseekv4.1-flash-1017",
|
||||
)
|
||||
|
||||
|
||||
class TestSarvamProviderConfig:
|
||||
def test_sarvam_provider_resolution(self):
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
|
||||
|
||||
model, provider, api_key, api_base = get_llm_provider(
|
||||
model="sarvam/sarvam-105b",
|
||||
custom_llm_provider=None,
|
||||
api_base=None,
|
||||
api_key=None,
|
||||
)
|
||||
|
||||
assert model == "sarvam-105b"
|
||||
assert provider == "sarvam"
|
||||
assert api_base == "https://api.sarvam.ai/v2"
|
||||
|
||||
def test_sarvam_responses_api_enabled(self):
|
||||
from litellm.utils import ProviderConfigManager
|
||||
|
||||
assert JSONProviderRegistry.supports_responses_api("sarvam") is True
|
||||
config = ProviderConfigManager.get_provider_responses_api_config(
|
||||
provider="sarvam",
|
||||
model="sarvam/sarvam-105b",
|
||||
)
|
||||
assert config is not None
|
||||
assert config.custom_llm_provider == "sarvam"
|
||||
|
||||
def test_sarvam_listed_in_add_model_provider_fields(self):
|
||||
from pathlib import Path
|
||||
|
||||
fields_path = Path(litellm.__file__).parent / "proxy" / "public_endpoints" / "provider_create_fields.json"
|
||||
entries = json.loads(fields_path.read_text())
|
||||
sarvam_entries = [entry for entry in entries if entry["litellm_provider"] == "sarvam"]
|
||||
|
||||
assert len(sarvam_entries) == 1
|
||||
entry = sarvam_entries[0]
|
||||
assert entry["provider"] == "SARVAM"
|
||||
assert entry["provider_display_name"] == "Sarvam"
|
||||
assert entry["default_model_placeholder"] == "sarvam/sarvam-105b"
|
||||
field_keys = {field["key"] for field in entry["credential_fields"]}
|
||||
assert "api_key" in field_keys
|
||||
assert "api_base" in field_keys
|
||||
|
||||
def test_sarvam_chat_completion_request(self):
|
||||
with respx.mock() as upstream:
|
||||
route = upstream.post("https://api.sarvam.ai/v2/chat/completions").respond(
|
||||
200,
|
||||
json={
|
||||
"id": "chatcmpl_sarvam",
|
||||
"object": "chat.completion",
|
||||
"created": 1,
|
||||
"model": "sarvam-105b",
|
||||
"choices": [
|
||||
{
|
||||
"index": 0,
|
||||
"message": {"role": "assistant", "content": "Hello"},
|
||||
"finish_reason": "stop",
|
||||
}
|
||||
],
|
||||
"usage": {"prompt_tokens": 4, "completion_tokens": 3, "total_tokens": 7},
|
||||
},
|
||||
)
|
||||
response = litellm.completion(
|
||||
model="sarvam/sarvam-105b",
|
||||
messages=[{"role": "user", "content": "Say hello"}],
|
||||
api_key="sarvam-test-key",
|
||||
max_completion_tokens=200,
|
||||
)
|
||||
|
||||
request = route.calls.last.request
|
||||
body = json.loads(request.content)
|
||||
assert route.call_count == 1
|
||||
assert str(request.url) == "https://api.sarvam.ai/v2/chat/completions"
|
||||
assert request.headers["authorization"] == "Bearer sarvam-test-key"
|
||||
# LiteLLM maps max_completion_tokens to max_tokens for OpenAI-compatible providers.
|
||||
assert body.get("max_completion_tokens", body.get("max_tokens")) == 200
|
||||
assert response.choices[0].message.content == "Hello"
|
||||
|
||||
def test_sarvam_responses_request(self):
|
||||
with respx.mock() as upstream:
|
||||
route = upstream.post("https://api.sarvam.ai/v2/responses").respond(
|
||||
200,
|
||||
json={
|
||||
"id": "resp_sarvam",
|
||||
"object": "response",
|
||||
"created_at": 1,
|
||||
"model": "sarvam-105b",
|
||||
"status": "completed",
|
||||
"output": [
|
||||
{
|
||||
"id": "msg_sarvam",
|
||||
"type": "message",
|
||||
"role": "assistant",
|
||||
"status": "completed",
|
||||
"content": [{"type": "output_text", "text": "Hello", "annotations": []}],
|
||||
}
|
||||
],
|
||||
"usage": {"input_tokens": 4, "output_tokens": 3, "total_tokens": 7},
|
||||
},
|
||||
)
|
||||
response = litellm.responses(
|
||||
model="sarvam/sarvam-105b",
|
||||
input="Say hello",
|
||||
api_key="sarvam-test-key",
|
||||
)
|
||||
|
||||
request = route.calls.last.request
|
||||
assert route.call_count == 1
|
||||
assert str(request.url) == "https://api.sarvam.ai/v2/responses"
|
||||
assert request.headers["authorization"] == "Bearer sarvam-test-key"
|
||||
assert response.output_text == "Hello"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("local_model_cost_map")
|
||||
class TestSarvamCostMap:
|
||||
@pytest.mark.parametrize("model", SARVAM_MODELS)
|
||||
def test_model_registered(self, model):
|
||||
assert model in litellm.model_cost
|
||||
|
||||
entry = litellm.model_cost[model]
|
||||
assert entry["litellm_provider"] == "sarvam"
|
||||
assert entry["mode"] == "chat"
|
||||
|
||||
@pytest.mark.parametrize("model", SARVAM_MODELS)
|
||||
def test_cached_input_cost_is_set(self, model):
|
||||
entry = litellm.model_cost[model]
|
||||
assert entry["cache_read_input_token_cost"] > 0
|
||||
|
||||
def test_sarvam_m_kept_for_deprecation(self):
|
||||
# Source: https://docs.sarvam.ai/changelog/2026/6/5.md (2026-06-05)
|
||||
entry = litellm.model_cost["sarvam/sarvam-m"]
|
||||
assert entry["deprecation_date"] == "2026-06-05"
|
||||
assert entry["cache_creation_input_token_cost_above_1hr"] == 0
|
||||
Loading…
Add table
Reference in a new issue