diff --git a/litellm/containers/main.py b/litellm/containers/main.py index 196722f5674..ccdc0087fae 100644 --- a/litellm/containers/main.py +++ b/litellm/containers/main.py @@ -279,7 +279,7 @@ def create_container( # Set the correct call type for container creation litellm_logging_obj.call_type = CallTypes.create_container.value - return base_llm_http_handler.container_create_handler( + container_obj = base_llm_http_handler.container_create_handler( name=name, container_create_request_params=container_create_request_params, container_provider_config=container_provider_config, @@ -289,6 +289,17 @@ def create_container( timeout=timeout or DEFAULT_REQUEST_TIMEOUT, _is_async=_is_async, ) + + # Encode container_id with provider/model metadata for routing + if isinstance(container_obj, ContainerObject): + model_id = kwargs.get("litellm_metadata", {}).get("model_info", {}).get("id") + container_obj = ContainerRequestUtils.encode_container_id_in_response( + response_obj=container_obj, + custom_llm_provider=custom_llm_provider, + model_id=model_id, + ) + + return container_obj except Exception as e: raise litellm.exception_type( @@ -683,7 +694,7 @@ def retrieve_container( # Set the correct call type litellm_logging_obj.call_type = CallTypes.retrieve_container.value - return base_llm_http_handler.container_retrieve_handler( + container_obj = base_llm_http_handler.container_retrieve_handler( container_id=original_container_id, # Use decoded original ID container_provider_config=container_provider_config, litellm_params=litellm_params, @@ -693,6 +704,17 @@ def retrieve_container( timeout=timeout or DEFAULT_REQUEST_TIMEOUT, _is_async=_is_async, ) + + # Encode container_id with provider/model metadata for routing + if isinstance(container_obj, ContainerObject): + model_id = kwargs.get("litellm_metadata", {}).get("model_info", {}).get("id") + container_obj = ContainerRequestUtils.encode_container_id_in_response( + response_obj=container_obj, + custom_llm_provider=custom_llm_provider, + model_id=model_id, + ) + + return container_obj except Exception as e: raise litellm.exception_type( @@ -879,7 +901,7 @@ def delete_container( # Set the correct call type litellm_logging_obj.call_type = CallTypes.delete_container.value - return base_llm_http_handler.container_delete_handler( + delete_result = base_llm_http_handler.container_delete_handler( container_id=original_container_id, # Use decoded original ID container_provider_config=container_provider_config, litellm_params=litellm_params, @@ -889,6 +911,17 @@ def delete_container( timeout=timeout or DEFAULT_REQUEST_TIMEOUT, _is_async=_is_async, ) + + # Encode container_id in response with provider/model metadata for routing + if isinstance(delete_result, DeleteContainerResult): + model_id = kwargs.get("litellm_metadata", {}).get("model_info", {}).get("id") + delete_result = ContainerRequestUtils.encode_container_id_in_response( + response_obj=delete_result, + custom_llm_provider=custom_llm_provider, + model_id=model_id, + ) + + return delete_result except Exception as e: raise litellm.exception_type( diff --git a/litellm/containers/utils.py b/litellm/containers/utils.py index 048f587fda7..43efb452f3f 100644 --- a/litellm/containers/utils.py +++ b/litellm/containers/utils.py @@ -1,4 +1,4 @@ -from typing import Dict +from typing import Any, Dict, Optional, TypeVar from litellm.llms.base_llm.containers.transformation import BaseContainerConfig from litellm.types.containers.main import ( @@ -6,6 +6,8 @@ from litellm.types.containers.main import ( ContainerListOptionalRequestParams, ) +T = TypeVar("T") + class ContainerRequestUtils: @staticmethod @@ -68,3 +70,35 @@ class ContainerRequestUtils: container_list_optional_params[param] = passed_params[param] # type: ignore return container_list_optional_params + + @staticmethod + def encode_container_id_in_response( + response_obj: T, + custom_llm_provider: Optional[str], + model_id: Optional[str], + ) -> T: + """ + Encode container_id in response object with provider/model metadata for routing. + + This mirrors the responses API pattern where response IDs are encoded with + routing metadata so follow-up calls can route to the correct provider. + + Args: + response_obj: Response object with an `id` attribute (ContainerObject, DeleteContainerResult, etc.) + custom_llm_provider: Provider name (e.g., "azure", "openai") + model_id: Model ID from litellm_metadata + + Returns: + The same response object with encoded container_id + """ + if response_obj and hasattr(response_obj, "id"): + from litellm.responses.utils import ResponsesAPIRequestUtils + + encoded_id = ResponsesAPIRequestUtils._build_container_id( + custom_llm_provider=custom_llm_provider, + model_id=model_id, + container_id=response_obj.id, + ) + response_obj.id = encoded_id + + return response_obj