Repository navigation
chore(release/1.5.1): cherry-pick #14563, #14436, #14435, #14474 - #15668
Merged
Merged
Conversation
…input (#14436) Signed-off-by: nnshah1 <neelays@nvidia.com> Signed-off-by: Dmitry Tokarev <dtokarev@nvidia.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Dmitry Tokarev <dtokarev@nvidia.com> (cherry picked from commit 77c6ff1) Signed-off-by: Dmitry Tokarev <dtokarev@nvidia.com>
…es (#14435) The sglang image-diffusion and video-generation handlers passed the client-supplied input_reference through to the generator's image_path after only a non-empty check. Validate it first, and for remote references materialize it locally before the generator sees it, so the generator is always handed a trusted local path. This brings the sglang diffusion path in line with the vLLM/omni and trtllm backends, which already validate the same field. Behavior change: local I2I/I2V references now require DYN_MM_LOCAL_PATH to be set to the allowed directory; previously any path was accepted. common/http: - validate_media_reference() returns a plain filesystem path for local references; local_media_reference() is an async context manager that fetches a remote one through fetch_bytes(policy=...), which revalidates every redirect hop, into a temp file removed on exit. data: is rejected -- a URI is not a path. - fetch_bytes() gained max_bytes, streaming through collect_capped at an explicit read granularity so the cap is an allocation bound and not only a rejection: a 128 MiB-decoded gzip body against the 64 MiB cap peaks at 68,032,217 bytes rather than the whole decompressed body. Content-Length is caller-controlled and absent when chunked, and aiohttp's read(n) returns at most n bytes, so neither a header check nor a single capped read suffices. Defaults to None, leaving existing callers unchanged. - DYN_MM_MAX_FILE_SIZE_MB makes that cap operator-tunable, in megabytes, as the SGLang arg it replaces was. Read per call; empty, unparseable or non-positive falls back to 64 with a warning, so a malformed value neither takes the worker down nor reads as unlimited. - Messages built from caller input are bounded via describe_media_source, moved from multimodal/media_source.py (it pulls in torch) into url_validator.py and re-exported from its old home; a no-op below 120 characters. - HttpStatusError bounds its .message attribute, not only the rendered string: errors.rs::extract_http_like_error reads .status and .message off this class by name and forwards .message on a 4xx without calling str(). Backend exception text is bounded head-and-tail, since aiohttp renders the host before the errno. - validate_local_path uses exc.strerror rather than the raw OSError, whose text repeats the filename, and now catches the ValueError that Path.resolve() raises on an embedded NUL so callers keep their 4xx-vs-5xx decision. Rebased onto #14563 (single aiohttp backend); the httpx-side half of the max_bytes plumbing went with that backend. Signed-off-by: nnshah1 <neelays@nvidia.com> Signed-off-by: Dmitry Tokarev <dtokarev@nvidia.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit 7a77a5d) Conflict resolution for release/1.5.1, which does not have #13000: - image_diffusion_handler.py: This pick keeps the generate() of the release branch, which returns a failure in the "error" field of the response. It adds the input_reference block of #14435 and the InvalidArgument import that this block uses. An empty input_reference still raises ValueError, as on the release branch. - test_sglang_image_diffusion_handler.py: Three new tests of #14435 expect generate() to raise. On this branch they read the "error" field of the response. They still make sure that the generator does not run. They also make sure that the message has fewer than 500 characters and does not contain the URL. Signed-off-by: Dmitry Tokarev <dtokarev@nvidia.com>
Signed-off-by: nnshah1 <neelays@nvidia.com> Signed-off-by: Dmitry Tokarev <dtokarev@nvidia.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Dmitry Tokarev <dtokarev@nvidia.com> (cherry picked from commit 848206e) Conflict resolution for release/1.5.1: - tests/report_pytest_markers.py: This pick adds only the three aiohttp stubs of #14474 and their comment. The "aiohttp.test_utils" stub next to them on main comes from #14377, which release/1.5.1 does not have. Signed-off-by: Dmitry Tokarev <dtokarev@nvidia.com>
dagil-nvidia
approved these changes
Oct 5, 2026
dagil-nvidia
left a comment
Collaborator
There was a problem hiding this comment.
Approved for 1.5.1 RC1. Remaining CI failures are the pre-existing aggregated_lmcache_mp vllm test on release/1.5.1 and an SGLang tool-call token-cap flake, not these changes.
This was referenced Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
release/1.5.1, as four commits in that order.image_diffusion_handler.pyconflicted in the pick of fix(sglang): validate diffusion input_reference and bound media fetches #14435, becauserelease/1.5.1does not have fix: surface image generation errors instead of returning empty HTTP 200 #13000. This pick keeps thegenerate()of the release branch, which returns a failure in theerrorfield of the response. It adds theinput_referenceblock of fix(sglang): validate diffusion input_reference and bound media fetches #14435 and theInvalidArgumentimport that this block uses.test_sglang_image_diffusion_handler.pymerged without a conflict, but three new tests of fix(sglang): validate diffusion input_reference and bound media fetches #14435 expectgenerate()to raise, as it does after fix: surface image generation errors instead of returning empty HTTP 200 #13000. On this branch, these tests read theerrorfield of the response.tests/report_pytest_markers.pyconflicted in the pick of fix(common-http): pin validated DNS answers at connect time #14474, becauserelease/1.5.1does not have fix(planner): keep control APIs responsive during Prometheus collection #14377. This pick adds only the threeaiohttpstubs of fix(common-http): pin validated DNS answers at connect time #14474 and their comment. It leaves out theaiohttp.test_utilsstub of fix(planner): keep control APIs responsive during Prometheus collection #14377.Validation
ai-dynamo/dynamo:5a28947ec671f2eb83c36e802bb1c8cbfdea2627-sglang-runtime-test(sha256:d55abcf5dd8e),ai-dynamo/dynamo:5a28947ec671f2eb83c36e802bb1c8cbfdea2627-vllm-runtime-test(sha256:26a8d41c80a1) andai-dynamo/dynamo:5a28947ec671f2eb83c36e802bb1c8cbfdea2627-trtllm-runtime-test(sha256:a769982eb315). fix(release): backport IPv6 fixes to 1.5.1 #15430 is based ona327f1ac11ofrelease/1.5.1, and its images are the nearest ones that are still in the registry. Each tree loads its own Python code throughPYTHONPATH.--network nonein one image, first onrelease/1.5.1(aa0d7ac456) and then on this branch:components/src/dynamo/common/tests/http(SGLang image): 76 passed onrelease/1.5.1, and 126 passed on this branch. refactor(http): consolidate to a single aiohttp backend; remove httpx #14563 removes 11 httpx tests, and this branch adds 61 tests.components/src/dynamo/common/tests/configuration(SGLang image): 113 passed and 2 skipped on both.components/src/dynamo/common/tests/multimodal, withouttest_embedding_transfer.py, which needs a GPU (SGLang image): 189 passed onrelease/1.5.1, and 191 passed on this branch. 3 tests skip on both.components/src/dynamo/sglang/tests(SGLang image): 467 passed onrelease/1.5.1, and 474 passed on this branch. 1 test skips on both. The same 14 tests intest_sglang_unit.pyfail on both, because they fetchQwen/Qwen3-0.6Bfrom Hugging Face and the container has no network.components/src/dynamo/vllm/tests/omni(vLLM image): 269 passed onrelease/1.5.1, and 330 passed on this branch.components/src/dynamo/trtllm/tests, with--gpus all(TRT-LLM image): 482 passed and 0 skipped on both.release/1.5.1put back, 4 tests intest_sglang_image_diffusion_handler.pyfail. When the 4xx message includes the exception text, 1 test fails.pytest-marker-reporthook passes. Without the three stubs, it fails withModuleNotFoundError: No module named 'aiohttp.helpers'.pre-commit run --all-filespasses.🤖 Generated with Claude Code