diff --git a/litellm/llms/fal_ai/videos/transformation.py b/litellm/llms/fal_ai/videos/transformation.py index 838e7065ef7..d6cd7f0d5ce 100644 --- a/litellm/llms/fal_ai/videos/transformation.py +++ b/litellm/llms/fal_ai/videos/transformation.py @@ -75,6 +75,14 @@ _H3_MAX_PROFILE: Final[_ModelProfile] = _ModelProfile( reference_key="image_url", reference_as_list=False, ) +_LUMA_RAY_PROFILE: Final[_ModelProfile] = _ModelProfile( + resolutions=frozenset({"540p", "720p", "1080p"}), + resolution_tiers=((540, "540p"), (720, "720p"), (sys.maxsize, "1080p")), + default_resolution="540p", + integer_duration=False, + reference_key="image_url", + reference_as_list=False, +) _SEEDANCE_REFERENCE_PROFILE: Final[_ModelProfile] = replace( _SEEDANCE_PROFILE, reference_key="image_urls", @@ -118,6 +126,8 @@ def _profile_for_model(model: str) -> _ModelProfile: return _H3_PROFILE if model.startswith("minimax/h3-max"): return _H3_MAX_PROFILE + if model.startswith("luma/agent/ray/"): + return _LUMA_RAY_PROFILE is_seedance_reference: Final = model.startswith("bytedance/seedance-") and model.endswith("/reference-to-video") return _SEEDANCE_REFERENCE_PROFILE if is_seedance_reference else _SEEDANCE_PROFILE diff --git a/tests/unit/llms/fal_ai/videos/test_fal_ai_video_transformation.py b/tests/unit/llms/fal_ai/videos/test_fal_ai_video_transformation.py index b20c8069789..3498663775f 100644 --- a/tests/unit/llms/fal_ai/videos/test_fal_ai_video_transformation.py +++ b/tests/unit/llms/fal_ai/videos/test_fal_ai_video_transformation.py @@ -232,6 +232,29 @@ class TestFalAIVideoTransformation: assert video.usage == {"duration_seconds": 5.0, "video_resolution": "2K"} + def test_transform_video_create_response_luma_ray_defaults_to_540p(self): + response = Mock(spec=httpx.Response) + response.json.return_value = {"request_id": "abc"} + + for model in ( + "luma/agent/ray/v3.2/text-to-video", + "luma/agent/ray/v3.2/image-to-video", + "luma/agent/ray/v3.2/reframe", + "luma/agent/ray/v3.2/video-to-video", + ): + video = self.config.transform_video_create_response( + model=model, + raw_response=response, + logging_obj=self.logging_obj, + custom_llm_provider="fal_ai", + request_data={"duration": "5"}, + ) + assert video.usage == {"duration_seconds": 5.0, "video_resolution": "540p"}, model + row = litellm.model_cost[f"fal_ai/{model}"] + assert default_video_cost_calculator(model, 5, "fal_ai", video_resolution="540p") == ( + 5 * row["output_cost_per_second"] + ), model + def test_transform_video_create_response_h3_max_leaves_default_resolution_to_cost_map( self, local_model_cost_map: None ) -> None: