mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
feat: add Meta Model API provider and muse-spark-1.1 (day-0) (#32701)
This commit is contained in:
parent
74623b12b1
commit
d82645d163
12 changed files with 469 additions and 1 deletions
|
|
@ -715,6 +715,7 @@ openai_compatible_endpoints: List = [
|
|||
"https://api.clarifai.com/v2/ext/openai/v1",
|
||||
"https://api.libertai.io/v1",
|
||||
"https://pinstripes.io/v1",
|
||||
"https://api.meta.ai/v1",
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -781,6 +782,7 @@ openai_compatible_providers: List = [
|
|||
"ragflow",
|
||||
"pinstripes", # Pinstripes - JSON-configured provider
|
||||
"darkbloom",
|
||||
"meta", # Meta Model API (Muse Spark) - JSON-configured provider
|
||||
]
|
||||
openai_text_completion_compatible_providers: List = [ # providers that support `/v1/completions`
|
||||
"together_ai",
|
||||
|
|
|
|||
|
|
@ -346,6 +346,9 @@ def get_llm_provider(
|
|||
elif endpoint == "https://pinstripes.io/v1":
|
||||
custom_llm_provider = "pinstripes"
|
||||
dynamic_api_key = get_secret_str("PINSTRIPES_API_KEY")
|
||||
elif endpoint == "https://api.meta.ai/v1":
|
||||
custom_llm_provider = "meta"
|
||||
dynamic_api_key = get_secret_str("META_API_KEY")
|
||||
|
||||
if api_base is not None and not isinstance(api_base, str):
|
||||
raise Exception("api base needs to be a string. api_base={}".format(api_base))
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ def create_config_class(provider: SimpleProviderConfig):
|
|||
def get_supported_openai_params(self, model: str) -> list:
|
||||
"""Get supported OpenAI params, excluding tool-related params for models
|
||||
that don't support function calling."""
|
||||
from litellm.utils import supports_function_calling
|
||||
from litellm.utils import supports_function_calling, supports_reasoning
|
||||
|
||||
supported_params = super().get_supported_openai_params(model=model)
|
||||
|
||||
|
|
@ -113,6 +113,10 @@ def create_config_class(provider: SimpleProviderConfig):
|
|||
f"function calling — removed tool-related params from supported params."
|
||||
)
|
||||
|
||||
_supports_reasoning = supports_reasoning(model=model, custom_llm_provider=provider.slug)
|
||||
if _supports_reasoning and "reasoning_effort" not in supported_params:
|
||||
supported_params.append("reasoning_effort")
|
||||
|
||||
return supported_params
|
||||
|
||||
def map_openai_params(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
from typing import Any, Optional
|
||||
|
||||
import litellm
|
||||
from litellm.llms.anthropic.experimental_pass_through.messages.transformation import (
|
||||
AnthropicMessagesConfig,
|
||||
)
|
||||
from litellm.llms.openai_like.json_loader import SimpleProviderConfig
|
||||
from litellm.secret_managers.main import get_secret_str
|
||||
|
||||
DEFAULT_ANTHROPIC_API_VERSION = "2023-06-01"
|
||||
|
||||
|
|
@ -67,3 +70,65 @@ class OpenAILikeAnthropicMessagesConfig(AnthropicMessagesConfig):
|
|||
if base.endswith("/v1"):
|
||||
base = base[: -len("/v1")]
|
||||
return f"{base}/v1/messages"
|
||||
|
||||
|
||||
class JSONProviderAnthropicMessagesConfig(OpenAILikeAnthropicMessagesConfig):
|
||||
"""
|
||||
Provider-level native Anthropic Messages passthrough for JSON-configured
|
||||
OpenAI-compatible providers whose ``supported_endpoints`` in providers.json
|
||||
includes ``"/v1/messages"``. Resolves the api key and api base from the
|
||||
provider's configured env vars, then forwards the Anthropic payload
|
||||
untranslated like ``OpenAILikeAnthropicMessagesConfig``.
|
||||
"""
|
||||
|
||||
def __init__(self, provider: SimpleProviderConfig):
|
||||
super().__init__()
|
||||
self._provider = provider
|
||||
|
||||
def should_strip_billing_metadata(self) -> bool:
|
||||
return True
|
||||
|
||||
def _resolve_api_key(self, api_key: Optional[str]) -> Optional[str]:
|
||||
return api_key or get_secret_str(self._provider.api_key_env) or litellm.api_key
|
||||
|
||||
def _resolve_api_base(self, api_base: Optional[str]) -> str:
|
||||
env_api_base = get_secret_str(self._provider.api_base_env) if self._provider.api_base_env else None
|
||||
return api_base or env_api_base or self._provider.base_url
|
||||
|
||||
def validate_anthropic_messages_environment(
|
||||
self,
|
||||
headers: dict[str, str],
|
||||
model: str,
|
||||
messages: list[Any],
|
||||
optional_params: dict,
|
||||
litellm_params: dict,
|
||||
api_key: Optional[str] = None,
|
||||
api_base: Optional[str] = None,
|
||||
) -> tuple[dict[str, str], Optional[str]]:
|
||||
return super().validate_anthropic_messages_environment(
|
||||
headers=headers,
|
||||
model=model,
|
||||
messages=messages,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
api_key=self._resolve_api_key(api_key),
|
||||
api_base=api_base,
|
||||
)
|
||||
|
||||
def get_complete_url(
|
||||
self,
|
||||
api_base: Optional[str],
|
||||
api_key: Optional[str],
|
||||
model: str,
|
||||
optional_params: dict,
|
||||
litellm_params: dict,
|
||||
stream: Optional[bool] = None,
|
||||
) -> str:
|
||||
return super().get_complete_url(
|
||||
api_base=self._resolve_api_base(api_base),
|
||||
api_key=api_key,
|
||||
model=model,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
stream=stream,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -168,6 +168,13 @@
|
|||
},
|
||||
"supported_endpoints": ["/v1/chat/completions", "/v1/responses"]
|
||||
},
|
||||
"meta": {
|
||||
"base_url": "https://api.meta.ai/v1",
|
||||
"api_key_env": "META_API_KEY",
|
||||
"api_base_env": "META_API_BASE",
|
||||
"base_class": "openai_gpt",
|
||||
"supported_endpoints": ["/v1/chat/completions", "/v1/responses", "/v1/messages"]
|
||||
},
|
||||
"pinstripes": {
|
||||
"base_url": "https://pinstripes.io/v1",
|
||||
"api_key_env": "PINSTRIPES_API_KEY",
|
||||
|
|
|
|||
|
|
@ -25501,6 +25501,42 @@
|
|||
"supports_function_calling": true,
|
||||
"supports_tool_choice": false
|
||||
},
|
||||
"meta/muse-spark-1.1": {
|
||||
"cache_read_input_token_cost": 1.5e-07,
|
||||
"input_cost_per_token": 1.25e-06,
|
||||
"litellm_provider": "meta",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 131072,
|
||||
"max_tokens": 131072,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4.25e-06,
|
||||
"source": "https://dev.meta.ai/docs/getting-started/pricing-rate-limits",
|
||||
"supported_endpoints": [
|
||||
"/v1/chat/completions",
|
||||
"/v1/responses",
|
||||
"/v1/messages"
|
||||
],
|
||||
"supported_modalities": [
|
||||
"text",
|
||||
"image",
|
||||
"video"
|
||||
],
|
||||
"supported_output_modalities": [
|
||||
"text"
|
||||
],
|
||||
"supports_function_calling": true,
|
||||
"supports_minimal_reasoning_effort": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_web_search": true,
|
||||
"supports_xhigh_reasoning_effort": true
|
||||
},
|
||||
"meta_llama/Llama-3.3-70B-Instruct": {
|
||||
"litellm_provider": "meta_llama",
|
||||
"max_input_tokens": 128000,
|
||||
|
|
|
|||
|
|
@ -3398,6 +3398,7 @@ class LlmProviders(str, Enum):
|
|||
LIBERTAI = "libertai"
|
||||
PINSTRIPES = "pinstripes"
|
||||
DARKBLOOM = "darkbloom"
|
||||
META = "meta"
|
||||
LITELLM_AGENT = "litellm_agent"
|
||||
CURSOR = "cursor"
|
||||
BEDROCK_MANTLE = "bedrock_mantle"
|
||||
|
|
|
|||
|
|
@ -8028,6 +8028,16 @@ class ProviderConfigManager:
|
|||
)
|
||||
|
||||
return GithubCopilotAnthropicMessagesConfig()
|
||||
|
||||
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
|
||||
|
||||
json_provider = JSONProviderRegistry.get(provider.value)
|
||||
if json_provider is not None and "/v1/messages" in json_provider.supported_endpoints:
|
||||
from litellm.llms.openai_like.messages.transformation import (
|
||||
JSONProviderAnthropicMessagesConfig,
|
||||
)
|
||||
|
||||
return JSONProviderAnthropicMessagesConfig(json_provider)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
|
|
@ -25659,6 +25659,42 @@
|
|||
"supports_function_calling": true,
|
||||
"supports_tool_choice": false
|
||||
},
|
||||
"meta/muse-spark-1.1": {
|
||||
"cache_read_input_token_cost": 1.5e-07,
|
||||
"input_cost_per_token": 1.25e-06,
|
||||
"litellm_provider": "meta",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 131072,
|
||||
"max_tokens": 131072,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4.25e-06,
|
||||
"source": "https://dev.meta.ai/docs/getting-started/pricing-rate-limits",
|
||||
"supported_endpoints": [
|
||||
"/v1/chat/completions",
|
||||
"/v1/responses",
|
||||
"/v1/messages"
|
||||
],
|
||||
"supported_modalities": [
|
||||
"text",
|
||||
"image",
|
||||
"video"
|
||||
],
|
||||
"supported_output_modalities": [
|
||||
"text"
|
||||
],
|
||||
"supports_function_calling": true,
|
||||
"supports_minimal_reasoning_effort": true,
|
||||
"supports_parallel_function_calling": true,
|
||||
"supports_pdf_input": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": true,
|
||||
"supports_vision": true,
|
||||
"supports_web_search": true,
|
||||
"supports_xhigh_reasoning_effort": true
|
||||
},
|
||||
"meta_llama/Llama-3.3-70B-Instruct": {
|
||||
"litellm_provider": "meta_llama",
|
||||
"max_input_tokens": 128000,
|
||||
|
|
|
|||
|
|
@ -1984,6 +1984,23 @@
|
|||
"interactions": true
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"display_name": "Meta Model API (`meta`)",
|
||||
"url": "https://docs.litellm.ai/docs/providers/meta",
|
||||
"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
|
||||
}
|
||||
},
|
||||
"pinstripes": {
|
||||
"display_name": "Pinstripes (`pinstripes`)",
|
||||
"url": "https://docs.litellm.ai/docs/providers/pinstripes",
|
||||
|
|
|
|||
224
tests/test_litellm/llms/openai_like/test_meta_provider.py
Normal file
224
tests/test_litellm/llms/openai_like/test_meta_provider.py
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
"""
|
||||
Tests for the Meta Model API (Muse Spark) provider configuration and integration.
|
||||
"""
|
||||
|
||||
import litellm
|
||||
|
||||
|
||||
class TestMetaProviderConfig:
|
||||
def test_meta_in_provider_list(self):
|
||||
from litellm import LlmProviders
|
||||
|
||||
assert hasattr(LlmProviders, "META")
|
||||
assert LlmProviders.META.value == "meta"
|
||||
assert "meta" in litellm.provider_list
|
||||
|
||||
def test_meta_json_config_exists(self):
|
||||
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
|
||||
|
||||
assert JSONProviderRegistry.exists("meta")
|
||||
|
||||
meta = JSONProviderRegistry.get("meta")
|
||||
assert meta is not None
|
||||
assert meta.base_url == "https://api.meta.ai/v1"
|
||||
assert meta.api_key_env == "META_API_KEY"
|
||||
assert meta.api_base_env == "META_API_BASE"
|
||||
|
||||
def test_meta_supports_responses_api(self):
|
||||
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
|
||||
|
||||
assert JSONProviderRegistry.supports_responses_api("meta")
|
||||
|
||||
def test_meta_in_openai_compatible_providers(self):
|
||||
from litellm.constants import openai_compatible_providers
|
||||
|
||||
assert "meta" in openai_compatible_providers
|
||||
|
||||
def test_meta_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="meta/muse-spark-1.1",
|
||||
custom_llm_provider=None,
|
||||
api_base=None,
|
||||
api_key="sk-test",
|
||||
)
|
||||
|
||||
assert model == "muse-spark-1.1"
|
||||
assert provider == "meta"
|
||||
assert api_base == "https://api.meta.ai/v1"
|
||||
|
||||
def test_meta_api_base_override(self):
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
|
||||
|
||||
model, provider, api_key, api_base = get_llm_provider(
|
||||
model="meta/muse-spark-1.1",
|
||||
custom_llm_provider=None,
|
||||
api_base="https://custom.meta.ai/v1",
|
||||
api_key="sk-test",
|
||||
)
|
||||
|
||||
assert provider == "meta"
|
||||
assert api_base == "https://custom.meta.ai/v1"
|
||||
assert api_key == "sk-test"
|
||||
|
||||
def test_meta_url_autodetection(self):
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
|
||||
|
||||
model, provider, api_key, api_base = get_llm_provider(
|
||||
model="muse-spark-1.1",
|
||||
custom_llm_provider=None,
|
||||
api_base="https://api.meta.ai/v1",
|
||||
api_key=None,
|
||||
)
|
||||
assert provider == "meta"
|
||||
assert api_base == "https://api.meta.ai/v1"
|
||||
|
||||
def test_meta_router_config(self):
|
||||
from litellm import Router
|
||||
|
||||
router = Router(
|
||||
model_list=[
|
||||
{
|
||||
"model_name": "muse-spark",
|
||||
"litellm_params": {
|
||||
"model": "meta/muse-spark-1.1",
|
||||
"api_key": "test-key",
|
||||
},
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
assert len(router.model_list) == 1
|
||||
assert router.model_list[0]["model_name"] == "muse-spark"
|
||||
|
||||
|
||||
class TestMetaReasoningParams:
|
||||
def test_muse_spark_supports_reasoning_effort(self):
|
||||
params = litellm.get_supported_openai_params(
|
||||
model="muse-spark-1.1", custom_llm_provider="meta"
|
||||
)
|
||||
assert params is not None
|
||||
assert "reasoning_effort" in params
|
||||
|
||||
def test_reasoning_effort_mapped_through(self):
|
||||
cfg = litellm.ProviderConfigManager.get_provider_chat_config(
|
||||
model="muse-spark-1.1", provider=litellm.LlmProviders.META
|
||||
)
|
||||
assert cfg is not None
|
||||
mapped = cfg.map_openai_params(
|
||||
non_default_params={"reasoning_effort": "xhigh"},
|
||||
optional_params={},
|
||||
model="muse-spark-1.1",
|
||||
drop_params=False,
|
||||
)
|
||||
assert mapped["reasoning_effort"] == "xhigh"
|
||||
|
||||
def test_reasoning_effort_gated_on_capability(self):
|
||||
"""A meta model without reasoning metadata must not advertise reasoning_effort."""
|
||||
params = litellm.get_supported_openai_params(
|
||||
model="some-non-reasoning-model", custom_llm_provider="meta"
|
||||
)
|
||||
assert params is not None
|
||||
assert "reasoning_effort" not in params
|
||||
|
||||
|
||||
class TestMetaAnthropicMessages:
|
||||
def test_meta_resolves_native_messages_config(self):
|
||||
from litellm.llms.openai_like.messages.transformation import (
|
||||
JSONProviderAnthropicMessagesConfig,
|
||||
)
|
||||
|
||||
cfg = litellm.ProviderConfigManager.get_provider_anthropic_messages_config(
|
||||
model="muse-spark-1.1", provider=litellm.LlmProviders.META
|
||||
)
|
||||
assert isinstance(cfg, JSONProviderAnthropicMessagesConfig)
|
||||
|
||||
def test_json_provider_without_messages_endpoint_resolves_none(self):
|
||||
cfg = litellm.ProviderConfigManager.get_provider_anthropic_messages_config(
|
||||
model="some-model", provider=litellm.LlmProviders.PINSTRIPES
|
||||
)
|
||||
assert cfg is None
|
||||
|
||||
def test_complete_url_defaults_to_meta_base(self):
|
||||
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
|
||||
from litellm.llms.openai_like.messages.transformation import (
|
||||
JSONProviderAnthropicMessagesConfig,
|
||||
)
|
||||
|
||||
provider = JSONProviderRegistry.get("meta")
|
||||
assert provider is not None
|
||||
cfg = JSONProviderAnthropicMessagesConfig(provider)
|
||||
|
||||
url = cfg.get_complete_url(
|
||||
api_base=None,
|
||||
api_key="sk-test",
|
||||
model="muse-spark-1.1",
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
)
|
||||
assert url == "https://api.meta.ai/v1/messages"
|
||||
|
||||
override_url = cfg.get_complete_url(
|
||||
api_base="https://custom.meta.ai/v1",
|
||||
api_key="sk-test",
|
||||
model="muse-spark-1.1",
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
)
|
||||
assert override_url == "https://custom.meta.ai/v1/messages"
|
||||
|
||||
def test_api_key_resolved_from_env(self, monkeypatch):
|
||||
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
|
||||
from litellm.llms.openai_like.messages.transformation import (
|
||||
JSONProviderAnthropicMessagesConfig,
|
||||
)
|
||||
|
||||
monkeypatch.setenv("META_API_KEY", "sk-env-key")
|
||||
provider = JSONProviderRegistry.get("meta")
|
||||
assert provider is not None
|
||||
cfg = JSONProviderAnthropicMessagesConfig(provider)
|
||||
|
||||
headers, _ = cfg.validate_anthropic_messages_environment(
|
||||
headers={},
|
||||
model="muse-spark-1.1",
|
||||
messages=[{"role": "user", "content": "hi"}],
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
api_key=None,
|
||||
api_base=None,
|
||||
)
|
||||
assert headers["authorization"] == "Bearer sk-env-key"
|
||||
assert headers["anthropic-version"] == "2023-06-01"
|
||||
|
||||
|
||||
class TestMuseSparkModelInfo:
|
||||
def test_muse_spark_pricing_and_capabilities(self):
|
||||
info = litellm.get_model_info("meta/muse-spark-1.1")
|
||||
|
||||
assert info["litellm_provider"] == "meta"
|
||||
assert info["input_cost_per_token"] == 1.25e-06
|
||||
assert info["output_cost_per_token"] == 4.25e-06
|
||||
assert info["cache_read_input_token_cost"] == 1.5e-07
|
||||
assert info["max_input_tokens"] == 1048576
|
||||
assert info["supports_reasoning"] is True
|
||||
assert info["supports_web_search"] is True
|
||||
assert info["supports_vision"] is True
|
||||
assert info["supports_function_calling"] is True
|
||||
assert info["supports_prompt_caching"] is True
|
||||
|
||||
def test_muse_spark_cost_calculation(self):
|
||||
from litellm import completion_cost
|
||||
from litellm.types.utils import ModelResponse, Usage
|
||||
|
||||
response = ModelResponse(
|
||||
model="muse-spark-1.1",
|
||||
usage=Usage(prompt_tokens=1000, completion_tokens=500, total_tokens=1500),
|
||||
)
|
||||
cost = completion_cost(
|
||||
completion_response=response,
|
||||
model="meta/muse-spark-1.1",
|
||||
custom_llm_provider="meta",
|
||||
)
|
||||
expected = 1000 * 1.25e-06 + 500 * 4.25e-06
|
||||
assert abs(cost - expected) < 1e-12
|
||||
63
tests/test_litellm/test_muse_spark_1_1_model_metadata.py
Normal file
63
tests/test_litellm/test_muse_spark_1_1_model_metadata.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
|
||||
|
||||
MUSE_SPARK_MODEL = "meta/muse-spark-1.1"
|
||||
|
||||
|
||||
def test_muse_spark_1_1_model_info():
|
||||
json_path = Path(__file__).parents[2] / "model_prices_and_context_window.json"
|
||||
with open(json_path) as f:
|
||||
model_cost = json.load(f)
|
||||
|
||||
info = model_cost.get(MUSE_SPARK_MODEL)
|
||||
assert info is not None, f"{MUSE_SPARK_MODEL} not found in model_prices_and_context_window.json"
|
||||
|
||||
assert info["litellm_provider"] == "meta"
|
||||
assert info["mode"] == "chat"
|
||||
|
||||
assert info["input_cost_per_token"] == 1.25e-06
|
||||
assert info["output_cost_per_token"] == 4.25e-06
|
||||
assert info["cache_read_input_token_cost"] == 1.5e-07
|
||||
|
||||
assert info["max_input_tokens"] == 1048576
|
||||
assert info["max_output_tokens"] == 131072
|
||||
assert info["max_tokens"] == 131072
|
||||
|
||||
assert info["supports_function_calling"] is True
|
||||
assert info["supports_parallel_function_calling"] is True
|
||||
assert info["supports_prompt_caching"] is True
|
||||
assert info["supports_reasoning"] is True
|
||||
assert info["supports_response_schema"] is True
|
||||
assert info["supports_tool_choice"] is True
|
||||
assert info["supports_vision"] is True
|
||||
assert info["supports_pdf_input"] is True
|
||||
assert info["supports_web_search"] is True
|
||||
assert info["supports_minimal_reasoning_effort"] is True
|
||||
assert info["supports_xhigh_reasoning_effort"] is True
|
||||
|
||||
assert info["supported_endpoints"] == ["/v1/chat/completions", "/v1/responses", "/v1/messages"]
|
||||
assert info["supported_modalities"] == ["text", "image", "video"]
|
||||
assert info["supported_output_modalities"] == ["text"]
|
||||
|
||||
routed_model, provider, _, api_base = get_llm_provider(model=MUSE_SPARK_MODEL, api_key="sk-test")
|
||||
assert routed_model == "muse-spark-1.1"
|
||||
assert provider == "meta"
|
||||
assert api_base == "https://api.meta.ai/v1"
|
||||
|
||||
|
||||
def test_muse_spark_1_1_backup_matches_main():
|
||||
"""Ensure the bundled model cost map stays in sync with the canonical file."""
|
||||
repo_root = Path(__file__).parents[2]
|
||||
main_path = repo_root / "model_prices_and_context_window.json"
|
||||
backup_path = repo_root / "litellm" / "model_prices_and_context_window_backup.json"
|
||||
|
||||
with open(main_path) as f:
|
||||
main_cost = json.load(f)
|
||||
with open(backup_path) as f:
|
||||
backup_cost = json.load(f)
|
||||
|
||||
assert backup_cost.get(MUSE_SPARK_MODEL) == main_cost.get(MUSE_SPARK_MODEL), (
|
||||
f"{MUSE_SPARK_MODEL} differs between main and backup model cost maps"
|
||||
)
|
||||
Loading…
Add table
Reference in a new issue