mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-12 08:42:18 +00:00
fix(openrouter): accept only PNG and JPEG images for TypeSafe Jev decision models
This commit is contained in:
parent
5d1a081334
commit
029d3c4a7e
4 changed files with 49 additions and 2 deletions
|
|
@ -612,7 +612,7 @@ def _has_media_type_in(media_types: frozenset[str], image: DecisionsImage) -> bo
|
|||
|
||||
|
||||
def _checked_image_types(call: DecisionsCall) -> DecisionsCall:
|
||||
media_types: Final = call.provider_config.image_media_types
|
||||
media_types: Final = call.provider_config.image_media_types_for(call.model)
|
||||
if media_types is None:
|
||||
return call
|
||||
found: Final = (image_media_type(image) for image in input_images(call.ir_request.input))
|
||||
|
|
|
|||
|
|
@ -649,6 +649,9 @@ class BaseDecisionsConfig(ABC):
|
|||
) -> bool:
|
||||
return self.supports_images
|
||||
|
||||
def image_media_types_for(self, model: str) -> frozenset[str] | None:
|
||||
return self.image_media_types
|
||||
|
||||
def supports_assets(self, headers: Mapping[str, str]) -> bool:
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ from typing import Final
|
|||
from litellm.llms.base_llm.decisions.transformation import BaseDecisionsConfig
|
||||
from litellm.types.decisions import DecisionsIRResponse
|
||||
|
||||
_TYPESAFE_IMAGE_MEDIA_TYPES: Final = frozenset({"image/png", "image/jpeg", "image/jpg"})
|
||||
|
||||
|
||||
class OpenRouterDecisionsConfig(BaseDecisionsConfig):
|
||||
path = "/alpha/decisions"
|
||||
|
|
@ -16,6 +18,11 @@ class OpenRouterDecisionsConfig(BaseDecisionsConfig):
|
|||
def get_default_api_base(self) -> str | None:
|
||||
return "https://openrouter.ai/api"
|
||||
|
||||
def image_media_types_for(self, model: str) -> frozenset[str] | None:
|
||||
if model.removeprefix("~").startswith("typesafe/"):
|
||||
return _TYPESAFE_IMAGE_MEDIA_TYPES
|
||||
return self.image_media_types
|
||||
|
||||
def provider_reported_cost(self, response: DecisionsIRResponse) -> float | None:
|
||||
cost: Final = response.usage.extra.get("cost") if response.usage is not None else None
|
||||
if not isinstance(cost, (int, float)):
|
||||
|
|
|
|||
|
|
@ -4065,7 +4065,7 @@ async def test_hosted_vllm_decisions_sends_input_images_to_systemone(
|
|||
|
||||
|
||||
_STATE_IMAGE_PROVIDERS: Final = (
|
||||
("openrouter/typesafe/jev-1.14", "https://openrouter.ai/api/alpha/decisions", "typesafe/jev-1.14"),
|
||||
("openrouter/cloudflare/clef", "https://openrouter.ai/api/alpha/decisions", "cloudflare/clef"),
|
||||
("perplexity/pplx-decider-v1.2", "https://api.perplexity.ai/v1/decisions", "pplx-decider-v1.2"),
|
||||
)
|
||||
_STATE_IMAGE_PROVIDER_IDS: Final = ("openrouter", "perplexity")
|
||||
|
|
@ -4157,6 +4157,43 @@ def test_a_gif_to_a_state_image_provider_is_rejected_before_http(
|
|||
assert not route.called
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", ("openrouter/typesafe/jev-1.14", "openrouter/~typesafe/jev-latest"))
|
||||
def test_openrouter_jev_rejects_webp_before_http(
|
||||
model: str, respx_mock: respx.MockRouter, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
monkeypatch.setattr(litellm, "drop_params", False)
|
||||
route: Final = respx_mock.post("https://openrouter.ai/api/alpha/decisions").respond(json=_RESPONSE)
|
||||
|
||||
with pytest.raises(litellm.BadRequestError, match=re.escape("got image/webp")):
|
||||
litellm.systemone(
|
||||
model=model,
|
||||
state=_SCREEN_TEXT,
|
||||
questions=_SYSTEMONE_PREDICATE,
|
||||
images=["data:image/webp;base64,BB=="],
|
||||
api_key="k",
|
||||
)
|
||||
|
||||
assert not route.called
|
||||
|
||||
|
||||
def test_openrouter_jev_drops_webp_and_keeps_png_under_drop_params(respx_mock: respx.MockRouter) -> None:
|
||||
route: Final = respx_mock.post("https://openrouter.ai/api/alpha/decisions").respond(json=_RESPONSE)
|
||||
|
||||
litellm.systemone(
|
||||
model="openrouter/typesafe/jev-1.14",
|
||||
state=_SCREEN_TEXT,
|
||||
questions=_SYSTEMONE_PREDICATE,
|
||||
images=["data:image/webp;base64,BB==", "data:image/png;base64,AA=="],
|
||||
api_key="k",
|
||||
drop_params=True,
|
||||
)
|
||||
|
||||
assert json.loads(route.calls.last.request.content)["state"] == [
|
||||
_SCREEN_TEXT,
|
||||
{"type": "image_url", "image_url": {"url": "data:image/png;base64,AA=="}},
|
||||
]
|
||||
|
||||
|
||||
def test_hosted_vllm_systemone_forwards_images(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
respx_mock: respx.MockRouter,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue