Slice 3a: image_edit Modality + Qwen-Image-Edit 2511 (1/2/3 images) (closes part of #5)#19
Open
jmpijll wants to merge 1 commit into
Open
Slice 3a: image_edit Modality + Qwen-Image-Edit 2511 (1/2/3 images) (closes part of #5)#19jmpijll wants to merge 1 commit into
jmpijll wants to merge 1 commit into
Conversation
Slice 3a adds the image_edit Modality and three Qwen-Image-Edit 2511 manifests (1, 2, and 3 input images) sharing one Plugin. Workflow JSONs were built from live /object_info introspection, not by copying the v2 workflows. The user-LoRA at node 5 defaults to strength 0.0 so the manifest stays safe to register on any server with the declared LoRA file installed. Closes part of #5. The FLUX Kontext on Klein half of #5 is deferred to a follow-up issue / PR because the Klein workflow is gated on Slice 2 fixing FLUX 2 Klein first. Issue #5 stays open. - core/modalities/image_edit/{__init__,plugin.py}: new ImageEditPlugin (modality IMAGE_EDIT, output image/png) with a stepped progress mapper, slot-value validator that reuses the manifest-driven coercion helpers, a Discord renderer that surfaces the edit instruction + every source-image slot + seed + output, and default_post_actions that echoes the Manifest's declared Actions. - core/modalities/{__init__,registry}.py: register ImageEditPlugin in the default registry alongside the existing Plugins. - workflows/qwen_image_edit_2511_{1image,2images,3images}.json: three variants of the same graph (UNETLoader -> Lightning LoRA -> user LoRA stack -> ModelSamplingAuraFlow -> CFGNorm -> KSampler / euler / simple / 4 steps; LoadImage -> ImageScaleToTotalPixels -> VAEEncode for the first source; positive + negative TextEncodeQwenImageEditPlus conditioning; VAEDecode -> SaveImage). Variants differ only in extra LoadImage nodes (16, 17) wired into image2 / image3 of the conditioning nodes. - workflows/manifests/qwen_image_edit_2511_{1image,2images,3images}.yaml: manifests with exact /object_info filenames in requires (UNET, VAE, CLIP, Lightning LoRA, QWEN_EDIT_ACTION_V1) and 6/7/8 Slots: prompt, negative_prompt, image_1[/image_2/image_3], seed, lora, lora_strength. Actions declare upscale + animate follow-ups; no model branching. - tests/test_image_edit_plugin.py: Plugin contract, slot-value coercion (incl. multi-image cases), progress monotonicity, render output surface + multi-source ordering, default_post_actions echoing. - tests/test_qwen_edit_manifest_loading.py: directory load, requires validation (positive + UNET/Lightning-LoRA negative paths), every slot target resolves to an existing (node, field) in the workflow JSON, slot counts match the variant, attachment positions are 1-indexed and unique, apply_slots writes through correctly, and every loader filename in the workflow appears in the manifest's requires list. - docs/v3/smoke/SLICE_3_RUNS.md: live-smoke evidence (prompt_ids, latencies, output bytes) for all three variants against the live ComfyUI at 172.27.1.165:8188. Live smoke evidence (Tuesday, 2026-06-02, all PASSED): 1image prompt_id f46e87b3-19a8-41f6-8a97-d5aa5cf9aaf2 21.77s 2,333,633 B 2images prompt_id 8f1e061c-2526-408a-aa81-77ce8b4865da 17.14s 1,896,280 B 3images prompt_id eeb3bf7a-1747-4750-8f87-5a1c0e2d5d14 20.47s 2,139,755 B Tests: 368 passed (full suite, ignoring tests/integration). Worktree: /Users/jamievanderpijll/discomfy-slice-3-qwen (slice/5-qwen-edit). Co-authored-by: Cursor <cursoragent@cursor.com>
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
Slice 3a covers the Qwen-Image-Edit 2511 half of issue #5. The
FLUX Kontext on Klein half is deferred to a follow-up issue / PR
because it is gated on Slice 2 fixing the FLUX 2 Klein workflow first.
Issue #5 stays open after this PR merges; the follow-up PR will close
it.
Closes part of #5.
image_editModality with one shared Plugin(
core/modalities/image_edit/plugin.py) - slot-value validation,stepped progress mapper, Discord renderer that surfaces the edit
instruction + every source-image slot + seed + output, default
post-actions echoing the Manifest's declared Actions (upscale +
animate are valid follow-ups for an edit Run).
All three share the same loader + sampler graph and differ only in
the number of
LoadImagenodes wired into theTextEncodeQwenImageEditPlusconditioning'simage2/image3inputs. Lightning 4-step LoRA is baked at node 4; a user-stack LoRA
at node 5 defaults to strength
0.0./object_infoonthe live ComfyUI; the only loader filenames in any of them are the
exact strings that
/object_infoadvertises, and the manifestrequiresblocks declare those exact strings.Rolevalues were needed:source_image,source_image_2, andsource_image_3already existed incore/manifest/roles.py.Modality.IMAGE_EDITwas already presenttoo (anticipated by ADR-0002).
Models used (from live
/object_info)qwen_image_edit_2511_fp8mixed.safetensorsqwen_2.5_vl_7b_fp8_scaled.safetensors(type: qwen_image)qwen_image_vae.safetensorsQwen-Image-Edit-2511-Lightning-4steps-V1.0-bf16.safetensorsQWEN_EDIT_ACTION_V1.safetensors(strength 0.0)Acceptance criteria
Modality.IMAGE_EDIT = "image_edit"present (it already was).source_image,source_image_2,source_image_3); no new Role added. (Seecore/manifest/roles.py.)ImageEditPluginvalidates slot values, exposes a progressmapper that sums sampler steps across nodes, renders Outputs
into a Discord embed, returns Manifest-declared default
Actions.
core.modalities.default_registry(verified by
tests/test_image_edit_plugin.py::test_registered_in_default_registry)./object_info, not copiedfrom v2 (
workflows/qwen_image_edit_2511_{1image,2images,3images}.json).requiresfilenames + slots forprompt,negative_prompt,image_1[/image_2/image_3],seed,lora,lora_strength(
workflows/manifests/qwen_image_edit_2511_*.yaml).tests/test_image_edit_plugin.py+tests/test_qwen_edit_manifest_loading.py(44 new tests).pytest(excludingtests/integration) green:368 passed.
http://172.27.1.165:8188PASSED for allthree variants.
Live smoke evidence
Source images were generated via the existing
qwen_image_2512manifest first, then fed into each edit variant. Full details +
reproduction commands in
docs/v3/smoke/SLICE_3_RUNS.md.qwen_image_edit_2511_1imagef46e87b3-19a8-41f6-8a97-d5aa5cf9aaf2qwen_image_edit_2511_2images8f1e061c-2526-408a-aa81-77ce8b4865daqwen_image_edit_2511_3imageseeb3bf7a-1747-4750-8f87-5a1c0e2d5d14ComfyUI: RTX 5090, fp8 mixed UNET, 4-step Lightning sampling.
Anchors
docs/v3/PRD.md-- "image edit (1-3 inputs)" item in thev3 ship list.
code;
requiresvalidated against/object_info).Deferred work (NOT in this PR)
2 (FLUX 2 Klein workflow fix). Will be a follow-up issue + PR. Do
not close v3 Slice 3: Image edit - Qwen-Image-Edit 2511 (1-3 images) + FLUX Kontext on Klein #5 when this PR merges.
Worktree note
This branch was implemented from the worktree at
/Users/jamievanderpijll/discomfy-slice-3-qwen(Slice 4 surfaced aclobber risk when working directly in the main checkout). The
worktree's
venvis a symlink to the main repo'svenv, so noduplicate environment was created.
Test plan
pytest -q --ignore=tests/integration-> 368 passed.pytest tests/test_image_edit_plugin.py tests/test_qwen_edit_manifest_loading.py -x -q-> 44 passed.python scripts/v3_smoke.py --manifest qwen_image_edit_2511_1image --slot prompt="..." --slot image_1=...-> OK.python scripts/v3_smoke.py --manifest qwen_image_edit_2511_2images --slot prompt="..." --slot image_1=... --slot image_2=...-> OK.python scripts/v3_smoke.py --manifest qwen_image_edit_2511_3images --slot prompt="..." --slot image_1=... --slot image_2=... --slot image_3=...-> OK.Made with Cursor