diff --git a/Nodes/Uniapi.py b/Nodes/Uniapi.py index 4c79dfa..729b966 100644 --- a/Nodes/Uniapi.py +++ b/Nodes/Uniapi.py @@ -134,8 +134,8 @@ class PrimereApiProcessor: "seed": ("INT", {"default": 1, "min": 0, "max": (2 ** 32) - 1, "forceInput": True}) } - for key, values in cls._parameter_options().items(): - required_inputs[key] = (values,) + # for key, values in cls._parameter_options().items(): + # required_inputs[key] = (values,) return {"required": required_inputs, "optional": optional_inputs} @@ -335,34 +335,44 @@ class PrimereApiProcessor: raise RuntimeError(f"API call failed for {api_provider}/{selected_service}: {api_error}") if api_error is None: - if api_result.candidates[0].content is not None and api_result.candidates[0].content.parts is not None: - image_parts = [ - part.inline_data.data - for part in api_result.candidates[0].content.parts - if part.inline_data - ] - if image_parts: - result_image = Image.open(BytesIO(image_parts[0])) + if api_provider == "Gemini" and (selected_service or api_service) == "Nanobanana": + if api_result.candidates[0].content is not None and api_result.candidates[0].content.parts is not None: + image_parts = [ + part.inline_data.data + for part in api_result.candidates[0].content.parts + if part.inline_data + ] + if image_parts: + result_image = Image.open(BytesIO(image_parts[0])) + if result_image is not None: + result_image = result_image.convert("RGB") + result_image = np.array(result_image).astype(np.float32) / 255.0 + result_image = torch.from_numpy(result_image)[None,] + final_batch_img.append(result_image) + + if type(final_batch_img).__name__ == "list" and len(final_batch_img) > 1: + image_list = final_batch_img + single_image_start = final_batch_img[0] + batch_count = 0 + s = None + for single_image in final_batch_img: + if (batch_count + 1) < len(final_batch_img): + current_single_image = final_batch_img[batch_count + 1] + if single_image_start.shape[1:] != current_single_image.shape[1:]: + current_single_image = comfy.utils.common_upscale(current_single_image.movedim(-1, 1), single_image_start.shape[2], single_image_start.shape[1], "bilinear", "center").movedim(1, -1) + batch_count = batch_count + 1 + if s is not None: + single_image = s + s = torch.cat((current_single_image, single_image), dim=0) + result_image = s + + if api_provider == "Gemini" and (selected_service or api_service) == "Imagen": + if api_result.generated_images[0].image is not None and api_result.generated_images[0].image.image_bytes is not None: + generated_image = api_result.generated_images[0].image.image_bytes + result_image = Image.open(BytesIO(generated_image)) if result_image is not None: result_image = result_image.convert("RGB") result_image = np.array(result_image).astype(np.float32) / 255.0 result_image = torch.from_numpy(result_image)[None,] - final_batch_img.append(result_image) - - if type(final_batch_img).__name__ == "list" and len(final_batch_img) > 1: - image_list = final_batch_img - single_image_start = final_batch_img[0] - batch_count = 0 - s = None - for single_image in final_batch_img: - if (batch_count + 1) < len(final_batch_img): - current_single_image = final_batch_img[batch_count + 1] - if single_image_start.shape[1:] != current_single_image.shape[1:]: - current_single_image = comfy.utils.common_upscale(current_single_image.movedim(-1, 1), single_image_start.shape[2], single_image_start.shape[1], "bilinear", "center").movedim(1, -1) - batch_count = batch_count + 1 - if s is not None: - single_image = s - s = torch.cat((current_single_image, single_image), dim=0) - result_image = s return (client, api_provider, schema, rendered_payload, api_schemas, api_result, result_image) \ No newline at end of file diff --git a/front_end/api_schemas.json b/front_end/api_schemas.json index 00fda1c..803312f 100644 --- a/front_end/api_schemas.json +++ b/front_end/api_schemas.json @@ -98,6 +98,41 @@ } } } + }, + "Imagen": { + "provider": "Gemini", + "service": "Imagen", + "possible_parameters": { + "resolution": [ + "1K", + "2K" + ], + "model": [ + "imagen-4.0-generate-001", + "imagen-4.0-ultra-generate-001", + "imagen-4.0-fast-generate-001" + ] + }, + "request": { + "method": "SDK", + "endpoint": "client.models.generate_images", + "sdk_call": { + "args": [], + "kwargs": { + "model": "{{model}}", + "prompt": "{{prompt}}", + "config": { + "$call": "types.GenerateImagesConfig", + "$args": [], + "$kwargs": { + "number_of_images": "{{config_number_of_images}}", + "aspect_ratio": "{{config_aspect_ratio}}", + "image_size": "{{config_image_size}}" + } + } + } + } + } } } } diff --git a/terminal_helpers/api_snippet_to_json.py b/terminal_helpers/api_snippet_to_json.py index 62a48de..ca88929 100644 --- a/terminal_helpers/api_snippet_to_json.py +++ b/terminal_helpers/api_snippet_to_json.py @@ -1,4 +1,6 @@ """Convert `snippet.py` into grouped provider->service API schema JSON.""" +# python api_snippet_to_json.py --provider Gemini --service Imagen + from __future__ import annotations diff --git a/terminal_helpers/result-imagen.json b/terminal_helpers/result-imagen.json new file mode 100644 index 0000000..6f37457 --- /dev/null +++ b/terminal_helpers/result-imagen.json @@ -0,0 +1,44 @@ +{ + "Gemini": { + "Imagen": { + "provider": "Gemini", + "service": "Imagen", + "possible_parameters": { + "resolution": [ + "1K", + "2K", + "4K" + ], + "config_number_of_images": [ + "fake_config_number_of_images_value_1", + "fake_config_number_of_images_value_2" + ], + "model": [ + "gemini-3-pro-image-preview", + "gemini-2.5-flash-image" + ] + }, + "request": { + "method": "SDK", + "endpoint": "client.models.generate_images", + "sdk_call": { + "args": [], + "kwargs": { + "model": "{{model}}", + "prompt": "{{prompt}}", + "config": { + "$call": "types.GenerateImagesConfig", + "$args": [], + "$kwargs": { + "number_of_images": "{{config_number_of_images}}", + "aspect_ratio": "{{config_aspect_ratio}}", + "image_size": "{{config_image_size}}", + "person_generation": "{{config_person_generation}}" + } + } + } + } + } + } + } +} diff --git a/terminal_helpers/result-nano.json b/terminal_helpers/result-nano.json new file mode 100644 index 0000000..aa52231 --- /dev/null +++ b/terminal_helpers/result-nano.json @@ -0,0 +1,50 @@ +{ + "Gemini": { + "Nanobanana": { + "provider": "Gemini", + "service": "Nanobanana", + "possible_parameters": { + "resolution": [ + "1K", + "2K", + "4K" + ], + "model": [ + "gemini-3-pro-image-preview", + "gemini-2.5-flash-image" + ] + }, + "request": { + "method": "SDK", + "endpoint": "client.models.generate_content", + "sdk_call": { + "args": [], + "kwargs": { + "model": "{{model}}", + "contents": [ + "{{prompt}}", + "{{reference_images}}" + ], + "config": { + "$call": "types.GenerateContentConfig", + "$args": [], + "$kwargs": { + "response_modalities": [ + "{{config_response_modalities_0}}" + ], + "image_config": { + "$call": "types.ImageConfig", + "$args": [], + "$kwargs": { + "aspect_ratio": "{{config_image_config_aspect_ratio}}", + "image_size": "{{config_image_config_image_size}}" + } + } + } + } + } + } + } + } + } +} diff --git a/terminal_helpers/result.json b/terminal_helpers/result.json new file mode 100644 index 0000000..3666024 --- /dev/null +++ b/terminal_helpers/result.json @@ -0,0 +1,144 @@ +{ + "Gemini": { + "Nanobanana": { + "provider": "Gemini", + "service": "Nanobanana", + "possible_parameters": { + "resolution": [ + "1K", + "2K", + "4K" + ], + "model": [ + "gemini-3-pro-image-preview", + "gemini-2.5-flash-image" + ] + }, + "request": { + "method": "SDK", + "endpoint": "client.models.generate_content", + "sdk_call": { + "args": [], + "kwargs": { + "model": "{{model}}", + "contents": [ + "{{prompt}}", + "{{reference_images}}" + ], + "config": { + "$call": "types.GenerateContentConfig", + "$args": [], + "$kwargs": { + "response_modalities": [ + "{{config_response_modalities_0}}" + ], + "image_config": { + "$call": "types.ImageConfig", + "$args": [], + "$kwargs": { + "aspect_ratio": "{{config_image_config_aspect_ratio}}", + "image_size": "{{config_image_config_image_size}}" + } + } + } + } + } + } + } + }, + "VEO": { + "provider": "Gemini", + "service": "VEO", + "possible_parameters": { + "durationSeconds": [ + "4", + "6", + "8" + ], + "personGeneration": [ + "allow_all", + "allow_adult", + "dont_allow" + ], + "resolution": [ + "720p", + "1080p", + "4K" + ], + "model": [ + "veo-3.0-generate", + "veo-3.0-fast-generate", + "veo-3.1-generate-preview", + "veo-3.1-generate", + "veo-3.1-fast-generate-preview", + "veo-3.1-fast-generate" + ] + }, + "request": { + "method": "SDK", + "endpoint": "client.models.generate_videos", + "sdk_call": { + "args": [], + "kwargs": { + "model": "{{model}}", + "prompt": "{{prompt}}", + "image": "{{first_image}}", + "config": { + "$call": "types.GenerateVideosConfig", + "$args": [], + "$kwargs": { + "aspectRatio": "{{config_aspectRatio}}", + "resolution": "{{config_resolution}}", + "durationSeconds": "{{config_durationSeconds}}", + "personGeneration": "{{config_personGeneration}}", + "reference_images": "{{reference_images}}", + "last_frame": "{{last_image}}" + } + } + } + } + } + }, + "Imagen": { + "provider": "Gemini", + "service": "Imagen", + "possible_parameters": { + "resolution": [ + "1K", + "2K" + ], + "model": [ + "imagen-4.0-generate-001", + "imagen-4.0-ultra-generate-001", + "imagen-4.0-fast-generate-001" + ], + "person_generation": [ + "allow_all", + "allow_adult", + "dont_allow" + ] + }, + "request": { + "method": "SDK", + "endpoint": "client.models.generate_images", + "sdk_call": { + "args": [], + "kwargs": { + "model": "{{model}}", + "prompt": "{{prompt}}", + "config": { + "$call": "types.GenerateImagesConfig", + "$args": [], + "$kwargs": { + "number_of_images": "{{config_number_of_images}}", + "aspect_ratio": "{{config_aspect_ratio}}", + "image_size": "{{config_image_size}}", + "person_generation": "{{config_person_generation}}" + } + } + } + } + } + } + } +} diff --git a/terminal_helpers/snippet-imagen.py b/terminal_helpers/snippet-imagen.py new file mode 100644 index 0000000..b7ebb30 --- /dev/null +++ b/terminal_helpers/snippet-imagen.py @@ -0,0 +1,10 @@ +response = client.models.generate_images( + model='imagen-4.0-generate-001', + prompt=prompt, + config=types.GenerateImagesConfig( + number_of_images=4, + aspect_ratio="16:9", + image_size="1K", + person_generation="allow_all", + ) +) \ No newline at end of file diff --git a/terminal_helpers/snippet.py b/terminal_helpers/snippet.py index 4e72bd3..b7ebb30 100644 --- a/terminal_helpers/snippet.py +++ b/terminal_helpers/snippet.py @@ -1,13 +1,10 @@ -response = client.models.generate_videos( - model="veo-3.1-generate-preview", +response = client.models.generate_images( + model='imagen-4.0-generate-001', prompt=prompt, - image=first_image, - config=types.GenerateVideosConfig( - aspectRatio="9:16", - resolution="720p", - durationSeconds="8s", - personGeneration="allow_all", - reference_images=reference_images, - last_frame=last_image - ), + config=types.GenerateImagesConfig( + number_of_images=4, + aspect_ratio="16:9", + image_size="1K", + person_generation="allow_all", + ) ) \ No newline at end of file