diff --git a/__init__.py b/__init__.py index 18862d2..6fee3d1 100644 --- a/__init__.py +++ b/__init__.py @@ -1,8 +1,9 @@ from .gemini.gemini_image_node import * from .gemini.gemini_image_preset_node import * +from .options.gemini_image_config_options_node import * from .ollama.ollama_vlm_node import * from .ollama.ollama_llm_node import * -from .ollama.ollama_llm_advanced_options_node import * +from .options.ollama_llm_advanced_options_node import * from typing_extensions import override class APIExtension(ComfyExtension): @@ -11,6 +12,7 @@ class APIExtension(ComfyExtension): return [ GeminiImage, GeminiImagePreset, + GeminiImageConfigOptions, OllamaVLM, OllamaLLM, OllamaLLMAdvanceOptions diff --git a/gemini/gemini_image_node.py b/gemini/gemini_image_node.py index 2e26d43..2ba16e7 100644 --- a/gemini/gemini_image_node.py +++ b/gemini/gemini_image_node.py @@ -42,11 +42,22 @@ class GeminiImage(io.ComfyNode): return ["gemini-2.5-flash-image"] @classmethod - def _load_config_credentials(cls): + def _load_config_credentials(cls, config_options=None): """ - 从config.json中加载并验证API凭据 + 从config.json中加载并验证API凭据,如果提供了config_options则优先使用 返回 (base_url, api_key, timeout) 元组 """ + # 如果提供了配置覆盖,则使用覆盖配置 + if config_options is not None: + base_url = config_options.get('base_url', '').strip() + api_key = config_options.get('api_key', '').strip() + timeout = config_options.get('timeout', 120) + + # 如果覆盖配置中有有效的 base_url 和 api_key,则直接返回 + if base_url and api_key: + return base_url, api_key, timeout + + # 否则从配置文件加载 config_path = os.path.join(os.path.dirname(__file__), '..', "config.json") # 检查配置文件是否存在 @@ -85,6 +96,15 @@ class GeminiImage(io.ComfyNode): except ValueError: timeout = 120 + # 如果有配置覆盖,则使用覆盖的值(如果提供了) + if config_options is not None: + if config_options.get('base_url', '').strip(): + base_url = config_options['base_url'].strip() + if config_options.get('api_key', '').strip(): + api_key = config_options['api_key'].strip() + if config_options.get('timeout'): + timeout = config_options['timeout'] + return base_url, api_key, timeout except Exception as e: @@ -133,6 +153,11 @@ class GeminiImage(io.ComfyNode): optional=True, tooltip="Optional image(s) to use as context for the model" ), + io.AnyType.Input( + id="config_options", + optional=True, + tooltip="Optional configuration override from YCYY Gemini Image Config Options" + ), io.String.Input( id="prompt", multiline=True, @@ -207,9 +232,9 @@ class GeminiImage(io.ComfyNode): # return [] # 执行 GeminiImage 节点 @classmethod - def execute(cls, prompt, model, aspectRatio, imageSize, enableSearch, seed,images=None) -> io.NodeOutput: - # 加载配置和凭据 - base_url, api_key, timeout = cls._load_config_credentials() + def execute(cls, prompt, model, aspectRatio, imageSize, enableSearch, seed, images=None, config_options=None) -> io.NodeOutput: + # 加载配置和凭据,如果提供了config_options则使用覆盖配置 + base_url, api_key, timeout = cls._load_config_credentials(config_options) # 获取代理配置 proxies = cls._get_proxy_config() if not prompt: diff --git a/options/gemini_image_config_options_node.py b/options/gemini_image_config_options_node.py new file mode 100644 index 0000000..475bba9 --- /dev/null +++ b/options/gemini_image_config_options_node.py @@ -0,0 +1,57 @@ +from comfy_api.latest import ComfyExtension, io + +class GeminiImageConfigOptions(io.ComfyNode): + """ + 这个节点用于覆盖 Gemini Image API 的配置参数(base_url、api_key、timeout) + """ + + @classmethod + def define_schema(cls) -> io.Schema: + return io.Schema( + node_id="YCYY_Gemini_Image_Config_Options", + display_name="Gemini Image Config Options", + category="YCYY/API/utils", + inputs=[ + io.String.Input( + id="base_url", + default="https://generativelanguage.googleapis.com/v1beta/models", + multiline=True, + tooltip="Override the base URL for Gemini Image API" + ), + io.String.Input( + id="api_key", + default="", + multiline=True, + tooltip="Override the API key for Gemini Image API" + ), + io.Int.Input( + id="timeout", + default=120, + min=1, + max=600, + tooltip="Override the request timeout in seconds" + ) + ], + outputs=[ + io.AnyType.Output( + id="config_options", + display_name="config_options", + tooltip="Configuration override for Gemini Image API" + ) + ], + description="This node provides configuration override options for Gemini Image API (base_url, api_key, timeout)." + ) + + @classmethod + def execute(cls, base_url, api_key, timeout) -> io.NodeOutput: + # 验证和清理输入 + base_url = base_url.strip() if base_url else "" + api_key = api_key.strip() if api_key else "" + + config_options = { + "base_url": base_url, + "api_key": api_key, + "timeout": timeout + } + + return io.NodeOutput(config_options) \ No newline at end of file diff --git a/ollama/ollama_llm_advanced_options_node.py b/options/ollama_llm_advanced_options_node.py similarity index 100% rename from ollama/ollama_llm_advanced_options_node.py rename to options/ollama_llm_advanced_options_node.py