Compare commits
27
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b153d355d | ||
|
|
a2643db230 | ||
|
|
1e39866b1b | ||
|
|
92670f29b4 | ||
|
|
693fec2bfb | ||
|
|
be24312c14 | ||
|
|
45d36e87b2 | ||
|
|
d098dc5e0a | ||
|
|
72d8afc3bf | ||
|
|
b34a3d3c44 | ||
|
|
8138bd48e4 | ||
|
|
49f506ba6d | ||
|
|
4dc62b0ee6 | ||
|
|
2f8ef101e9 | ||
|
|
0c5d03ba8c | ||
|
|
fe559461db | ||
|
|
a74e25e8c9 | ||
|
|
a1d99499d4 | ||
|
|
5984b64ee6 | ||
|
|
08d91ad3d3 | ||
|
|
533f2a67f6 | ||
|
|
d03e817877 | ||
|
|
5025b95afb | ||
|
|
f23100ab37 | ||
|
|
b6f3cf6d9e | ||
|
|
f9a25a573f | ||
|
|
a701eb3b02 |
@@ -8,17 +8,19 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- "pyproject.toml"
|
- "pyproject.toml"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-node:
|
publish-node:
|
||||||
name: Publish Custom Node to registry
|
name: Publish Custom Node to registry
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# if this is a forked repository. Skipping the workflow.
|
if: ${{ github.repository_owner == 'Visionatrix' }}
|
||||||
if: github.event.repository.fork == false
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Publish Custom Node
|
- name: Publish Custom Node
|
||||||
uses: Comfy-Org/publish-node-action@main
|
uses: Comfy-Org/publish-node-action@v1
|
||||||
with:
|
with:
|
||||||
## Add your own personal access token to your Github Repository secrets and reference it here.
|
## Add your own personal access token to your Github Repository secrets and reference it here.
|
||||||
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
|
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
exclude: ^(screenshots)/
|
exclude: ^(screenshots)/
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v5.0.0
|
rev: v6.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
- id: check-toml
|
- id: check-toml
|
||||||
@@ -10,23 +10,23 @@ repos:
|
|||||||
- id: mixed-line-ending
|
- id: mixed-line-ending
|
||||||
|
|
||||||
- repo: https://github.com/PyCQA/isort
|
- repo: https://github.com/PyCQA/isort
|
||||||
rev: 5.13.2
|
rev: 9.0.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
files: .
|
files: .
|
||||||
|
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||||
rev: 24.10.0
|
rev: 26.10.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
files: .
|
files: .
|
||||||
|
|
||||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||||
rev: 2.3.1
|
rev: v2.30.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyproject-fmt
|
- id: pyproject-fmt
|
||||||
|
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.6.9
|
rev: v0.16.10
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
|
|||||||
@@ -2,6 +2,48 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [1.1.2 - 2025-06-26]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `temperature` and `num_predict` optional parameters.
|
||||||
|
|
||||||
|
## [1.1.1 - 2025-06-26]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- New `gemma-3-12b-it` and `gemma-3-27b-it` models.
|
||||||
|
|
||||||
|
## [1.1.0 - 2025-06-19]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Replaced Gemini `1.5` models with Gemini `2.5` models.
|
||||||
|
|
||||||
|
## [1.0.5 - 2025-05-25]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Corrected support of the `GOOGLE_API_KEY` env variable.
|
||||||
|
|
||||||
|
## [1.0.4 - 2025-04-04]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- New `gemini-2.0-flash-lite-001` model.
|
||||||
|
|
||||||
|
## [1.0.3 - 2025-02-10]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- New `gemini-2.0-flash` model.
|
||||||
|
|
||||||
|
## [1.0.2 - 2025-02-08]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Optional `seed` parameter.
|
||||||
|
|
||||||
## [1.0.1 - 2024-10-20]
|
## [1.0.1 - 2024-10-20]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -46,8 +46,12 @@ These nodes integrate the Gemini API into ComfyUI, allowing you to send prompts
|
|||||||
- **model (CHOICE)**:
|
- **model (CHOICE)**:
|
||||||
- Selects the Gemini model to use.
|
- Selects the Gemini model to use.
|
||||||
- Options:
|
- Options:
|
||||||
- `gemini-1.5-flash-002`: Standard model.
|
- `gemma-3-12b-it`: Very small model that you can run locally or remotely on the Google infrastructure.
|
||||||
- `gemini-1.5-pro-002`: Pro model with advanced capabilities.
|
- `gemma-3-27b-it`: Medium size model that you can run locally or remotely on the Google infrastructure.
|
||||||
|
- `gemini-2.0-flash-lite-001`: Old version of the **very** fast and free model.
|
||||||
|
- `gemini-2.0-flash-001`: Old version of the fast and free model.
|
||||||
|
- `gemini-2.5-flash`: Latest stable version of the fast and free model.
|
||||||
|
- `gemini-2.5-pro`: Latest stable **Pro** model with advanced capabilities.
|
||||||
- **api_key (STRING, Optional)**:
|
- **api_key (STRING, Optional)**:
|
||||||
- Your Gemini API key.
|
- Your Gemini API key.
|
||||||
- Recommended to set via environment variable.
|
- Recommended to set via environment variable.
|
||||||
@@ -62,5 +66,9 @@ These nodes integrate the Gemini API into ComfyUI, allowing you to send prompts
|
|||||||
- **error_fallback_value (STRING, Optional, Lazy Input)**:
|
- **error_fallback_value (STRING, Optional, Lazy Input)**:
|
||||||
- Value to return if an error occurs when accessing Gemini.
|
- Value to return if an error occurs when accessing Gemini.
|
||||||
- If not set, the node will raise an exception on error.
|
- If not set, the node will raise an exception on error.
|
||||||
|
- **temperature (FLOAT, Optional, Lazy Input)**:
|
||||||
|
- Controls the randomness of the output. Any **negative value** means to use default value for model.
|
||||||
|
- **num_predict (INT, Optional, Lazy Input)**:
|
||||||
|
- The maximum number of tokens to include in a candidate, value `0` means to use default value for model.
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
|
||||||
import google.generativeai as genai
|
import google.generativeai as genai
|
||||||
from torch import Tensor
|
from torch import Tensor
|
||||||
@@ -10,12 +12,23 @@ class GeminiNode:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def INPUT_TYPES(cls): # noqa
|
def INPUT_TYPES(cls): # noqa
|
||||||
|
seed = random.randint(1, 2**31)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"required": {
|
"required": {
|
||||||
"prompt": ("STRING", {"default": "Why number 42 is important?", "multiline": True}),
|
"prompt": ("STRING", {"default": "Why number 42 is important?", "multiline": True}),
|
||||||
"safety_settings": (["BLOCK_NONE", "BLOCK_ONLY_HIGH", "BLOCK_MEDIUM_AND_ABOVE"],),
|
"safety_settings": (["BLOCK_NONE", "BLOCK_ONLY_HIGH", "BLOCK_MEDIUM_AND_ABOVE"],),
|
||||||
"response_type": (["text", "json"],),
|
"response_type": (["text", "json"],),
|
||||||
"model": (["gemini-1.5-flash-002", "gemini-1.5-pro-002"],),
|
"model": (
|
||||||
|
[
|
||||||
|
"gemma-3-12b-it",
|
||||||
|
"gemma-3-27b-it",
|
||||||
|
"gemini-2.0-flash-lite-001",
|
||||||
|
"gemini-2.0-flash-001",
|
||||||
|
"gemini-2.5-flash",
|
||||||
|
"gemini-2.5-pro",
|
||||||
|
],
|
||||||
|
),
|
||||||
},
|
},
|
||||||
"optional": {
|
"optional": {
|
||||||
"api_key": ("STRING", {}),
|
"api_key": ("STRING", {}),
|
||||||
@@ -25,6 +38,9 @@ class GeminiNode:
|
|||||||
"image_3": ("IMAGE",),
|
"image_3": ("IMAGE",),
|
||||||
"system_instruction": ("STRING", {}),
|
"system_instruction": ("STRING", {}),
|
||||||
"error_fallback_value": ("STRING", {"lazy": True}),
|
"error_fallback_value": ("STRING", {"lazy": True}),
|
||||||
|
"seed": ("INT", {"default": seed, "min": 0, "max": 2**31, "step": 1}),
|
||||||
|
"temperature": ("FLOAT", {"default": -0.05, "min": -0.05, "max": 1, "step": 0.05}),
|
||||||
|
"num_predict": ("INT", {"default": 0, "min": 0, "max": 1048576, "step": 1}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +69,9 @@ class GeminiNode:
|
|||||||
image_3: Tensor | list[Tensor] | None = None,
|
image_3: Tensor | list[Tensor] | None = None,
|
||||||
system_instruction: str | None = None,
|
system_instruction: str | None = None,
|
||||||
error_fallback_value: str | None = None,
|
error_fallback_value: str | None = None,
|
||||||
|
temperature: float | None = None,
|
||||||
|
num_predict: int | None = None,
|
||||||
|
**kwargs,
|
||||||
):
|
):
|
||||||
self.text_output = None
|
self.text_output = None
|
||||||
if not system_instruction:
|
if not system_instruction:
|
||||||
@@ -61,11 +80,18 @@ class GeminiNode:
|
|||||||
for image in [image_1, image_2, image_3]:
|
for image in [image_1, image_2, image_3]:
|
||||||
if image is not None:
|
if image is not None:
|
||||||
images_to_send.extend(images_to_pillow(image))
|
images_to_send.extend(images_to_pillow(image))
|
||||||
genai.configure(api_key=api_key, transport="rest")
|
if "GOOGLE_API_KEY" in os.environ and not api_key:
|
||||||
|
genai.configure(transport="rest")
|
||||||
|
else:
|
||||||
|
genai.configure(api_key=api_key, transport="rest")
|
||||||
model = genai.GenerativeModel(model, safety_settings=safety_settings, system_instruction=system_instruction)
|
model = genai.GenerativeModel(model, safety_settings=safety_settings, system_instruction=system_instruction)
|
||||||
generation_config = genai.GenerationConfig(
|
generation_config = genai.GenerationConfig(
|
||||||
response_mime_type="application/json" if response_type == "json" else "text/plain"
|
response_mime_type="application/json" if response_type == "json" else "text/plain"
|
||||||
)
|
)
|
||||||
|
if temperature is not None and temperature >= 0:
|
||||||
|
generation_config.temperature = temperature
|
||||||
|
if num_predict is not None and num_predict > 0:
|
||||||
|
generation_config.max_output_tokens = num_predict
|
||||||
try:
|
try:
|
||||||
with temporary_env_var("HTTP_PROXY", proxy), temporary_env_var("HTTPS_PROXY", proxy):
|
with temporary_env_var("HTTP_PROXY", proxy), temporary_env_var("HTTPS_PROXY", proxy):
|
||||||
response = model.generate_content([prompt, *images_to_send], generation_config=generation_config)
|
response = model.generate_content([prompt, *images_to_send], generation_config=generation_config)
|
||||||
|
|||||||
+4
-2
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "comfyui-gemini"
|
name = "comfyui-gemini"
|
||||||
version = "1.0.1"
|
version = "1.1.2"
|
||||||
description = "Nodes for Google Gemini API, focusing on backward compatibility and stability within ComfyUI."
|
description = "Nodes for Google Gemini API, focusing on backward compatibility and stability within ComfyUI."
|
||||||
license = { file = "LICENSE" }
|
license = { file = "LICENSE" }
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
@@ -10,8 +10,10 @@ classifiers = [
|
|||||||
"Programming Language :: Python :: 3.11",
|
"Programming Language :: Python :: 3.11",
|
||||||
"Programming Language :: Python :: 3.12",
|
"Programming Language :: Python :: 3.12",
|
||||||
"Programming Language :: Python :: 3.13",
|
"Programming Language :: Python :: 3.13",
|
||||||
|
"Programming Language :: Python :: 3.14",
|
||||||
|
"Programming Language :: Python :: 3.15",
|
||||||
]
|
]
|
||||||
dependencies = [ "google-generativeai>=0.8.3" ]
|
dependencies = [ "google-generativeai>=0.8.5" ]
|
||||||
urls.Changelog = "https://github.com/Visionatrix/ComfyUI-Gemini/blob/main/CHANGELOG.md"
|
urls.Changelog = "https://github.com/Visionatrix/ComfyUI-Gemini/blob/main/CHANGELOG.md"
|
||||||
urls.Repository = "https://github.com/Visionatrix/ComfyUI-Gemini"
|
urls.Repository = "https://github.com/Visionatrix/ComfyUI-Gemini"
|
||||||
urls.Source = "https://github.com/Visionatrix/ComfyUI-Gemini"
|
urls.Source = "https://github.com/Visionatrix/ComfyUI-Gemini"
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ def temporary_env_var(key: str, new_value: str | None):
|
|||||||
del os.environ[key]
|
del os.environ[key]
|
||||||
|
|
||||||
|
|
||||||
def images_to_pillow(images: Tensor | list[Tensor]) -> list[Image]:
|
def images_to_pillow(images: Tensor | list[Tensor]) -> list[Image.Image]:
|
||||||
pillow_images = []
|
pillow_images = []
|
||||||
for _bn, image in enumerate(images):
|
for _bn, image in enumerate(images):
|
||||||
i = 255.0 * image.cpu().numpy()
|
i = 255.0 * image.cpu().numpy()
|
||||||
|
|||||||
Reference in New Issue
Block a user