Skip to content

[TRTLLM-14730][feat] Add image edit serving endpoint for visual generation models - #16987

Merged
yibinl-nvidia merged 14 commits into
NVIDIA:mainfrom
yibinl-nvidia:qwen-image-edit-openai-endpoint
Aug 18, 2026
Merged

[TRTLLM-14730][feat] Add image edit serving endpoint for visual generation models#16987
yibinl-nvidia merged 14 commits into
NVIDIA:mainfrom
yibinl-nvidia:qwen-image-edit-openai-endpoint

Conversation

@yibinl-nvidia

@yibinl-nvidia yibinl-nvidia commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Description

Adds an OpenAI-compatible /v1/images/edits serving endpoint for VisualGen models. The endpoint accepts JSON/base64 and multipart image inputs, materializes uploaded inputs into server-owned temporary storage, cleans request input files after generation, and returns edited images through either url or b64_json responses.

This PR wires image edit serving for Qwen image-edit, Qwen-Image-Layered, and Flux2 local checkpoint routing. For Qwen-Image-Layered, the pipeline default output changes from a packed layer grid to a per-layer image batch; callers that need the previous single-grid behavior should pass extra_params={"save_layers_to_grid": true}.

Test Coverage

  • tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py
  • tests/unittest/_torch/visual_gen/test_qwen_image_layered_registry.py
  • tests/integration/test_lists/test-db/l0_b200.yml enrolls both visual-gen unit test files.

@yibinl-nvidia yibinl-nvidia changed the title [TRTLLM-14730][feat]Add OpenAI image edit endpoint for visual generation [TRTLLM-14730][feat] Add image edit serving endpoint for visual generation models Jul 29, 2026
@yibinl-nvidia
yibinl-nvidia force-pushed the qwen-image-edit-openai-endpoint branch 3 times, most recently from f5b8b99 to bad7e7f Compare July 30, 2026 21:48
@yibinl-nvidia
yibinl-nvidia marked this pull request as ready for review July 30, 2026 21:48
@yibinl-nvidia
yibinl-nvidia requested review from a team as code owners July 30, 2026 21:48
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Qwen image-edit requests now support JSON and multipart inputs for supported Qwen visual-generation models. Qwen-Image-Layered outputs default to separate RGBA layers, with an option to return a packed grid. Tests, examples, and model documentation reflect the new behavior.

Changes

Qwen Image Edit and Layer Output

Layer / File(s) Summary
Layered output formatting
tensorrt_llm/_torch/visual_gen/models/qwen_image_layered/pipeline_qwen_image_layered.py, examples/visual_gen/models/qwen_image_layered.py, tests/unittest/_torch/visual_gen/test_qwen_image_layered_registry.py
The pipeline adds save_layers_to_grid, validates its type, and returns either separate layer images or a packed grid. The example and tests cover both formats.
Image-edit request materialization
tensorrt_llm/serve/openai_protocol.py, tensorrt_llm/serve/visual_gen_utils.py, tensorrt_llm/visual_gen/params.py
ImageEditRequest defines image-edit fields and dimension validation. Media helpers decode and materialize conditioning images.
OpenAI image-edit endpoint
tensorrt_llm/serve/openai_server.py
The server detects supported Qwen models, parses JSON or multipart requests, forwards generation parameters, serializes outputs, and handles errors.
Endpoint validation coverage
tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py
Tests cover model gating, image materialization, request limits, cleanup, URL and path rejection, default layered responses, and optional grid packing.
Model support documentation
docs/source/models/supported-models.md, docs/source/models/visual-generation.md
Feature matrices and footnotes document trtllm-serve support, per-layer output, grid packing, and disabled backends.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant OpenAIServer
  participant visual_gen_utils
  participant QwenImageLayeredPipeline
  Client->>OpenAIServer: Submit image-edit request
  OpenAIServer->>visual_gen_utils: Materialize input images
  OpenAIServer->>QwenImageLayeredPipeline: Generate edited layers
  QwenImageLayeredPipeline-->>OpenAIServer: Return layers or grid
  OpenAIServer-->>Client: Return encoded images or URLs
Loading

Possibly related PRs

Suggested reviewers: brnguyen2, allisonlim-nv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.97% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the feature, affected model category, and implementation type.
Description check ✅ Passed The description explains the endpoint, supported inputs and models, behavior changes, and relevant test coverage.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unittest/_torch/visual_gen/test_qwen_image_layered_registry.py (1)

117-126: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Test coverage is insufficient

  • Modified: test_qwen_image_layered_default_params_match_runtime_inputs, test_qwen_image_layered_layer_stack_to_image_grid
  • Added: test_qwen_image_layered_formats_multiple_layer_images_by_default, test_qwen_image_layered_rejects_non_bool_save_layers_to_grid
  • No matching entry was found for tests/unittest/_torch/visual_gen/test_qwen_image_layered_registry.py in tests/integration/test_lists/; add it to the appropriate list (likely tests/integration/test_lists/test-db/l0_b200.yml) so it runs in CI.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/visual_gen/test_qwen_image_layered_registry.py` around
lines 117 - 126, Add
tests/unittest/_torch/visual_gen/test_qwen_image_layered_registry.py to the
appropriate CI test-list entry, likely
tests/integration/test_lists/test-db/l0_b200.yml, so the Qwen image layered
registry tests run in CI.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/source/models/supported-models.md`:
- Around line 191-192: Update the footnote definitions in the supported-models
documentation: align the FLUX definition with the matrix’s referenced footnote
identifier, and remove or rename the duplicate `[^3]` definition so the
Qwen-Image-Layered row resolves to its intended note. Preserve the existing
footnote text and ensure all referenced definitions are unique and
markdownlint-compliant.

In `@examples/visual_gen/models/qwen_image_layered.py`:
- Around line 69-79: Update the output-saving condition around output.image to
inspect the leading batch dimension size rather than image rank: use the
multi-file layer path only when output.image.shape[0] is greater than one, and
preserve the direct output.save(args.output_path) path for a single image or
grid.

In `@tensorrt_llm/serve/visual_gen_utils.py`:
- Around line 105-131: Update _materialize_conditioning_input so existing local
paths and file:// URIs are not passed through unchanged; only accept paths under
media_storage_path or an established allowed-path list, materializing or
rejecting other local inputs. Preserve direct passthrough for HTTP(S) URLs and
ensure _load_image_input can only open image files from the permitted upload
storage.

---

Outside diff comments:
In `@tests/unittest/_torch/visual_gen/test_qwen_image_layered_registry.py`:
- Around line 117-126: Add
tests/unittest/_torch/visual_gen/test_qwen_image_layered_registry.py to the
appropriate CI test-list entry, likely
tests/integration/test_lists/test-db/l0_b200.yml, so the Qwen image layered
registry tests run in CI.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f782df60-3992-4e72-b5a7-890a7578cc60

📥 Commits

Reviewing files that changed from the base of the PR and between c083da6 and bad7e7f.

📒 Files selected for processing (9)
  • docs/source/models/supported-models.md
  • docs/source/models/visual-generation.md
  • examples/visual_gen/models/qwen_image_layered.py
  • tensorrt_llm/_torch/visual_gen/models/qwen_image_layered/pipeline_qwen_image_layered.py
  • tensorrt_llm/serve/openai_protocol.py
  • tensorrt_llm/serve/openai_server.py
  • tensorrt_llm/serve/visual_gen_utils.py
  • tests/unittest/_torch/visual_gen/test_qwen_image_layered_registry.py
  • tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py

Comment thread docs/source/models/supported-models.md Outdated
Comment thread examples/visual_gen/models/qwen_image_layered.py Outdated
Comment thread tensorrt_llm/serve/visual_gen_utils.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py (1)

147-174: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve an explicitly empty extra-parameter schema.

extra_param_specs={} is stored as empty, but the executor receives the fallback stg_scale schema because both assignments use truthiness. This makes the mock metadata disagree with validation behavior and can let tests accept an unsupported parameter. Use is not None when selecting the fallback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py` around lines
147 - 174, Update the executor.extra_param_specs assignment in the mock
initialization to use the provided extra_param_specs whenever it is not None,
including an explicitly empty dictionary; only apply the default stg_scale
schema when no schema was supplied. Keep the earlier self._extra_param_specs
assignment and existing validation metadata unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py`:
- Around line 746-759: Preserve any pre-existing TRTLLM_MEDIA_STORAGE_PATH
instead of unconditionally removing it after each test. Update both
environment-handling blocks at
tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py lines 746-759
and 776-790 to use monkeypatch.setenv() or explicitly restore the original value
during cleanup.

---

Outside diff comments:
In `@tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py`:
- Around line 147-174: Update the executor.extra_param_specs assignment in the
mock initialization to use the provided extra_param_specs whenever it is not
None, including an explicitly empty dictionary; only apply the default stg_scale
schema when no schema was supplied. Keep the earlier self._extra_param_specs
assignment and existing validation metadata unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d0ac62ec-8f0c-4eb3-bc61-d1f609448ef9

📥 Commits

Reviewing files that changed from the base of the PR and between bad7e7f and f2a2db9.

📒 Files selected for processing (1)
  • tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py

Comment thread tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py (1)

163-174: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Preserve an explicit empty extra-parameter schema.

Line 173 converts {} into the default stg_scale schema. MockVisualGen(extra_param_specs={}) then exposes no extra parameters through extra_param_specs, but its executor accepts stg_scale. Tests cannot model a pipeline that rejects every model-specific parameter.

Proposed fix
-            extra_param_specs=extra_param_specs
-            or {"stg_scale": ExtraParamSchema(type="float", default=1.0)},
+            extra_param_specs=(
+                extra_param_specs if extra_param_specs is not None else {
+                    "stg_scale": ExtraParamSchema(type="float", default=1.0),
+                }
+            ),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py` around lines
163 - 174, Update the SimpleNamespace initialization in MockVisualGen so
extra_param_specs uses the provided value whenever it is explicitly supplied,
including an empty dictionary, and only applies the default stg_scale schema
when the argument is omitted or None. Keep the executor’s extra_param_specs
consistent with the model’s exposed parameters.
🧹 Nitpick comments (1)
tensorrt_llm/serve/visual_gen_utils.py (1)

105-106: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use explicit input types instead of Any and hasattr().

Type the helpers with their supported union, including bytes and starlette.datastructures.UploadFile. Use isinstance(value, starlette.datastructures.UploadFile) because raw_request.form() can return Starlette upload objects, not fastapi.UploadFile instances.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/serve/visual_gen_utils.py` around lines 105 - 106, Update
_materialize_conditioning_input and its related helpers to use an explicit
supported union type including bytes and starlette.datastructures.UploadFile
instead of Any; replace hasattr-based detection with isinstance(value,
starlette.datastructures.UploadFile), ensuring Starlette upload objects returned
by raw_request.form() are handled correctly.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py`:
- Around line 163-174: Update the SimpleNamespace initialization in
MockVisualGen so extra_param_specs uses the provided value whenever it is
explicitly supplied, including an empty dictionary, and only applies the default
stg_scale schema when the argument is omitted or None. Keep the executor’s
extra_param_specs consistent with the model’s exposed parameters.

---

Nitpick comments:
In `@tensorrt_llm/serve/visual_gen_utils.py`:
- Around line 105-106: Update _materialize_conditioning_input and its related
helpers to use an explicit supported union type including bytes and
starlette.datastructures.UploadFile instead of Any; replace hasattr-based
detection with isinstance(value, starlette.datastructures.UploadFile), ensuring
Starlette upload objects returned by raw_request.form() are handled correctly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b8ee523f-9694-47cd-bf0a-94d7a41ec3c2

📥 Commits

Reviewing files that changed from the base of the PR and between f2a2db9 and e9f7506.

📒 Files selected for processing (4)
  • docs/source/models/supported-models.md
  • examples/visual_gen/models/qwen_image_layered.py
  • tensorrt_llm/serve/visual_gen_utils.py
  • tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/source/models/supported-models.md

@yibinl-nvidia
yibinl-nvidia force-pushed the qwen-image-edit-openai-endpoint branch from e9f7506 to 4b6542f Compare July 31, 2026 04:05
@yibinl-nvidia

Copy link
Copy Markdown
Collaborator Author

/bot run

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tensorrt_llm/serve/openai_server.py (2)

2594-2638: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Guard against non-string extra_params in multipart requests.

If a client sends the extra_params field as a file part instead of text, value at line 2621-2630 is an UploadFile, not a string. value == "" is False, so the code proceeds to json.loads(value), which raises TypeError, not json.JSONDecodeError. That TypeError is not caught by except json.JSONDecodeError here, nor by except ValueError/except ValidationError in openai_image_edit, so it falls through to the outer except Exception and returns an InternalServerError (500) instead of a BadRequestError (400) for what is a client-input error.

🐛 Proposed fix
                 if key == "extra_params":
                     if value == "":
                         continue
+                    if not isinstance(value, str):
+                        raise ValueError(
+                            "'extra_params' must be a JSON object string.")
                     try:
                         data[key] = json.loads(value)
                     except json.JSONDecodeError as exc:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/serve/openai_server.py` around lines 2594 - 2638, Guard the
extra_params branch in _parse_image_edit_request against non-string multipart
values before calling json.loads. Treat an UploadFile or any other non-string
value as invalid client input and raise ValueError, while preserving the
existing empty-value skip and JSON decoding behavior so openai_image_edit
returns a 400 response instead of an internal error.

500-511: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use bounded matching for image-edit model IDs.

_model_supports_image_edit() uses unbounded substring matching. This enables image editing for unrelated IDs such as org/not-qwen-image-edit-compatible. Match supported model IDs with explicit boundaries while preserving valid variants such as Qwen/Qwen-Image-Edit-2511, and add regression tests for near matches.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/serve/openai_server.py` around lines 500 - 511, Update
_model_supports_image_edit to use bounded matching for supported model
identifiers, so embedded substrings in unrelated IDs are rejected while valid
variants such as Qwen/Qwen-Image-Edit-2511 remain accepted. Preserve
_supports_image_edit’s existing model-ID sources and add regression tests
covering both near-match rejection and valid variant acceptance.
♻️ Duplicate comments (1)
tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py (1)

930-996: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Use monkeypatch.setenv() instead of raw os.environ mutation.

test_qwen_layered_image_edit_returns_multiple_layers_by_default (lines 948, 961) and test_qwen_layered_image_edit_save_layers_to_grid_returns_single_image (lines 978, 992) set and then unconditionally pop TRTLLM_MEDIA_STORAGE_PATH via os.environ, unlike the newer tests in this same class that already use monkeypatch.setenv(...). This mirrors the pattern flagged in a prior review round for this same test family: it can clobber a pre-existing value of TRTLLM_MEDIA_STORAGE_PATH and leaves it removed instead of restored.

♻️ Proposed fix
-        os.environ["TRTLLM_MEDIA_STORAGE_PATH"] = str(tmp_path)
+        monkeypatch.setenv("TRTLLM_MEDIA_STORAGE_PATH", str(tmp_path))
         client = _create_server(gen, model_name="Qwen/Qwen-Image-Layered")
-        try:
-            image_bytes = BytesIO(base64.b64decode(_b64_white_png_1x1()))
-            resp = client.post(...)
-        finally:
-            os.environ.pop("TRTLLM_MEDIA_STORAGE_PATH", None)
+        image_bytes = BytesIO(base64.b64decode(_b64_white_png_1x1()))
+        resp = client.post(...)

Add the monkeypatch fixture parameter to both test functions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py` around lines
930 - 996, Update both test methods,
test_qwen_layered_image_edit_returns_multiple_layers_by_default and
test_qwen_layered_image_edit_save_layers_to_grid_returns_single_image, to accept
the monkeypatch fixture and replace direct os.environ assignment/removal with
monkeypatch.setenv("TRTLLM_MEDIA_STORAGE_PATH", str(tmp_path)). Remove the
manual cleanup blocks so any pre-existing environment value is restored
automatically.
🧹 Nitpick comments (2)
tensorrt_llm/serve/visual_gen_utils.py (2)

141-171: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Narrow the broad exception handling.

Both _materialize_conditioning_input (line 164) and _materialize_conditioning_inputs (line 245) catch except Exception: before cleanup and re-raise. The only exceptions the wrapped calls can raise here are ValueError (limit/decode failures) and OSError (file I/O failures). Catch that narrower tuple instead of Exception.

♻️ Proposed fix
-    except Exception:
+    except (ValueError, OSError):
         try:
             os.remove(path)
         except FileNotFoundError:
             pass
         raise

Apply the same change to the except Exception: at line 245.

As per coding guidelines, "Catch specific exceptions instead of using broad or bare exception handling such as except:."

Also applies to: 222-248

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/serve/visual_gen_utils.py` around lines 141 - 171, Replace the
broad exception handlers in _materialize_conditioning_input and
_materialize_conditioning_inputs with a tuple catching only ValueError and
OSError, while preserving the existing path cleanup and re-raise behavior.

Source: Coding guidelines


251-261: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a docstring to this public helper.

cleanup_materialized_conditioning_inputs is imported and called from openai_server.py, so it is a cross-module public interface. It currently has no docstring, unlike its sibling _materialize_conditioning_input. Document that it accepts a single path or a list, silently skips non-string entries, and tolerates missing files.

As per coding guidelines, "Prefer docstrings for external interfaces, use Google-style docstrings, document public function arguments."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/serve/visual_gen_utils.py` around lines 251 - 261, Add a
Google-style docstring to the public helper
cleanup_materialized_conditioning_inputs describing that value may be one path
or a list of paths, non-string entries are skipped, and missing files are
tolerated; document its argument according to the project’s docstring
conventions.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@tensorrt_llm/serve/openai_server.py`:
- Around line 2594-2638: Guard the extra_params branch in
_parse_image_edit_request against non-string multipart values before calling
json.loads. Treat an UploadFile or any other non-string value as invalid client
input and raise ValueError, while preserving the existing empty-value skip and
JSON decoding behavior so openai_image_edit returns a 400 response instead of an
internal error.
- Around line 500-511: Update _model_supports_image_edit to use bounded matching
for supported model identifiers, so embedded substrings in unrelated IDs are
rejected while valid variants such as Qwen/Qwen-Image-Edit-2511 remain accepted.
Preserve _supports_image_edit’s existing model-ID sources and add regression
tests covering both near-match rejection and valid variant acceptance.

---

Duplicate comments:
In `@tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py`:
- Around line 930-996: Update both test methods,
test_qwen_layered_image_edit_returns_multiple_layers_by_default and
test_qwen_layered_image_edit_save_layers_to_grid_returns_single_image, to accept
the monkeypatch fixture and replace direct os.environ assignment/removal with
monkeypatch.setenv("TRTLLM_MEDIA_STORAGE_PATH", str(tmp_path)). Remove the
manual cleanup blocks so any pre-existing environment value is restored
automatically.

---

Nitpick comments:
In `@tensorrt_llm/serve/visual_gen_utils.py`:
- Around line 141-171: Replace the broad exception handlers in
_materialize_conditioning_input and _materialize_conditioning_inputs with a
tuple catching only ValueError and OSError, while preserving the existing path
cleanup and re-raise behavior.
- Around line 251-261: Add a Google-style docstring to the public helper
cleanup_materialized_conditioning_inputs describing that value may be one path
or a list of paths, non-string entries are skipped, and missing files are
tolerated; document its argument according to the project’s docstring
conventions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0592c272-a419-4976-9fc8-46b88e7dffd4

📥 Commits

Reviewing files that changed from the base of the PR and between e9f7506 and 4b6542f.

📒 Files selected for processing (6)
  • docs/source/models/supported-models.md
  • examples/visual_gen/models/qwen_image_layered.py
  • tensorrt_llm/serve/openai_protocol.py
  • tensorrt_llm/serve/openai_server.py
  • tensorrt_llm/serve/visual_gen_utils.py
  • tests/unittest/_torch/visual_gen/test_trtllm_serve_endpoints.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • tensorrt_llm/serve/openai_protocol.py
  • examples/visual_gen/models/qwen_image_layered.py
  • docs/source/models/supported-models.md

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #62948 [ run ] triggered by Bot. Commit: 4b6542f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #62948 [ run ] completed with state SUCCESS. Commit: 4b6542f
/LLM/main/L0_MergeRequest_PR pipeline #51064 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@yibinl-nvidia

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #62969 [ run ] triggered by Bot. Commit: 4b6542f Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #62969 [ run ] completed with state FAILURE. Commit: 4b6542f
/LLM/main/L0_MergeRequest_PR pipeline #51081 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@yibinl-nvidia

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #63009 [ run ] triggered by Bot. Commit: 4b6542f Link to invocation

Signed-off-by: yibinl-nvidia <109242046+yibinl-nvidia@users.noreply.github.com>
Signed-off-by: yibinl-nvidia <109242046+yibinl-nvidia@users.noreply.github.com>
Signed-off-by: yibinl-nvidia <109242046+yibinl-nvidia@users.noreply.github.com>
Signed-off-by: yibinl-nvidia <109242046+yibinl-nvidia@users.noreply.github.com>
Ensure the seconds-without-frame-rate test removes the mock pipeline frame_rate default so it exercises the intended validation path.

Signed-off-by: yibinl-nvidia <109242046+yibinl-nvidia@users.noreply.github.com>
Signed-off-by: yibinl-nvidia <109242046+yibinl-nvidia@users.noreply.github.com>
Signed-off-by: yibinl-nvidia <109242046+yibinl-nvidia@users.noreply.github.com>
@yibinl-nvidia
yibinl-nvidia force-pushed the qwen-image-edit-openai-endpoint branch from 3a001dc to 4ce1940 Compare August 17, 2026 21:09
@yibinl-nvidia

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #66856 [ run ] triggered by Bot. Commit: 4ce1940 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #66856 [ run ] completed with state SUCCESS. Commit: 4ce1940
/LLM/main/L0_MergeRequest_PR pipeline #54415 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@yibinl-nvidia

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #66875 [ run ] triggered by Bot. Commit: 4ce1940 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #66875 [ run ] completed with state FAILURE. Commit: 4ce1940
/LLM/main/L0_MergeRequest_PR pipeline #54429 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@yibinl-nvidia

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #66906 [ run ] triggered by Bot. Commit: 4ce1940 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #66906 [ run ] completed with state FAILURE. Commit: 4ce1940
/LLM/main/L0_MergeRequest_PR pipeline #54462 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@yibinl-nvidia

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #66944 [ run ] triggered by Bot. Commit: 4ce1940 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #66944 [ run ] completed with state FAILURE. Commit: 4ce1940
/LLM/main/L0_MergeRequest_PR pipeline #54496 completed with status: 'UNSTABLE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

Link to invocation

@yibinl-nvidia

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #67050 [ run ] triggered by Bot. Commit: 4ce1940 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #67050 [ run ] completed with state FAILURE. Commit: 4ce1940
/LLM/main/L0_MergeRequest_PR pipeline #54590 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

@yibinl-nvidia

Copy link
Copy Markdown
Collaborator Author

/bot run

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #67057 [ run ] triggered by Bot. Commit: 4ce1940 Link to invocation

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #67057 [ run ] completed with state SUCCESS. Commit: 4ce1940
/LLM/main/L0_MergeRequest_PR pipeline #54595 completed with status: 'SUCCESS'

CI Report

Link to invocation

@yibinl-nvidia
yibinl-nvidia merged commit 61c11a0 into NVIDIA:main Aug 18, 2026
7 checks passed
@yibinl-nvidia
yibinl-nvidia deleted the qwen-image-edit-openai-endpoint branch August 18, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants