feat(containers): Azure routing, managed container IDs, delete response parsing - #25287
Conversation
…sponse wire format - Add AzureContainerConfig and safe URL joining for paths with api-version query - Encode/decode managed container IDs in responses, streaming, and proxy handlers - Accept OpenAI delete response object literal container.file.deleted - Tests for Azure URL regression and DeleteContainerFileResponse parsing Made-with: Cursor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Delta stream events do not include a response body; Mock-based tests (and any truthy synthetic .response on transforms) must not trigger _update_responses_api_response_id_with_model_id. Fixes test_stop_async_iteration_not_logged_as_failure (TypeError: Mock not iterable). Made-with: Cursor
- Add ContainerRequestUtils.encode_container_id_in_response utility - Encode container_id in create/retrieve/delete responses (SDK path) - Fix streaming iterator: gate response ID update on parsed_chunk key - Follows responses API pattern (encode after handler, not in handler) Made-with: Cursor
Greptile SummaryThis PR extends LiteLLM's container API with four improvements: Azure routing (
Confidence Score: 5/5Safe to merge; all remaining findings are P2 style and performance suggestions Core logic is correct and well-tested: AzureContainerConfig registration, managed ID encode/decode (None-guard fix applied), httpx.URL path joining, and DeleteContainerFileResponse wire-format fix all work correctly. The two P2 findings (inline imports, uncached JSON read) are non-blocking. litellm/llms/custom_httpx/container_handler.py (inline imports + uncached JSON read); litellm/containers/utils.py (target_model_names affinity edge case)
|
| Filename | Overview |
|---|---|
| litellm/llms/azure/containers/transformation.py | New AzureContainerConfig inheriting OpenAIContainerConfig; delegates auth/URL to BaseAzureLLM — clean and minimal |
| litellm/llms/openai/containers/utils.py | New join_container_api_base_path helper using httpx.URL to preserve query-string when appending paths — fixes Azure api-version placement bug |
| litellm/llms/custom_httpx/container_handler.py | New GenericContainerHandler; _load_endpoints_config() re-reads endpoints.json without caching on every request; three inline imports |
| litellm/containers/utils.py | decode_managed_container_id_for_request and encode_container_id_in_response added; target_model_names[0] affinity may not match actual deployment |
| litellm/responses/utils.py | _build_container_id/_decode_container_id helpers with correct None-guard; robust regex-based decoding with safe fallback |
| litellm/types/containers/main.py | DeleteContainerFileResponse now accepts container.file.deleted (OpenAI/Azure wire) and container_file.deleted (legacy) |
| litellm/proxy/container_endpoints/handler_factory.py | Proxy handlers decode managed container IDs; decode pattern duplicated across three functions; inline imports remain |
| litellm/containers/main.py | All container functions accept azure/azure_text and call decode_managed_container_id_for_request before provider config lookup |
| litellm/containers/endpoint_factory.py | Endpoint factory updated for azure/azure_text; decode_managed_container_id_for_request called before dispatching |
| tests/test_litellm/containers/test_azure_container_transformation.py | Comprehensive unit tests for AzureContainerConfig including URL construction and api-version regression tests |
| tests/test_litellm/containers/test_container_utils.py | Tests for decode_managed_container_id_for_request roundtrip and DeleteContainerFileResponse wire format |
| tests/test_litellm/containers/test_container_api.py | Container API tests covering encode/decode roundtrip at the API layer |
| tests/test_litellm/responses/test_responses_utils.py | ResponsesAPIRequestUtils tests including container ID encode/decode roundtrip |
| litellm/responses/streaming_iterator.py | Streaming iterator now calls _encode_container_id_on_output_item for output_item events so managed IDs appear incrementally in streaming |
| litellm/utils.py | ProviderConfigManager.get_provider_container_config now returns AzureContainerConfig for AZURE/AZURE_TEXT providers |
| litellm/llms/azure/containers/init.py | New empty init.py for the azure containers module |
| litellm/llms/openai/containers/transformation.py | All URL-building methods now use join_container_api_base_path instead of f-string concatenation |
Sequence Diagram
sequenceDiagram
participant Client
participant Proxy as LiteLLM Proxy
participant Handler as handler_factory.py
participant SDK as containers/main.py
participant Azure as Azure OpenAI
Note over Client,Azure: Container Create (encoding)
Client->>Proxy: POST /v1/containers {name}
Proxy->>SDK: create_container(provider=azure)
SDK->>Azure: POST /openai/v1/containers
Azure-->>SDK: {id: "cntr_abc"}
SDK->>SDK: encode_container_id_in_response()<br/>id -> cntr_{b64(litellm:azure;model_id:X;cntr_abc)}
SDK-->>Proxy: ContainerObject(id=cntr_{b64...})
Proxy-->>Client: {id: "cntr_{b64...}"}
Note over Client,Azure: Follow-up (decoding)
Client->>Proxy: GET /v1/containers/cntr_{b64...}/files
Proxy->>Handler: _process_request(container_id=cntr_{b64...})
Handler->>Handler: _decode_container_id()<br/>-> original=cntr_abc, provider=azure
Handler->>SDK: list_container_files(cntr_abc, azure)
SDK->>Azure: GET /openai/v1/containers/cntr_abc/files?api-version=v1
Azure-->>SDK: ContainerFileListResponse
SDK-->>Proxy: ContainerFileListResponse
Proxy-->>Client: file list
Reviews (3): Last reviewed commit: "Fix p1 concern" | Re-trigger Greptile
- Move ResponsesAPIRequestUtils imports to module scope (utils, main, handler_factory). - Serialize absent model_id as empty segment instead of literal None; decode empty and legacy "None" segments as missing for router affinity. - Add unit tests for build/decode round-trip and legacy IDs. Made-with: Cursor
|
@greptile-apps will raise another PR for P1 as this is not an issue introduced by this feat but an already existing issue |
|
That makes sense. Addressing pre-existing issues in a separate PR keeps this one focused and makes the changes easier to review. Just make sure to link the P1 PR here when you open it so we can track the fix. Tip: You can customize Greptile's behavior for this repo with |
- Add decode_managed_container_id_for_request in containers/utils and reuse from main. - Strip LiteLLM cntr_ wrappers before generic_container_handler (64-char API limit). - Resolve provider for logging/errors; add unit test for decode helper. - Use resolved_custom_llm_provider after decode for mypy-safe provider typing. Made-with: Cursor
d03eced
into
litellm_internal_staging_04_11_2026
…se parsing (BerriAI#25287) * feat(containers): Azure container routing, managed IDs, and delete response wire format - Add AzureContainerConfig and safe URL joining for paths with api-version query - Encode/decode managed container IDs in responses, streaming, and proxy handlers - Accept OpenAI delete response object literal container.file.deleted - Tests for Azure URL regression and DeleteContainerFileResponse parsing Made-with: Cursor * fix(responses): gate response id update on parsed_chunk having response Delta stream events do not include a response body; Mock-based tests (and any truthy synthetic .response on transforms) must not trigger _update_responses_api_response_id_with_model_id. Fixes test_stop_async_iteration_not_logged_as_failure (TypeError: Mock not iterable). Made-with: Cursor * feat(containers): encode container IDs in SDK responses for routing - Add ContainerRequestUtils.encode_container_id_in_response utility - Encode container_id in create/retrieve/delete responses (SDK path) - Fix streaming iterator: gate response ID update on parsed_chunk key - Follows responses API pattern (encode after handler, not in handler) Made-with: Cursor * fix(containers): module-level imports and managed cntr_ ID encoding - Move ResponsesAPIRequestUtils imports to module scope (utils, main, handler_factory). - Serialize absent model_id as empty segment instead of literal None; decode empty and legacy "None" segments as missing for router affinity. - Add unit tests for build/decode round-trip and legacy IDs. Made-with: Cursor * fix(containers): decode managed IDs in endpoint_factory SDK path - Add decode_managed_container_id_for_request in containers/utils and reuse from main. - Strip LiteLLM cntr_ wrappers before generic_container_handler (64-char API limit). - Resolve provider for logging/errors; add unit test for decode helper. - Use resolved_custom_llm_provider after decode for mypy-safe provider typing. Made-with: Cursor * Fix p1 concern * Fix p1 concern
Summary
AzureContainerConfigand register it for Azure / Azure Text inProviderConfigManager.httpx.URLsoapi-versionstays in the query string (fixes malformed Azure URLs).cntr_IDs: encode on responses/streaming output; decode in proxy container handlers and container SDK helpers so upstream sees the original provider container id.DeleteContainerFileResponse: accept OpenAI/Azure wire valuecontainer.file.deleted(was rejecting and surfacing 500s after successful DELETE).