test: cover app.nz provider params

This commit is contained in:
Lee Penkman 2026-07-01 19:15:24 +12:00
parent aca10df765
commit 09b91accbc
3 changed files with 46 additions and 39 deletions

View file

@ -94,9 +94,7 @@ def create_config_class(provider: SimpleProviderConfig):
from litellm.utils import supports_function_calling
supported_params = super().get_supported_openai_params(model=model)
supported_params = list(
dict.fromkeys([*supported_params, *provider.extra_supported_params])
)
supported_params = list(dict.fromkeys([*supported_params, *provider.extra_supported_params]))
_supports_fc = supports_function_calling(model=model, custom_llm_provider=provider.slug)

View file

@ -177,6 +177,24 @@
"interactions": true
}
},
"app_nz": {
"display_name": "app.nz (`app_nz`)",
"url": "https://docs.litellm.ai/docs/providers/app_nz",
"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": true,
"interactions": true
}
},
"apertis": {
"display_name": "Apertis (`apertis`)",
"endpoints": {

View file

@ -52,9 +52,7 @@ class TestJSONProviderLoader:
assert api_base == "https://api.publicai.co/v1"
# Test with custom base
api_base, api_key = config._get_openai_compatible_provider_info(
"https://custom.api.com", "test-key"
)
api_base, api_key = config._get_openai_compatible_provider_info("https://custom.api.com", "test-key")
assert api_base == "https://custom.api.com"
assert api_key == "test-key"
@ -70,9 +68,7 @@ class TestJSONProviderLoader:
# Test parameter mapping
optional_params = {}
non_default_params = {"max_completion_tokens": 100, "temperature": 0.7}
result = config.map_openai_params(
non_default_params, optional_params, "gpt-4", False
)
result = config.map_openai_params(non_default_params, optional_params, "gpt-4", False)
# max_completion_tokens should be mapped to max_tokens
assert "max_tokens" in result
@ -98,6 +94,19 @@ class TestJSONProviderLoader:
assert isinstance(supported, list)
assert len(supported) > 0
def test_extra_supported_params(self):
"""Test JSON providers can extend supported OpenAI params"""
from litellm.llms.openai_like.dynamic_config import create_config_class
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
provider = JSONProviderRegistry.get("app_nz")
config_class = create_config_class(provider)
config = config_class()
supported = config.get_supported_openai_params("app/auto")
assert "reasoning_effort" in supported
def test_tool_params_excluded_when_function_calling_not_supported(self):
"""Test that tool-related params are excluded for models that don't support
function calling. Regression test for https://github.com/BerriAI/litellm/issues/21125
@ -121,9 +130,9 @@ class TestJSONProviderLoader:
"parallel_tool_calls",
]
for param in tool_params:
assert (
param not in supported
), f"'{param}' should not be in supported params when function calling is not supported"
assert param not in supported, (
f"'{param}' should not be in supported params when function calling is not supported"
)
# Non-tool params should still be present
assert "temperature" in supported
@ -168,9 +177,7 @@ class TestJSONProviderLoader:
from litellm import LlmProviders
from litellm.utils import ProviderConfigManager
config = ProviderConfigManager.get_provider_chat_config(
model="gpt-4", provider=LlmProviders.PUBLICAI
)
config = ProviderConfigManager.get_provider_chat_config(model="gpt-4", provider=LlmProviders.PUBLICAI)
assert config is not None
assert config.custom_llm_provider == "publicai"
@ -218,9 +225,7 @@ class TestPinstripes:
api_base, api_key = config._get_openai_compatible_provider_info(None, None)
assert api_base == "https://pinstripes.io/v1"
api_base, api_key = config._get_openai_compatible_provider_info(
"https://custom.pinstripes.io/v1", "test-key"
)
api_base, api_key = config._get_openai_compatible_provider_info("https://custom.pinstripes.io/v1", "test-key")
assert api_base == "https://custom.pinstripes.io/v1"
assert api_key == "test-key"
@ -235,9 +240,7 @@ class TestPinstripes:
optional_params = {}
non_default_params = {"max_completion_tokens": 100, "temperature": 0.7}
result = config.map_openai_params(
non_default_params, optional_params, "ps/glm-4.5-air", False
)
result = config.map_openai_params(non_default_params, optional_params, "ps/glm-4.5-air", False)
assert "max_tokens" in result
assert result["max_tokens"] == 100
@ -282,9 +285,7 @@ class TestDarkbloom:
api_base, api_key = config._get_openai_compatible_provider_info(None, None)
assert api_base == "https://api.darkbloom.dev/v1"
api_base, api_key = config._get_openai_compatible_provider_info(
"https://custom.darkbloom.dev/v1", "test-key"
)
api_base, api_key = config._get_openai_compatible_provider_info("https://custom.darkbloom.dev/v1", "test-key")
assert api_base == "https://custom.darkbloom.dev/v1"
assert api_key == "test-key"
@ -311,17 +312,13 @@ class TestDarkbloom:
from litellm import LlmProviders
from litellm.utils import ProviderConfigManager
config = ProviderConfigManager.get_provider_chat_config(
model="gemma-4-26b", provider=LlmProviders.DARKBLOOM
)
config = ProviderConfigManager.get_provider_chat_config(model="gemma-4-26b", provider=LlmProviders.DARKBLOOM)
assert config is not None
assert config.custom_llm_provider == "darkbloom"
def test_darkbloom_model_cost_map(self):
with open(
os.path.join(workspace_path, "model_prices_and_context_window.json")
) as f:
with open(os.path.join(workspace_path, "model_prices_and_context_window.json")) as f:
model_cost = json.load(f)
expected_models = {
@ -373,9 +370,7 @@ class TestPublicAIIntegration:
content = response.choices[0].message.content.lower()
assert len(content) > 0
print(
f"✓ PublicAI completion successful: {response.choices[0].message.content}"
)
print(f"✓ PublicAI completion successful: {response.choices[0].message.content}")
except Exception as e:
if pytest:
@ -403,9 +398,7 @@ class TestPublicAIIntegration:
chunks = []
for chunk in response:
assert chunk is not None
if hasattr(chunk.choices[0], "delta") and hasattr(
chunk.choices[0].delta, "content"
):
if hasattr(chunk.choices[0], "delta") and hasattr(chunk.choices[0].delta, "content"):
if chunk.choices[0].delta.content:
chunks.append(chunk.choices[0].delta.content)
@ -461,9 +454,7 @@ class TestPublicAIIntegration:
# Send message with content as list (should be converted to string)
response = litellm.completion(
model="publicai/swiss-ai/apertus-8b-instruct",
messages=[
{"role": "user", "content": [{"type": "text", "text": "Say hello"}]}
],
messages=[{"role": "user", "content": [{"type": "text", "text": "Say hello"}]}],
max_tokens=10,
)