mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-28 01:32:17 +00:00
feat: update Morph model support
This commit is contained in:
parent
3dac3f7a36
commit
677b716c08
4 changed files with 278 additions and 19 deletions
|
|
@ -25,14 +25,31 @@ class MorphChatConfig(OpenAILikeChatConfig):
|
|||
self, api_base: str | None, api_key: str | None
|
||||
) -> tuple[str | None, str | None]:
|
||||
api_base = (
|
||||
api_base or get_secret_str("MORPH_API_BASE") or "https://api.morphllm.com/v1" # default api base
|
||||
api_base
|
||||
or get_secret_str("MORPH_API_BASE")
|
||||
or "https://api.morphllm.com/v1" # default api base
|
||||
)
|
||||
dynamic_api_key: Final = api_key or get_secret_str("MORPH_API_KEY")
|
||||
return api_base, dynamic_api_key
|
||||
|
||||
def get_supported_openai_params(self, model: str) -> list:
|
||||
return [
|
||||
"extra_headers",
|
||||
"frequency_penalty",
|
||||
"logit_bias",
|
||||
"max_completion_tokens",
|
||||
"max_retries",
|
||||
"max_tokens",
|
||||
"messages",
|
||||
"model",
|
||||
"presence_penalty",
|
||||
"response_format",
|
||||
"seed",
|
||||
"stop",
|
||||
"stream",
|
||||
"stream_options",
|
||||
"temperature",
|
||||
"tool_choice",
|
||||
"tools",
|
||||
"top_p",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -34650,11 +34650,12 @@
|
|||
"morph/morph-v3-fast": {
|
||||
"input_cost_per_token": 8e-07,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 16000,
|
||||
"max_output_tokens": 16000,
|
||||
"max_tokens": 16000,
|
||||
"max_input_tokens": 262144,
|
||||
"max_output_tokens": 131072,
|
||||
"max_tokens": 262144,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.2e-06,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": false,
|
||||
"supports_parallel_function_calling": false,
|
||||
"supports_system_messages": true,
|
||||
|
|
@ -34664,17 +34665,104 @@
|
|||
"morph/morph-v3-large": {
|
||||
"input_cost_per_token": 9e-07,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 16000,
|
||||
"max_output_tokens": 16000,
|
||||
"max_tokens": 16000,
|
||||
"max_input_tokens": 262144,
|
||||
"max_output_tokens": 131072,
|
||||
"max_tokens": 262144,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.9e-06,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": false,
|
||||
"supports_parallel_function_calling": false,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": false,
|
||||
"supports_vision": false
|
||||
},
|
||||
"morph/morph-dsv4flash": {
|
||||
"cache_read_input_token_cost": 2.5e-08,
|
||||
"input_cost_per_token": 9.875e-08,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 2.78e-07,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": false
|
||||
},
|
||||
"morph/morph-glm53-744b": {
|
||||
"cache_read_input_token_cost": 2.6e-07,
|
||||
"input_cost_per_token": 1.25e-06,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4.4e-06,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": false
|
||||
},
|
||||
"morph/morph-glm53flash": {
|
||||
"cache_read_input_token_cost": 1e-08,
|
||||
"input_cost_per_token": 1.5e-07,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4.2e-07,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_video_input": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"morph/morph-kimik3": {
|
||||
"cache_read_input_token_cost": 2.9e-07,
|
||||
"input_cost_per_token": 2.8e-06,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.4e-05,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"morph/morph-kimik3-fast": {
|
||||
"cache_read_input_token_cost": 6e-07,
|
||||
"input_cost_per_token": 6e-06,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 2.25e-05,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"multimodalembedding": {
|
||||
"input_cost_per_character": 2e-07,
|
||||
"input_cost_per_image": 0.0001,
|
||||
|
|
|
|||
|
|
@ -34650,11 +34650,12 @@
|
|||
"morph/morph-v3-fast": {
|
||||
"input_cost_per_token": 8e-07,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 16000,
|
||||
"max_output_tokens": 16000,
|
||||
"max_tokens": 16000,
|
||||
"max_input_tokens": 262144,
|
||||
"max_output_tokens": 131072,
|
||||
"max_tokens": 262144,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.2e-06,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": false,
|
||||
"supports_parallel_function_calling": false,
|
||||
"supports_system_messages": true,
|
||||
|
|
@ -34664,17 +34665,104 @@
|
|||
"morph/morph-v3-large": {
|
||||
"input_cost_per_token": 9e-07,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 16000,
|
||||
"max_output_tokens": 16000,
|
||||
"max_tokens": 16000,
|
||||
"max_input_tokens": 262144,
|
||||
"max_output_tokens": 131072,
|
||||
"max_tokens": 262144,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.9e-06,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": false,
|
||||
"supports_parallel_function_calling": false,
|
||||
"supports_system_messages": true,
|
||||
"supports_tool_choice": false,
|
||||
"supports_vision": false
|
||||
},
|
||||
"morph/morph-dsv4flash": {
|
||||
"cache_read_input_token_cost": 2.5e-08,
|
||||
"input_cost_per_token": 9.875e-08,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 2.78e-07,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": false
|
||||
},
|
||||
"morph/morph-glm53-744b": {
|
||||
"cache_read_input_token_cost": 2.6e-07,
|
||||
"input_cost_per_token": 1.25e-06,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4.4e-06,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": false
|
||||
},
|
||||
"morph/morph-glm53flash": {
|
||||
"cache_read_input_token_cost": 1e-08,
|
||||
"input_cost_per_token": 1.5e-07,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 4.2e-07,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_video_input": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"morph/morph-kimik3": {
|
||||
"cache_read_input_token_cost": 2.9e-07,
|
||||
"input_cost_per_token": 2.8e-06,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 1.4e-05,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"morph/morph-kimik3-fast": {
|
||||
"cache_read_input_token_cost": 6e-07,
|
||||
"input_cost_per_token": 6e-06,
|
||||
"litellm_provider": "morph",
|
||||
"max_input_tokens": 1048576,
|
||||
"max_output_tokens": 1048576,
|
||||
"max_tokens": 1048576,
|
||||
"mode": "chat",
|
||||
"output_cost_per_token": 2.25e-05,
|
||||
"source": "https://www.morphllm.com/api/models/json",
|
||||
"supports_function_calling": true,
|
||||
"supports_prompt_caching": true,
|
||||
"supports_reasoning": true,
|
||||
"supports_response_schema": true,
|
||||
"supports_system_messages": true,
|
||||
"supports_vision": true
|
||||
},
|
||||
"multimodalembedding": {
|
||||
"input_cost_per_character": 2e-07,
|
||||
"input_cost_per_image": 0.0001,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
import os
|
||||
from unittest.mock import patch
|
||||
|
||||
|
||||
import litellm
|
||||
from litellm import MorphChatConfig, get_llm_provider
|
||||
|
||||
|
|
@ -43,13 +42,16 @@ def test_morph_get_llm_provider():
|
|||
_, custom_llm_provider, _, _ = get_llm_provider("morph/morph-v3-fast")
|
||||
assert custom_llm_provider == "morph"
|
||||
|
||||
_, custom_llm_provider, _, _ = get_llm_provider("morph/morph-kimik3")
|
||||
assert custom_llm_provider == "morph"
|
||||
|
||||
|
||||
def test_morph_in_provider_lists():
|
||||
"""Test that morph is included in all necessary provider lists."""
|
||||
import litellm
|
||||
from litellm.constants import (
|
||||
openai_compatible_providers,
|
||||
openai_compatible_endpoints,
|
||||
openai_compatible_providers,
|
||||
)
|
||||
|
||||
# Check morph is in openai_compatible_providers
|
||||
|
|
@ -64,7 +66,15 @@ def test_morph_in_provider_lists():
|
|||
# Check models are in model_list after initialization
|
||||
assert all(
|
||||
model in litellm.model_list
|
||||
for model in ["morph/morph-v3-large", "morph/morph-v3-fast"]
|
||||
for model in [
|
||||
"morph/morph-dsv4flash",
|
||||
"morph/morph-glm53-744b",
|
||||
"morph/morph-glm53flash",
|
||||
"morph/morph-kimik3",
|
||||
"morph/morph-kimik3-fast",
|
||||
"morph/morph-v3-large",
|
||||
"morph/morph-v3-fast",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -76,9 +86,9 @@ def test_morph_model_info():
|
|||
|
||||
assert model_info["litellm_provider"] == "morph"
|
||||
assert model_info["mode"] == "chat"
|
||||
assert model_info["max_tokens"] == 16000
|
||||
assert model_info["max_input_tokens"] == 16000
|
||||
assert model_info["max_output_tokens"] == 16000
|
||||
assert model_info["max_tokens"] == 262144
|
||||
assert model_info["max_input_tokens"] == 262144
|
||||
assert model_info["max_output_tokens"] == 131072
|
||||
assert model_info["input_cost_per_token"] == 9e-07 # $0.9/1M tokens
|
||||
assert model_info["output_cost_per_token"] == 1.9e-06 # $1.9/1M tokens
|
||||
assert model_info["supports_function_calling"] is False
|
||||
|
|
@ -86,20 +96,76 @@ def test_morph_model_info():
|
|||
assert model_info["supports_system_messages"] is True
|
||||
|
||||
|
||||
def test_morph_open_model_info():
|
||||
model_info = litellm.get_model_info("morph/morph-glm53flash")
|
||||
|
||||
assert model_info["litellm_provider"] == "morph"
|
||||
assert model_info["mode"] == "chat"
|
||||
assert model_info["max_input_tokens"] == 1048576
|
||||
assert model_info["input_cost_per_token"] == 1.5e-07
|
||||
assert model_info["cache_read_input_token_cost"] == 1e-08
|
||||
assert model_info["output_cost_per_token"] == 4.2e-07
|
||||
assert model_info["supports_function_calling"] is True
|
||||
assert model_info["supports_prompt_caching"] is True
|
||||
assert model_info["supports_response_schema"] is True
|
||||
assert model_info["supports_vision"] is True
|
||||
|
||||
|
||||
def test_morph_supported_params():
|
||||
"""Test that MorphChatConfig returns correct supported parameters."""
|
||||
config = MorphChatConfig()
|
||||
supported_params = config.get_supported_openai_params("morph/morph-v3-large")
|
||||
|
||||
expected_params = [
|
||||
"frequency_penalty",
|
||||
"max_tokens",
|
||||
"messages",
|
||||
"model",
|
||||
"presence_penalty",
|
||||
"response_format",
|
||||
"seed",
|
||||
"stop",
|
||||
"stream",
|
||||
"temperature",
|
||||
"tool_choice",
|
||||
"tools",
|
||||
"top_p",
|
||||
]
|
||||
|
||||
assert all(param in supported_params for param in expected_params)
|
||||
|
||||
|
||||
def test_morph_maps_tool_and_response_format_params():
|
||||
config = MorphChatConfig()
|
||||
tools = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "get_weather",
|
||||
"parameters": {"type": "object", "properties": {}},
|
||||
},
|
||||
}
|
||||
]
|
||||
response_format = {"type": "json_object"}
|
||||
|
||||
mapped = config.map_openai_params(
|
||||
non_default_params={
|
||||
"max_completion_tokens": 64,
|
||||
"response_format": response_format,
|
||||
"tool_choice": "required",
|
||||
"tools": tools,
|
||||
},
|
||||
optional_params={},
|
||||
model="morph/morph-glm53flash",
|
||||
drop_params=False,
|
||||
)
|
||||
|
||||
assert mapped["max_tokens"] == 64
|
||||
assert mapped["response_format"] == response_format
|
||||
assert mapped["tool_choice"] == "required"
|
||||
assert mapped["tools"] == tools
|
||||
|
||||
|
||||
def test_morph_custom_llm_provider():
|
||||
"""Test that morph models are correctly identified."""
|
||||
config = MorphChatConfig()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue