mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
fix(apodex): harden provider routing metadata
This commit is contained in:
parent
64dcb95268
commit
190a3e01ec
5 changed files with 98 additions and 6 deletions
|
|
@ -15,6 +15,7 @@ from collections.abc import Mapping
|
|||
from typing import Final
|
||||
|
||||
from litellm.llms.openai.chat.gpt_transformation import OpenAIGPTConfig
|
||||
from litellm.types.llms.openai import AllMessageValues
|
||||
|
||||
from ..common_utils import (
|
||||
APODEX_API_BASE_URL,
|
||||
|
|
@ -46,6 +47,8 @@ _CORE_PARAMS: Final = (
|
|||
"parallel_tool_calls",
|
||||
)
|
||||
|
||||
_PIN_NON_STREAMING: Final = "_apodex_pin_non_streaming"
|
||||
|
||||
|
||||
class ApodexChatConfig(OpenAIGPTConfig):
|
||||
"""
|
||||
|
|
@ -116,5 +119,35 @@ class ApodexChatConfig(OpenAIGPTConfig):
|
|||
)
|
||||
return { # mutable-ok: JSON request body
|
||||
**renamed,
|
||||
"extra_body": {"stream": False, **extra_body}, # mutable-ok: JSON request body
|
||||
_PIN_NON_STREAMING: True,
|
||||
"extra_body": {**extra_body, "stream": False}, # mutable-ok: JSON request body
|
||||
}
|
||||
|
||||
def transform_request(
|
||||
self,
|
||||
model: str,
|
||||
messages: list[AllMessageValues],
|
||||
optional_params: dict, # mutable-ok: matches the base-class signature
|
||||
litellm_params: dict, # mutable-ok: matches the base-class signature
|
||||
headers: dict, # mutable-ok: matches the base-class signature
|
||||
) -> dict: # mutable-ok: JSON request body
|
||||
"""Apply the non-streaming pin after LiteLLM merges caller ``extra_body``."""
|
||||
pin_non_streaming: Final = bool(optional_params.pop(_PIN_NON_STREAMING, False))
|
||||
transformed: Final = super().transform_request(
|
||||
model=model,
|
||||
messages=messages,
|
||||
optional_params=optional_params,
|
||||
litellm_params=litellm_params,
|
||||
headers=headers,
|
||||
)
|
||||
if not pin_non_streaming:
|
||||
return transformed
|
||||
|
||||
requested_extra_body: Final = transformed.get("extra_body")
|
||||
extra_body: Final = (
|
||||
requested_extra_body if isinstance(requested_extra_body, Mapping) else {} # mutable-ok: JSON request body
|
||||
)
|
||||
return { # mutable-ok: JSON request body
|
||||
**transformed,
|
||||
"extra_body": {**extra_body, "stream": False}, # mutable-ok: JSON request body
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,6 +177,23 @@
|
|||
"interactions": true
|
||||
}
|
||||
},
|
||||
"apodex": {
|
||||
"display_name": "Apodex (`apodex`)",
|
||||
"url": "https://docs.litellm.ai/docs/providers/apodex",
|
||||
"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
|
||||
}
|
||||
},
|
||||
"apertis": {
|
||||
"display_name": "Apertis (`apertis`)",
|
||||
"endpoints": {
|
||||
|
|
|
|||
|
|
@ -156,6 +156,17 @@ class TestStreamDefault:
|
|||
assert captured["body"]["stream"] is False
|
||||
assert captured["body"]["mcp_servers"] == mcp_servers
|
||||
|
||||
def test_extra_body_cannot_override_non_streaming_pin(self):
|
||||
captured: dict = {}
|
||||
litellm.completion(
|
||||
model=DEEP_RESEARCH_MODEL,
|
||||
messages=[{"role": "user", "content": "hi"}],
|
||||
extra_body={"stream": True},
|
||||
client=_client(captured),
|
||||
)
|
||||
|
||||
assert captured["body"]["stream"] is False
|
||||
|
||||
|
||||
class TestSupportedParams:
|
||||
def test_core_models_support_tools(self):
|
||||
|
|
|
|||
|
|
@ -82,6 +82,12 @@ class TestRegistration:
|
|||
assert litellm.ApodexChatConfig().custom_llm_provider == "apodex"
|
||||
assert litellm.ApodexResponsesConfig().custom_llm_provider == LlmProviders.APODEX
|
||||
|
||||
def test_packaged_endpoint_matrix_matches_the_source(self):
|
||||
source = json.loads((REPO_ROOT / "provider_endpoints_support.json").read_text())
|
||||
backup = json.loads((REPO_ROOT / "litellm" / "provider_endpoints_support_backup.json").read_text())
|
||||
|
||||
assert backup["providers"]["apodex"] == source["providers"]["apodex"]
|
||||
|
||||
|
||||
class TestModelMetadata:
|
||||
@pytest.fixture(scope="class")
|
||||
|
|
|
|||
|
|
@ -62,12 +62,37 @@ class TestNativePassthroughRouting:
|
|||
forwarding to a path Apodex does not serve for these tiers."""
|
||||
assert _messages_config(model) is None
|
||||
|
||||
def test_deep_research_translation_uses_responses_api(self):
|
||||
from litellm.llms.anthropic.experimental_pass_through.messages.handler import (
|
||||
_should_route_to_responses_api,
|
||||
)
|
||||
@pytest.mark.parametrize("stream", (False, True), ids=("non-streaming", "streaming"))
|
||||
def test_deep_research_translation_uses_responses_api(self, monkeypatch: pytest.MonkeyPatch, stream: bool):
|
||||
from litellm.llms.anthropic.experimental_pass_through.messages import handler
|
||||
|
||||
assert _should_route_to_responses_api("apodex") is True
|
||||
captured: dict = {}
|
||||
|
||||
class ResponsesRouteSelected(Exception):
|
||||
pass
|
||||
|
||||
def capture_responses_translation(**kwargs):
|
||||
captured.update(kwargs)
|
||||
raise ResponsesRouteSelected
|
||||
|
||||
def reject_chat_translation(**kwargs):
|
||||
pytest.fail("Apodex Deep Research messages must not route through chat completions")
|
||||
|
||||
monkeypatch.setattr(litellm, "responses", capture_responses_translation)
|
||||
monkeypatch.setattr(litellm, "completion", reject_chat_translation)
|
||||
|
||||
with pytest.raises(ResponsesRouteSelected):
|
||||
handler.anthropic_messages_handler(
|
||||
max_tokens=256,
|
||||
messages=[{"role": "user", "content": "hi"}],
|
||||
model="apodex/apodex-1-1-deep-research",
|
||||
custom_llm_provider="apodex",
|
||||
stream=stream,
|
||||
)
|
||||
|
||||
assert captured["model"] == "apodex-1-1-deep-research"
|
||||
assert captured["custom_llm_provider"] == "apodex"
|
||||
assert captured.get("stream", False) is stream
|
||||
|
||||
|
||||
class TestNativePassthroughRequest:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue