Fix : use litellm params for other video apis

This commit is contained in:
Sameer Kankute 2025-12-09 23:03:29 +05:30
parent 8039c5052f
commit 320f861916
6 changed files with 123 additions and 24 deletions

View file

@ -4338,6 +4338,7 @@ class BaseLLMHTTPHandler:
headers=extra_headers or {},
model="",
api_key=api_key,
litellm_params=litellm_params,
)
if extra_headers:
@ -4413,6 +4414,7 @@ class BaseLLMHTTPHandler:
headers=extra_headers or {},
model="",
api_key=api_key,
litellm_params=litellm_params,
)
if extra_headers:
@ -4727,6 +4729,7 @@ class BaseLLMHTTPHandler:
api_key=api_key,
headers=extra_headers or {},
model="",
litellm_params=litellm_params,
)
if extra_headers:
@ -4899,6 +4902,7 @@ class BaseLLMHTTPHandler:
api_key=api_key,
headers=extra_headers or {},
model="",
litellm_params=litellm_params,
)
if extra_headers:
@ -4985,6 +4989,7 @@ class BaseLLMHTTPHandler:
api_key=api_key,
headers=extra_headers or {},
model="",
litellm_params=litellm_params,
)
if extra_headers:

View file

@ -222,6 +222,8 @@ class VertexAIVideoConfig(BaseVideoConfig, VertexBase):
# Construct the URL
if api_base:
base_url = api_base.rstrip("/")
elif vertex_location == "global":
base_url = "https://aiplatform.googleapis.com"
else:
base_url = f"https://{vertex_location}-aiplatform.googleapis.com"

View file

@ -257,8 +257,19 @@ async def route_request(
"aretrieve_container",
"adelete_container",
]:
# moderation endpoint does not require `model` parameter
# These endpoints can work with or without model parameter
return getattr(llm_router, f"{route_type}")(**data)
elif route_type in [
"avideo_status",
"avideo_content",
"avideo_remix",
]:
# Video endpoints: If model is provided (e.g., from decoded video_id), try router first
try:
return getattr(llm_router, f"{route_type}")(**data)
except Exception:
# If router fails (e.g., model not found in router), fall back to direct call
return getattr(litellm, f"{route_type}")(**data)
elif user_model is not None:
return getattr(litellm, f"{route_type}")(**data)

View file

@ -1,20 +1,21 @@
#### Video Endpoints #####
from typing import Any, Dict, Optional
import orjson
from fastapi import APIRouter, Depends, Request, Response, UploadFile, File
from fastapi import APIRouter, Depends, File, Request, Response, UploadFile
from fastapi.responses import ORJSONResponse
from typing import Optional, Dict, Any
from litellm.proxy._types import *
from litellm.proxy.auth.user_api_key_auth import UserAPIKeyAuth, user_api_key_auth
from litellm.proxy.common_request_processing import ProxyBaseLLMRequestProcessing
from litellm.proxy.image_endpoints.endpoints import batch_to_bytesio
from litellm.proxy.common_utils.http_parsing_utils import _read_request_body
from litellm.proxy.common_utils.openai_endpoint_utils import (
get_custom_llm_provider_from_request_body,
get_custom_llm_provider_from_request_headers,
get_custom_llm_provider_from_request_query,
)
from litellm.proxy.image_endpoints.endpoints import batch_to_bytesio
from litellm.types.videos.utils import decode_video_id_with_provider
router = APIRouter()
@ -240,6 +241,7 @@ async def video_status(
decoded = decode_video_id_with_provider(video_id)
provider_from_id = decoded.get("custom_llm_provider")
model_id_from_decoded = decoded.get("model_id")
custom_llm_provider = (
get_custom_llm_provider_from_request_headers(request=request)
@ -251,6 +253,13 @@ async def video_status(
if custom_llm_provider:
data["custom_llm_provider"] = custom_llm_provider
# Resolve model_name from model_id if available
# This allows the router to automatically inject litellm_params from the model config
if model_id_from_decoded and llm_router:
resolved_model = llm_router.resolve_model_name_from_model_id(model_id_from_decoded)
if resolved_model:
data["model"] = resolved_model
# Process request using ProxyBaseLLMRequestProcessing
processor = ProxyBaseLLMRequestProcessing(data=data)
try:
@ -331,6 +340,7 @@ async def video_content(
decoded = decode_video_id_with_provider(video_id)
provider_from_id = decoded.get("custom_llm_provider")
model_id_from_decoded = decoded.get("model_id")
custom_llm_provider = (
get_custom_llm_provider_from_request_headers(request=request)
@ -341,6 +351,12 @@ async def video_content(
if custom_llm_provider:
data["custom_llm_provider"] = custom_llm_provider
# Resolve model_name from model_id if available
# This allows the router to automatically inject litellm_params from the model config
if model_id_from_decoded and llm_router:
resolved_model = llm_router.resolve_model_name_from_model_id(model_id_from_decoded)
if resolved_model:
data["model"] = resolved_model
# Process request using ProxyBaseLLMRequestProcessing
processor = ProxyBaseLLMRequestProcessing(data=data)
try:
@ -436,6 +452,7 @@ async def video_remix(
decoded = decode_video_id_with_provider(video_id)
provider_from_id = decoded.get("custom_llm_provider")
model_id_from_decoded = decoded.get("model_id")
custom_llm_provider = (
get_custom_llm_provider_from_request_headers(request=request)
@ -446,6 +463,13 @@ async def video_remix(
if custom_llm_provider:
data["custom_llm_provider"] = custom_llm_provider
# Resolve model_name from model_id if available
# This allows the router to automatically inject litellm_params from the model config
if model_id_from_decoded and llm_router:
resolved_model = llm_router.resolve_model_name_from_model_id(model_id_from_decoded)
if resolved_model:
data["model"] = resolved_model
# Process request using ProxyBaseLLMRequestProcessing
processor = ProxyBaseLLMRequestProcessing(data=data)
try:

View file

@ -43,10 +43,6 @@ import litellm
import litellm.litellm_core_utils
import litellm.litellm_core_utils.exception_mapping_utils
from litellm import get_secret_str
from litellm.router_utils.common_utils import (
filter_team_based_models,
filter_web_search_deployments,
)
from litellm._logging import verbose_router_logger
from litellm._uuid import uuid
from litellm.caching.caching import (
@ -89,6 +85,10 @@ from litellm.router_utils.clientside_credential_handler import (
get_dynamic_litellm_params,
is_clientside_credential,
)
from litellm.router_utils.common_utils import (
filter_team_based_models,
filter_web_search_deployments,
)
from litellm.router_utils.cooldown_cache import CooldownCache
from litellm.router_utils.cooldown_handlers import (
DEFAULT_COOLDOWN_TIME_SECONDS,
@ -157,7 +157,11 @@ from litellm.types.utils import (
)
from litellm.types.utils import ModelInfo
from litellm.types.utils import ModelInfo as ModelMapInfo
from litellm.types.utils import ModelResponseStream, StandardLoggingPayload, Usage
from litellm.types.utils import (
ModelResponseStream,
StandardLoggingPayload,
Usage,
)
from litellm.utils import (
CustomStreamWrapper,
EmbeddingResponse,
@ -6679,6 +6683,58 @@ class Router:
"""
return candidate_id in self.model_id_to_deployment_index_map
def resolve_model_name_from_model_id(self, model_id: Optional[str]) -> Optional[str]:
"""
Resolve model_name from model_id.
This method attempts to find the correct model_name to use with the router
so that litellm_params can be automatically injected from the model config.
Strategy:
1. First, check if model_id directly matches a model_name or deployment ID
2. If not, search through router's model_list to find a match by litellm_params.model
3. Return the model_name if found, None otherwise
Args:
model_id: The model_id extracted from decoded video_id
(could be model_name or litellm_params.model value)
Returns:
model_name if found, None otherwise. If None, the request will fall through
to normal flow using environment variables.
"""
if not model_id:
return None
# Strategy 1: Check if model_id directly matches a model_name or deployment ID
if model_id in self.model_names or self.has_model_id(model_id):
return model_id
# Strategy 2: Search through router's model_list to find by litellm_params.model
all_models = self.get_model_list(model_name=None)
if not all_models:
return None
for deployment in all_models:
litellm_params = deployment.get("litellm_params", {})
actual_model = litellm_params.get("model")
# Match by exact match or by checking if actual_model ends with /model_id or :model_id
# e.g., model_id="veo-2.0-generate-001" matches actual_model="vertex_ai/veo-2.0-generate-001"
matches = (
actual_model == model_id
or (actual_model and actual_model.endswith(f"/{model_id}"))
or (actual_model and actual_model.endswith(f":{model_id}"))
)
if matches:
model_name = deployment.get("model_name")
if model_name:
return model_name
# No match found
return None
def map_team_model(self, team_model_name: str, team_id: str) -> Optional[str]:
"""
Map a team model name to a team-specific model name.

View file

@ -1,25 +1,26 @@
import asyncio
import contextvars
from functools import partial
from typing import Any, Coroutine, Literal, Optional, Union, overload, Dict, List
import json
from functools import partial
from typing import Any, Coroutine, Dict, List, Literal, Optional, Union, overload
import litellm
from litellm.constants import DEFAULT_VIDEO_ENDPOINT_MODEL
from litellm.constants import request_timeout as DEFAULT_REQUEST_TIMEOUT
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
from litellm.llms.base_llm.videos.transformation import BaseVideoConfig
from litellm.llms.custom_httpx.llm_http_handler import BaseLLMHTTPHandler
from litellm.main import base_llm_http_handler
from litellm.types.router import GenericLiteLLMParams
from litellm.types.utils import CallTypes, FileTypes
from litellm.types.videos.main import (
VideoCreateOptionalRequestParams,
VideoObject,
)
from litellm.videos.utils import VideoGenerationRequestUtils
from litellm.constants import DEFAULT_VIDEO_ENDPOINT_MODEL, request_timeout as DEFAULT_REQUEST_TIMEOUT
from litellm.main import base_llm_http_handler
from litellm.utils import client, ProviderConfigManager
from litellm.types.utils import FileTypes, CallTypes
from litellm.types.router import GenericLiteLLMParams
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
from litellm.llms.base_llm.videos.transformation import BaseVideoConfig
from litellm.llms.custom_httpx.llm_http_handler import BaseLLMHTTPHandler
from litellm.types.videos.utils import decode_video_id_with_provider
from litellm.utils import ProviderConfigManager, client
from litellm.videos.utils import VideoGenerationRequestUtils
#################### Initialize provider clients ####################
llm_http_handler: BaseLLMHTTPHandler = BaseLLMHTTPHandler()
@ -416,10 +417,10 @@ async def avideo_content(
loop = asyncio.get_event_loop()
kwargs["async_call"] = True
# Ensure custom_llm_provider is not None - default to openai if not provided
# Video content endpoints don't require a model parameter
# Try to decode provider from video_id if not explicitly provided
if custom_llm_provider is None:
custom_llm_provider = "openai"
decoded = decode_video_id_with_provider(video_id)
custom_llm_provider = decoded.get("custom_llm_provider") or "openai"
func = partial(
video_content,