WAI-4383: update to support multiple images

This commit is contained in:
Ubuntu
2026-01-24 21:06:12 +00:00
parent fda3d917b2
commit 3e9599c0fb
2 changed files with 124 additions and 133 deletions
+24 -33
View File
@@ -1,11 +1,9 @@
import requests
import torch
from .common import (
deserialize_and_get_comfy_key,
image_to_base64,
normalize_images_input,
poll_status_until_completed,
preprocess_image,
)
@@ -19,7 +17,7 @@ class FIBOEditStructuredInstructionNode:
return {
"required": {
"api_token": ("STRING", {"default": "BRIA_API_TOKEN"}),
"image": ("IMAGE",),
"images": ("IMAGE",),
"instruction": ("STRING",),
},
}
@@ -33,53 +31,46 @@ class FIBOEditStructuredInstructionNode:
if api_token.strip() == "" or api_token.strip() == "BRIA_API_TOKEN":
raise Exception("Please insert a valid API token.")
def _build_payload(self, image, instruction):
# Process image
if isinstance(image, torch.Tensor):
processed_image = preprocess_image(image)
else:
processed_image = image
def _build_payload(self, processed_image, instruction):
payload = {
"instruction": instruction,
"images": [image_to_base64(processed_image)],
}
return payload
def execute(self, api_token, image, instruction):
def execute(self, api_token, images, instruction):
self._validate_token(api_token)
payload = self._build_payload(image, instruction)
api_token = deserialize_and_get_comfy_key(api_token)
headers = {"Content-Type": "application/json", "api_token": api_token}
# Normalize input to list of PIL images
images = normalize_images_input(images)
try:
response = requests.post(self.api_url, json=payload, headers=headers)
batch_results = []
if response.status_code in (200, 202):
print(
f"Initial request successful to {self.api_url}, polling for completion..."
)
for idx, pil_image in enumerate(images):
try:
payload = self._build_payload(pil_image, instruction)
headers = {"Content-Type": "application/json", "api_token": api_token}
response = requests.post(self.api_url, json=payload, headers=headers)
if response.status_code not in (200, 202):
raise Exception(f"API request failed with status {response.status_code}: {response.text}")
print(f"Initial request successful for image {idx}, polling for completion...")
response_dict = response.json()
status_url = response_dict.get("status_url")
request_id = response_dict.get("request_id")
if not status_url:
raise Exception("No status_url returned from API")
print(f"Request ID: {request_id}, Status URL: {status_url}")
final_response = poll_status_until_completed(status_url, api_token)
result = final_response.get("result", {})
structured_instruction = result.get("structured_instruction", "")
batch_results.append(structured_instruction)
return (structured_instruction,)
except Exception as e:
print(f"[FIBOEditStructuredInstructionNode] Skipping image {idx} due to error: {e}")
batch_results.append("")
raise Exception(
f"Error: API request failed with status code {response.status_code} {response.text}"
)
except Exception as e:
raise Exception(f"{e}")
combined_instructions = "\n---\n".join(batch_results)
return (combined_instructions,)
+100 -100
View File
@@ -1,48 +1,9 @@
{
"id": "3eb93704-25f0-4511-b147-cf0403c5d060",
"revision": 0,
"last_node_id": 8,
"last_link_id": 9,
"last_node_id": 10,
"last_link_id": 11,
"nodes": [
{
"id": 2,
"type": "LoadImage",
"pos": [
-245.09060668945312,
882.640869140625
],
"size": [
274.080078125,
314
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
4,
6,
8
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"0a9d91e579872d653daf3243df4598f0 (2).png",
"image"
]
},
{
"id": 7,
"type": "PreviewImage",
@@ -130,7 +91,7 @@
"widget": {
"name": "structured_instruction"
},
"link": 7
"link": 11
}
],
"outputs": [
@@ -142,7 +103,7 @@
]
},
{
"name": "structured_prompt",
"name": "structured_instruction",
"type": "STRING",
"links": null
},
@@ -166,44 +127,6 @@
"randomize"
]
},
{
"id": 5,
"type": "FIBOEditStructuredInstructionNode",
"pos": [
-122.1817626953125,
435.91400146484375
],
"size": [
314.6372985839844,
82
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 6
}
],
"outputs": [
{
"name": "structured_instruction",
"type": "STRING",
"links": [
7
]
}
],
"properties": {
"Node name for S&R": "FIBOEditStructuredInstructionNode"
},
"widgets_values": [
"",
"change the lamp to a coffee mug"
]
},
{
"id": 4,
"type": "FIBOEditNode",
@@ -240,7 +163,7 @@
]
},
{
"name": "structured_prompt",
"name": "structured_instruction",
"type": "STRING",
"links": null
},
@@ -263,6 +186,83 @@
55,
"randomize"
]
},
{
"id": 2,
"type": "LoadImage",
"pos": [
-245.09060668945312,
882.640869140625
],
"size": [
274.080078125,
314
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
4,
8,
10
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"0a9d91e579872d653daf3243df4598f0 (2).png",
"image"
]
},
{
"id": 10,
"type": "FIBOEditStructuredInstructionNode",
"pos": [
-139.52833557128906,
410.5189208984375
],
"size": [
314.6372985839844,
82
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 10
}
],
"outputs": [
{
"name": "structured_instruction",
"type": "STRING",
"links": [
11
]
}
],
"properties": {
"Node name for S&R": "FIBOEditStructuredInstructionNode"
},
"widgets_values": [
"BRIA_API_TOKEN",
""
]
}
],
"links": [
@@ -282,22 +282,6 @@
0,
"IMAGE"
],
[
6,
2,
0,
5,
0,
"IMAGE"
],
[
7,
5,
0,
8,
2,
"STRING"
],
[
8,
2,
@@ -313,6 +297,22 @@
7,
0,
"IMAGE"
],
[
10,
2,
0,
10,
0,
"IMAGE"
],
[
11,
10,
0,
8,
2,
"STRING"
]
],
"groups": [],
@@ -321,8 +321,8 @@
"ds": {
"scale": 0.7522123482651067,
"offset": [
958.445911560887,
-236.63172581276325
684.0553164416729,
-258.9658284524182
]
},
"frontendVersion": "1.25.11"