Add multi-image support for Seedream45 Edit

This commit is contained in:
Dreaming Computers
2026-02-02 10:35:46 +07:00
parent d22086ffaf
commit 4ce2139503
7 changed files with 270 additions and 10 deletions
+1 -1
View File
@@ -42,7 +42,7 @@ This node pack currently includes the following nodes:
- Image generation node using the Googles Nano Banana Pro model
- **Seedream Text-to-Image / Edit**
- Text-to-image and image-editing node for Seedream models.
- Supports prompt-based generation and edits.
- Supports prompt-based generation and edits (edit node accepts up to 14 input images).
- **Flux 2 Image-to-Image (Pro/Flex)**
- Image-to-image node with a model dropdown for Pro or Flex.
- Accepts 1–8 input images via ComfyUI batch.
+2 -1
View File
@@ -1,6 +1,6 @@
# Internal Status
Last updated: 2026-01-31
Last updated: 2026-02-02
## Active Tasks
- [x] Consolidate Gemini LLM nodes into one with model dropdown (2.5/3 Pro/Flash)
@@ -9,3 +9,4 @@ Last updated: 2026-01-31
## Notes
- 2026-01-31: Gemini LLM node now selects model via dropdown and logs selected model.
- 2026-02-02: Seedream 4.5 Edit updated to accept up to 14 input images.
@@ -0,0 +1,194 @@
Seedream 4.5 is Bytedance’s refined image model for 4K generation, precise editing, and consistent multi-image output.
POST
/api/v1/jobs/createTask
Create Task
Create a new generation task
Request Parameters
The API accepts a JSON payload with the following structure:
Request Body Structure
{
"model": "string",
"callBackUrl": "string (optional)",
"input": {
// Input parameters based on form configuration
}
}
Root Level Parameters
model
Required
string
The model name to use for generation
Example:
"seedream/4.5-edit"
callBackUrl
Optional
string
Callback URL for task completion notifications. Optional parameter. If provided, the system will send POST requests to this URL when the task completes (success or failure). If not provided, no callback notifications will be sent.
Example:
"https://your-domain.com/api/callback"
Input Object Parameters
The input object contains the following parameters based on the form configuration:
input.prompt
Required
string
A text description of the image you want to generate
Max length: 3000 characters
Example:
"Keep the model's pose and the flowing shape of the liquid dress unchanged. Change the clothing material from silver metal to completely transparent clear water (or glass). Through the liquid water, the model's skin details are visible. Lighting changes from reflection to refraction."
input.image_urls
Required
array(URL)
Upload an image file to use as input for the API
File URL after upload, not file content; Accepted types: image/jpeg, image/png, image/webp; Max size: 10.0MB
Max count: 14 images
Example:
["https://static.aiquickdraw.com/tools/example/1764851484363_ScV1s2aq.webp"]
input.aspect_ratio
Required
string
Width-height ratio of the image, determining its visual form.
Available options:
1:1
-
1:1
4:3
-
4:3
3:4
-
3:4
16:9
-
16:9
9:16
-
9:16
2:3
-
2:3
3:2
-
3:2
21:9
-
21:9
Example:
"1:1"
input.quality
Required
string
Basic outputs 2K images, while High outputs 4K images.
Available options:
basic
-
Basic
high
-
High
Example:
"basic"
Request Example
cURL
JavaScript
Python
import requests
import json
url = "https://api.kie.ai/api/v1/jobs/createTask"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY"
}
payload = {
"model": "seedream/4.5-edit",
"callBackUrl": "https://your-domain.com/api/callback",
"input": {
"prompt": "Keep the model's pose and the flowing shape of the liquid dress unchanged. Change the clothing material from silver metal to completely transparent clear water (or glass). Through the liquid water, the model's skin details are visible. Lighting changes from reflection to refraction.",
"image_urls": [
"https://static.aiquickdraw.com/tools/example/1764851484363_ScV1s2aq.webp"
],
"aspect_ratio": "1:1",
"quality": "basic"
}
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
result = response.json()
print(result)
Response Example
{
"code": 200,
"message": "success",
"data": {
"taskId": "task_12345678"
}
}
Response Fields
code
Status code, 200 for success, others for failure
message
Response message, error description when failed
data.taskId
Task ID for querying task status
Callback Notifications
When you provide the callBackUrl parameter when creating a task, the system will send POST requests to the specified URL upon task completion (success or failure).
Success Callback Example
{
"code": 200,
"data": {
"completeTime": 1755599644000,
"consumeCredits": 100,
"costTime": 8,
"createTime": 1755599634000,
"model": "seedream/4.5-edit",
"param": "{\"callBackUrl\":\"https://your-domain.com/api/callback\",\"model\":\"seedream/4.5-edit\",\"input\":{\"prompt\":\"Keep the model's pose and the flowing shape of the liquid dress unchanged. Change the clothing material from silver metal to completely transparent clear water (or glass). Through the liquid water, the model's skin details are visible. Lighting changes from reflection to refraction.\",\"image_urls\":[\"https://static.aiquickdraw.com/tools/example/1764851484363_ScV1s2aq.webp\"],\"aspect_ratio\":\"1:1\",\"quality\":\"basic\"}}",
"remainedCredits": 2510330,
"resultJson": "{\"resultUrls\":[\"https://example.com/generated-image.jpg\"]}",
"state": "success",
"taskId": "e989621f54392584b05867f87b160672",
"updateTime": 1755599644000
},
"msg": "Playground task completed successfully."
}
Failure Callback Example
{
"code": 501,
"data": {
"completeTime": 1755597081000,
"consumeCredits": 0,
"costTime": 0,
"createTime": 1755596341000,
"failCode": "500",
"failMsg": "Internal server error",
"model": "seedream/4.5-edit",
"param": "{\"callBackUrl\":\"https://your-domain.com/api/callback\",\"model\":\"seedream/4.5-edit\",\"input\":{\"prompt\":\"Keep the model's pose and the flowing shape of the liquid dress unchanged. Change the clothing material from silver metal to completely transparent clear water (or glass). Through the liquid water, the model's skin details are visible. Lighting changes from reflection to refraction.\",\"image_urls\":[\"https://static.aiquickdraw.com/tools/example/1764851484363_ScV1s2aq.webp\"],\"aspect_ratio\":\"1:1\",\"quality\":\"basic\"}}",
"remainedCredits": 2510430,
"state": "fail",
"taskId": "bd3a37c523149e4adf45a3ddb5faf1a8",
"updateTime": 1755597097000
},
"msg": "Playground task failed."
}
@@ -0,0 +1,39 @@
# KIE Seedream 4.5 Edit — Multi-Image Support Task List
Goal: allow the Seedream45_Edit node/helper to accept and upload up to 14 input images, then pass all uploaded URLs to `input.image_urls`.
## Context (current behavior)
- Helper: `kie_api/seedream45_edit.py` uploads only the first image in the batch.
- Node: `nodes.py` HELP text explicitly says "first image used".
- Spec: `_internal/docs/KIE_API_SEEDREAM_45_EDIT_SPEC.md` lists `input.image_urls` but does not specify a max count.
- Multi-image patterns to mirror: `kie_api/flux2_i2i.py` and `kie_api/nanobanana.py`.
## Open question (must confirm before coding)
- Confirm the server-side max image count for Seedream 4.5 Edit (user believes 14). If confirmed, update the spec doc to include the max.
## Phase 1 — Spec/requirements alignment
- [ ] Confirm max image count with KIE docs or internal source.
- [ ] Update `_internal/docs/KIE_API_SEEDREAM_45_EDIT_SPEC.md` to include max count (1..14) once confirmed.
## Phase 2 — Helper changes (seedream45_edit.py)
- [ ] Add `MAX_IMAGE_COUNT = 14` (or confirmed value).
- [ ] Update `_validate_image_input()` to keep shape checks; do not fail on batch size > 1.
- [ ] Upload up to `MAX_IMAGE_COUNT` images using the pattern in `flux2_i2i.py`:
- log when more than max provided
- iterate through `min(total_images, MAX_IMAGE_COUNT)`
- build `image_urls` list from uploads
- [ ] Update payload to use `image_urls` list (instead of a single URL).
- [ ] Log how many URLs are sent to `createTask` for traceability.
## Phase 3 — Node wrapper and docs
- [ ] Update `nodes.py` HELP text for `KIE_Seedream45_Edit` to reflect up to 14 images and that all provided images are uploaded (up to the cap).
- [ ] Update `web/docs/KIE_Seedream45_Edit.md` with correct inputs/outputs and helper behavior (upload cap, truncation behavior).
## Phase 4 — Validation
- [ ] Run `python3 -m py_compile nodes.py kie_api/seedream45_edit.py`.
- [ ] Minimal manual test: pass a batch of 2+ images and confirm multiple uploads + task creation includes multiple URLs.
## Acceptance criteria
- Helper uploads up to 14 images and sends all URLs in `input.image_urls`.
- If more than 14 images are supplied, the helper logs a truncation message and uses only the first 14.
- Node HELP and web docs clearly describe the multi-image behavior.
+16 -7
View File
@@ -33,6 +33,7 @@ MODEL_NAME = "seedream/4.5-edit"
ASPECT_RATIO_OPTIONS = ["1:1", "4:3", "3:4", "16:9", "9:16", "2:3", "3:2", "21:9"]
QUALITY_OPTIONS = ["basic", "high"]
PROMPT_MAX_LENGTH = 3000
MAX_IMAGE_COUNT = 14
def _validate_options(aspect_ratio: str, quality: str) -> None:
@@ -119,24 +120,32 @@ def run_seedream45_edit(
api_key = _load_api_key()
if images.shape[0] > 1:
_log(log, f"More than 1 image provided ({images.shape[0]}); only the first will be used.")
total_images = images.shape[0]
if total_images > MAX_IMAGE_COUNT:
_log(log, f"More than {MAX_IMAGE_COUNT} images provided ({total_images}); only first {MAX_IMAGE_COUNT} used.")
_log(log, "Uploading edit input image...")
png_bytes = _image_tensor_to_png_bytes(images[0])
image_url = _upload_image(api_key, png_bytes)
_log(log, f"Input image upload success: {_truncate_url(image_url)}")
upload_count = min(total_images, MAX_IMAGE_COUNT)
image_urls: list[str] = []
if upload_count > 0:
_log(log, f"Uploading {upload_count} edit image(s)...")
for idx in range(upload_count):
png_bytes = _image_tensor_to_png_bytes(images[idx])
image_url = _upload_image(api_key, png_bytes)
image_urls.append(image_url)
_log(log, f"Image {idx + 1} upload success: {_truncate_url(image_url)}")
payload = {
"model": MODEL_NAME,
"input": {
"prompt": prompt,
"image_urls": [image_url],
"image_urls": image_urls,
"aspect_ratio": aspect_ratio,
"quality": quality,
},
}
_log(log, f"Sending {len(image_urls)} image URL(s) to createTask")
_log(log, "Creating Seedream 4.5 edit task...")
start_time = time.time()
task_id, create_response_text = _create_seedream45_edit_task(api_key, payload)
+1 -1
View File
@@ -219,7 +219,7 @@ Edit an input image using Seedream 4.5.
Inputs:
- prompt: Edit prompt (required)
- images: Source image batch (first image used)
- images: Source image batch (up to 14 images; all uploaded)
- aspect_ratio / quality
- poll_interval_s / timeout_s / log
+17
View File
@@ -0,0 +1,17 @@
## KIE Seedream 4.5 Edit
Edit an input image (or batch of images) using Seedream 4.5.
### Inputs
- **prompt** (STRING, required): Edit prompt text (max 3000 chars).
- **images** (IMAGE, required): Source image batch. Up to 14 images are uploaded; extra images are ignored.
- **aspect_ratio** (COMBO, optional): `1:1`, `4:3`, `3:4`, `16:9`, `9:16`, `2:3`, `3:2`, `21:9` (default: `1:1`).
- **quality** (COMBO, optional): `basic`, `high` (default: `basic`).
- **log** (BOOLEAN, optional): Enable helper logging (default: `true`).
### Outputs
- **IMAGE**: ComfyUI image tensor (BHWC float32, 0..1).
### Helper behavior
- Uploads up to 14 images and sends all uploaded URLs in `input.image_urls`.
- If more than 14 images are provided, only the first 14 are used and a log message is emitted.