add grok image api
This commit is contained in:
+3
-1
@@ -2,6 +2,7 @@ from comfy_api.latest import ComfyExtension, io
|
||||
from typing_extensions import override
|
||||
|
||||
from .gemini.gemini_image_node import *
|
||||
from .grok.grok_image_node import *
|
||||
from .gemini.gemini_image_preset_node import *
|
||||
from .gemini.gemini_tts_node import *
|
||||
from .gemini.gemini_tts_multi_node import *
|
||||
@@ -27,7 +28,8 @@ class APIExtension(ComfyExtension):
|
||||
@override
|
||||
async def get_node_list(self) -> list[type[io.ComfyNode]]:
|
||||
return [
|
||||
GeminiImage,
|
||||
GeminiImage,
|
||||
GrokImage,
|
||||
GeminiTTS,
|
||||
GeminiTTSMulti,
|
||||
GeminiSTT,
|
||||
|
||||
+25
-7
@@ -6,7 +6,10 @@
|
||||
"api_key": "put your key here",
|
||||
"timeout": 120,
|
||||
"api_protocol": "openai-completions",
|
||||
"models": ["gpt-4o", "gpt-5"]
|
||||
"models": [
|
||||
"gpt-4o",
|
||||
"gpt-5"
|
||||
]
|
||||
},
|
||||
{
|
||||
"api-name": "OpenAI Responses",
|
||||
@@ -14,14 +17,29 @@
|
||||
"api_key": "put your key here",
|
||||
"timeout": 120,
|
||||
"api_protocol": "openai-responses",
|
||||
"models": ["gpt-5"]
|
||||
"models": [
|
||||
"gpt-5"
|
||||
]
|
||||
}
|
||||
],
|
||||
"skills": {
|
||||
"paths": ["skills"],
|
||||
"paths": [
|
||||
"skills"
|
||||
],
|
||||
"allow_call": false
|
||||
},
|
||||
"gemini-image":{
|
||||
"grok-image": {
|
||||
"base_url": "https://api.x.ai/v1",
|
||||
"api_key": "put your key here",
|
||||
"timeout": 120,
|
||||
"models": [
|
||||
"grok-imagine-image-2.0",
|
||||
"grok-imagine-image-quality",
|
||||
"grok-imagine-image-pro",
|
||||
"grok-imagine-image"
|
||||
]
|
||||
},
|
||||
"gemini-image": {
|
||||
"base_url": "https://generativelanguage.googleapis.com/v1beta/models",
|
||||
"api_key": "put your key here",
|
||||
"timeout": 120,
|
||||
@@ -31,7 +49,7 @@
|
||||
"gemini-3.1-flash-image-preview"
|
||||
]
|
||||
},
|
||||
"gemini-tts": {
|
||||
"gemini-tts": {
|
||||
"base_url": "https://generativelanguage.googleapis.com/v1beta/models",
|
||||
"api_key": "put your key here",
|
||||
"timeout": 120,
|
||||
@@ -96,9 +114,9 @@
|
||||
"FireRedTeam/FireRed-Image-Edit-1.1"
|
||||
]
|
||||
},
|
||||
"proxy":{
|
||||
"proxy": {
|
||||
"enable": false,
|
||||
"http": "",
|
||||
"https": "http://127.0.0.1:7890"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,525 @@
|
||||
import os
|
||||
import json
|
||||
import base64
|
||||
import requests
|
||||
import torch
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
from typing import Optional, List, Dict, Any, Tuple
|
||||
from comfy_api.latest import ComfyExtension, io
|
||||
from ..utils.image_utils import tensor_to_base64_string
|
||||
from ..utils.config_utils import get_config_section
|
||||
|
||||
|
||||
DEFAULT_MODELS = [
|
||||
"grok-imagine-image-2.0",
|
||||
"grok-imagine-image-quality",
|
||||
"grok-imagine-image-pro",
|
||||
"grok-imagine-image"
|
||||
]
|
||||
|
||||
|
||||
class GrokImage(io.ComfyNode):
|
||||
"""
|
||||
这个节点使用 xAI Grok Image API 生成或者修改图片
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _load_models_from_config(cls) -> List[str]:
|
||||
"""
|
||||
从 config.json 中加载模型列表
|
||||
如果获取不到,返回默认模型列表
|
||||
"""
|
||||
try:
|
||||
config_path = os.path.join(os.path.dirname(__file__), '..', "config.json")
|
||||
if not os.path.exists(config_path):
|
||||
return DEFAULT_MODELS
|
||||
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
|
||||
if 'grok-image' in config and 'models' in config['grok-image']:
|
||||
models = config['grok-image']['models']
|
||||
if isinstance(models, list) and len(models) > 0:
|
||||
return models
|
||||
|
||||
return DEFAULT_MODELS
|
||||
except Exception:
|
||||
return DEFAULT_MODELS
|
||||
|
||||
@classmethod
|
||||
def _load_config_credentials(cls, config_options: Optional[dict] = None) -> Tuple[str, str, int]:
|
||||
"""
|
||||
从 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")
|
||||
|
||||
# 检查配置文件是否存在
|
||||
if not os.path.exists(config_path):
|
||||
raise FileNotFoundError(f"Config file not found: {config_path}")
|
||||
|
||||
try:
|
||||
with open(config_path, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
|
||||
# 检查是否存在 grok-image 配置段
|
||||
if 'grok-image' not in config:
|
||||
raise ValueError("Missing 'grok-image' section in config file")
|
||||
|
||||
grok_config = config['grok-image']
|
||||
|
||||
# 获取并验证 base_url (默认 https://api.x.ai/v1)
|
||||
base_url = grok_config.get('base_url', 'https://api.x.ai/v1')
|
||||
base_url = base_url.strip() if isinstance(base_url, str) else str(base_url).strip()
|
||||
if not base_url:
|
||||
base_url = "https://api.x.ai/v1"
|
||||
|
||||
# 获取并验证 api_key
|
||||
if 'api_key' not in grok_config:
|
||||
raise ValueError("Missing 'api_key' in grok-image section")
|
||||
api_key = grok_config['api_key'].strip() if isinstance(grok_config['api_key'], str) else str(grok_config['api_key']).strip()
|
||||
if not api_key:
|
||||
raise ValueError("api_key cannot be empty")
|
||||
|
||||
# 获取 timeout 参数,默认值为 120 秒
|
||||
timeout = grok_config.get('timeout', 120)
|
||||
if isinstance(timeout, str):
|
||||
try:
|
||||
timeout = int(timeout)
|
||||
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:
|
||||
raise ValueError(f"Config loading error: {str(e)}")
|
||||
|
||||
@classmethod
|
||||
def _get_proxy_config(cls, proxy_options: Optional[dict] = None) -> Optional[Dict[str, str]]:
|
||||
"""
|
||||
从 config.json 中获取代理配置,如果提供了 proxy_options 则优先使用
|
||||
返回 proxies 字典或 None
|
||||
"""
|
||||
# 如果提供了代理覆盖配置
|
||||
if proxy_options is not None:
|
||||
if not proxy_options.get('enable', False):
|
||||
return None
|
||||
|
||||
proxies = {}
|
||||
if proxy_options.get('http', '').strip():
|
||||
proxies['http'] = proxy_options['http'].strip()
|
||||
if proxy_options.get('https', '').strip():
|
||||
proxies['https'] = proxy_options['https'].strip()
|
||||
|
||||
return proxies if proxies else None
|
||||
|
||||
# 否则从配置文件加载
|
||||
try:
|
||||
proxy_config = get_config_section('proxy')
|
||||
if not proxy_config or not proxy_config.get('enable', False):
|
||||
return None
|
||||
|
||||
proxies = {}
|
||||
if proxy_config.get('http'):
|
||||
proxies['http'] = proxy_config['http']
|
||||
if proxy_config.get('https'):
|
||||
proxies['https'] = proxy_config['https']
|
||||
|
||||
return proxies if proxies else None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def define_schema(cls) -> io.Schema:
|
||||
"""
|
||||
返回 GrokImage 节点 schema
|
||||
"""
|
||||
model_options = cls._load_models_from_config()
|
||||
default_model = model_options[0]
|
||||
|
||||
return io.Schema(
|
||||
node_id="YCYY_Grok_Image_API",
|
||||
display_name="Grok Image API",
|
||||
category="YCYY/API/image",
|
||||
inputs=[
|
||||
io.Image.Input(
|
||||
id="images",
|
||||
optional=True,
|
||||
tooltip="Optional image(s) for image-to-image editing. Grok supports up to 3 reference images (1 for pro model)."
|
||||
),
|
||||
io.AnyType.Input(
|
||||
id="config_options",
|
||||
optional=True,
|
||||
tooltip="Optional configuration override from YCYY API Config Options"
|
||||
),
|
||||
io.AnyType.Input(
|
||||
id="proxy_options",
|
||||
optional=True,
|
||||
tooltip="Optional proxy configuration override from YCYY API Proxy Options"
|
||||
),
|
||||
io.String.Input(
|
||||
id="prompt",
|
||||
multiline=True,
|
||||
tooltip="The text prompt used to generate or edit the image"
|
||||
),
|
||||
io.Combo.Input(
|
||||
id="model",
|
||||
options=model_options,
|
||||
default=default_model,
|
||||
tooltip="Grok image model"
|
||||
),
|
||||
io.Combo.Input(
|
||||
id="aspect_ratio",
|
||||
options=[
|
||||
"auto",
|
||||
"1:1",
|
||||
"2:3",
|
||||
"3:2",
|
||||
"3:4",
|
||||
"4:3",
|
||||
"9:16",
|
||||
"16:9",
|
||||
"9:19.5",
|
||||
"19.5:9",
|
||||
"9:20",
|
||||
"20:9",
|
||||
"1:2",
|
||||
"2:1"
|
||||
],
|
||||
default="auto",
|
||||
tooltip="Aspect ratio of the output image. 'auto' matches input image in edit mode or generates 1:1."
|
||||
),
|
||||
io.Combo.Input(
|
||||
id="resolution",
|
||||
options=[
|
||||
"1K",
|
||||
"2K"
|
||||
],
|
||||
default="1K",
|
||||
tooltip="Resolution of the output image (1K or 2K)."
|
||||
),
|
||||
io.Combo.Input(
|
||||
id="quality",
|
||||
options=[
|
||||
"default",
|
||||
"medium",
|
||||
"low"
|
||||
],
|
||||
default="medium",
|
||||
tooltip="Quality level, supported only by the grok-imagine-image-2.0 model."
|
||||
),
|
||||
io.Int.Input(
|
||||
id="number_of_images",
|
||||
default=1,
|
||||
min=1,
|
||||
max=10,
|
||||
step=1,
|
||||
tooltip="Number of images to generate (1 to 10)."
|
||||
),
|
||||
io.Int.Input(
|
||||
id="seed",
|
||||
min=0,
|
||||
max=0xFFFFFFFFFFFFFFFF,
|
||||
default=0,
|
||||
control_after_generate=True,
|
||||
tooltip="Random seed for generation."
|
||||
)
|
||||
],
|
||||
outputs=[
|
||||
io.Image.Output(),
|
||||
io.String.Output()
|
||||
],
|
||||
description="This node uses the xAI Grok Image API to generate or edit images."
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def execute(
|
||||
cls,
|
||||
prompt: str,
|
||||
model: str,
|
||||
aspect_ratio: str,
|
||||
resolution: str,
|
||||
quality: str,
|
||||
number_of_images: int,
|
||||
seed: int,
|
||||
images: Optional[torch.Tensor] = None,
|
||||
config_options: Optional[dict] = None,
|
||||
proxy_options: Optional[dict] = None
|
||||
) -> io.NodeOutput:
|
||||
# 加载配置和凭据,如果提供了 config_options 则使用覆盖配置
|
||||
base_url, api_key, timeout = cls._load_config_credentials(config_options)
|
||||
# 获取代理配置,如果提供了 proxy_options 则使用覆盖配置
|
||||
proxies = cls._get_proxy_config(proxy_options)
|
||||
|
||||
if not prompt or not prompt.strip():
|
||||
raise ValueError("prompt cannot be empty")
|
||||
|
||||
clean_base_url = base_url.rstrip("/")
|
||||
if clean_base_url.endswith("/images/generations") or clean_base_url.endswith("/images/edits"):
|
||||
clean_base_url = clean_base_url.rsplit("/images", 1)[0]
|
||||
elif clean_base_url.endswith("/images"):
|
||||
clean_base_url = clean_base_url.rsplit("/images", 1)[0]
|
||||
|
||||
gen_url = f"{clean_base_url}/images/generations"
|
||||
edit_url = f"{clean_base_url}/images/edits"
|
||||
|
||||
if images is not None:
|
||||
return cls._edit_images(
|
||||
api_url=edit_url,
|
||||
api_key=api_key,
|
||||
prompt=prompt,
|
||||
model=model,
|
||||
aspect_ratio=aspect_ratio,
|
||||
resolution=resolution,
|
||||
quality=quality,
|
||||
number_of_images=number_of_images,
|
||||
seed=seed,
|
||||
images=images,
|
||||
timeout=timeout,
|
||||
proxies=proxies
|
||||
)
|
||||
else:
|
||||
return cls._generate_images(
|
||||
api_url=gen_url,
|
||||
api_key=api_key,
|
||||
prompt=prompt,
|
||||
model=model,
|
||||
aspect_ratio=aspect_ratio,
|
||||
resolution=resolution,
|
||||
quality=quality,
|
||||
number_of_images=number_of_images,
|
||||
seed=seed,
|
||||
timeout=timeout,
|
||||
proxies=proxies
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _generate_images(
|
||||
cls,
|
||||
api_url: str,
|
||||
api_key: str,
|
||||
prompt: str,
|
||||
model: str,
|
||||
aspect_ratio: str,
|
||||
resolution: str,
|
||||
quality: str,
|
||||
number_of_images: int,
|
||||
seed: int,
|
||||
timeout: int,
|
||||
proxies: Optional[dict] = None
|
||||
) -> io.NodeOutput:
|
||||
headers = {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
payload = {
|
||||
"model": model,
|
||||
"prompt": prompt,
|
||||
"n": number_of_images,
|
||||
"seed": seed,
|
||||
"response_format": "b64_json",
|
||||
"resolution": resolution.lower() if resolution else "1k"
|
||||
}
|
||||
if aspect_ratio != "auto":
|
||||
payload["aspect_ratio"] = aspect_ratio
|
||||
if quality and quality != "default":
|
||||
payload["quality"] = quality
|
||||
|
||||
try:
|
||||
resp = requests.post(api_url, headers=headers, json=payload, timeout=timeout, proxies=proxies)
|
||||
return cls._parse_response(resp, model=model, timeout=timeout, proxies=proxies)
|
||||
except Exception as e:
|
||||
empty_image = cls._create_empty_image()
|
||||
err_info = {
|
||||
"success": False,
|
||||
"message": f"The API request failed. Please check if the interface address and key are correct: {str(e)}"
|
||||
}
|
||||
return io.NodeOutput(empty_image, json.dumps(err_info, ensure_ascii=False))
|
||||
|
||||
@classmethod
|
||||
def _edit_images(
|
||||
cls,
|
||||
api_url: str,
|
||||
api_key: str,
|
||||
prompt: str,
|
||||
model: str,
|
||||
aspect_ratio: str,
|
||||
resolution: str,
|
||||
quality: str,
|
||||
number_of_images: int,
|
||||
seed: int,
|
||||
images: torch.Tensor,
|
||||
timeout: int,
|
||||
proxies: Optional[dict] = None
|
||||
) -> io.NodeOutput:
|
||||
headers = {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
input_images = []
|
||||
total_imgs = images.shape[0] if len(images.shape) >= 4 else 1
|
||||
max_imgs = 1 if "pro" in model else 3
|
||||
num_to_take = min(total_imgs, max_imgs)
|
||||
|
||||
for idx in range(num_to_take):
|
||||
img_tensor = images[idx].unsqueeze(0) if len(images.shape) >= 4 else images.unsqueeze(0)
|
||||
b64_str = tensor_to_base64_string(img_tensor, mime_type="image/png")
|
||||
input_images.append({
|
||||
"url": f"data:image/png;base64,{b64_str}"
|
||||
})
|
||||
|
||||
payload = {
|
||||
"model": model,
|
||||
"prompt": prompt,
|
||||
"images": input_images,
|
||||
"n": number_of_images,
|
||||
"seed": seed,
|
||||
"response_format": "b64_json",
|
||||
"resolution": resolution.lower() if resolution else "1k"
|
||||
}
|
||||
if aspect_ratio != "auto":
|
||||
payload["aspect_ratio"] = aspect_ratio
|
||||
|
||||
try:
|
||||
resp = requests.post(api_url, headers=headers, json=payload, timeout=timeout, proxies=proxies)
|
||||
return cls._parse_response(resp, model=model, timeout=timeout, proxies=proxies)
|
||||
except Exception as e:
|
||||
empty_image = cls._create_empty_image()
|
||||
err_info = {
|
||||
"success": False,
|
||||
"message": f"The API request failed. Please check if the interface address and key are correct: {str(e)}"
|
||||
}
|
||||
return io.NodeOutput(empty_image, json.dumps(err_info, ensure_ascii=False))
|
||||
|
||||
@classmethod
|
||||
def _parse_response(
|
||||
cls,
|
||||
resp: requests.Response,
|
||||
model: str = "",
|
||||
timeout: int = 120,
|
||||
proxies: Optional[dict] = None
|
||||
) -> io.NodeOutput:
|
||||
# 检查 HTTP 状态码
|
||||
if resp.status_code != 200:
|
||||
empty_image = cls._create_empty_image()
|
||||
err_info = {
|
||||
"success": False,
|
||||
"message": f"API request returns an error. status_code: {resp.status_code}, error_reason: {resp.text}"
|
||||
}
|
||||
return io.NodeOutput(empty_image, json.dumps(err_info, ensure_ascii=False))
|
||||
|
||||
# 检查返回内容是否为空
|
||||
if not resp.text.strip():
|
||||
empty_image = cls._create_empty_image()
|
||||
err_info = {
|
||||
"success": False,
|
||||
"message": "The API returns an empty content"
|
||||
}
|
||||
return io.NodeOutput(empty_image, json.dumps(err_info, ensure_ascii=False))
|
||||
|
||||
try:
|
||||
data = resp.json()
|
||||
except Exception as json_exception:
|
||||
empty_image = cls._create_empty_image()
|
||||
err_info = {
|
||||
"success": False,
|
||||
"message": f"The API returned a JSON parsing failure: {str(json_exception)}"
|
||||
}
|
||||
return io.NodeOutput(empty_image, json.dumps(err_info, ensure_ascii=False))
|
||||
|
||||
# 提取图像数据列表
|
||||
items = data.get("data", [])
|
||||
if not items:
|
||||
empty_image = cls._create_empty_image()
|
||||
err_info = {
|
||||
"success": False,
|
||||
"message": "Image data not found in response",
|
||||
"raw_response": data
|
||||
}
|
||||
return io.NodeOutput(empty_image, json.dumps(err_info, ensure_ascii=False))
|
||||
|
||||
image_tensors = []
|
||||
revised_prompts = []
|
||||
for item in items:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
if item.get("revised_prompt"):
|
||||
revised_prompts.append(item["revised_prompt"])
|
||||
|
||||
b64_json = item.get("b64_json")
|
||||
image_url = item.get("url")
|
||||
|
||||
if b64_json:
|
||||
try:
|
||||
image_bytes = base64.b64decode(b64_json)
|
||||
pil_image = Image.open(BytesIO(image_bytes)).convert("RGB")
|
||||
img_np = np.array(pil_image).astype(np.float32) / 255.0
|
||||
img_tensor = torch.from_numpy(img_np).unsqueeze(0)
|
||||
image_tensors.append(img_tensor)
|
||||
except Exception:
|
||||
pass
|
||||
elif image_url:
|
||||
try:
|
||||
img_resp = requests.get(image_url, timeout=timeout, proxies=proxies)
|
||||
if img_resp.status_code == 200:
|
||||
pil_image = Image.open(BytesIO(img_resp.content)).convert("RGB")
|
||||
img_np = np.array(pil_image).astype(np.float32) / 255.0
|
||||
img_tensor = torch.from_numpy(img_np).unsqueeze(0)
|
||||
image_tensors.append(img_tensor)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not image_tensors:
|
||||
empty_image = cls._create_empty_image()
|
||||
err_info = {
|
||||
"success": False,
|
||||
"message": "Failed to decode or download any image from response",
|
||||
"raw_response": data
|
||||
}
|
||||
return io.NodeOutput(empty_image, json.dumps(err_info, ensure_ascii=False))
|
||||
|
||||
if len(image_tensors) == 1:
|
||||
final_tensor = image_tensors[0]
|
||||
else:
|
||||
final_tensor = torch.cat(image_tensors, dim=0)
|
||||
|
||||
usage = data.get("usage", {})
|
||||
info = {
|
||||
"success": True,
|
||||
"model": model,
|
||||
"created": data.get("created"),
|
||||
"usage": usage,
|
||||
"revised_prompts": revised_prompts
|
||||
}
|
||||
return io.NodeOutput(final_tensor, json.dumps(info, ensure_ascii=False, indent=2))
|
||||
|
||||
@classmethod
|
||||
def _create_empty_image(cls) -> torch.Tensor:
|
||||
"""创建空图像"""
|
||||
try:
|
||||
return torch.zeros(1, 512, 512, 3, dtype=torch.float32)
|
||||
except Exception:
|
||||
return None
|
||||
+179
-35
@@ -3,44 +3,101 @@
|
||||
"display_name": "OpenAI Text API",
|
||||
"description": "OpenAI and OpenAI-compatible text, image and video API.",
|
||||
"inputs": {
|
||||
"api_name": {"name": "api_name"},
|
||||
"model": {"name": "model"},
|
||||
"system_prompt": {"name": "system_prompt"},
|
||||
"user_prompt": {"name": "user_prompt"},
|
||||
"persist_context": {"name": "persist_context", "tooltip": "Persist chat context between calls"},
|
||||
"clear_history": {"name": "clear_history", "tooltip": "Clear the current conversation history"},
|
||||
"stream": {"name": "stream", "tooltip": "If true, the model response is streamed to the client as it is generated using server-sent events (SSE)."},
|
||||
"images": {"name": "images", "tooltip": "Optional image input"},
|
||||
"videos": {"name": "videos", "tooltip": "Optional video input; unsupported APIs return an error"},
|
||||
"config_options": {"name": "config_options", "tooltip": "Configuration override"},
|
||||
"proxy_options": {"name": "proxy_options", "tooltip": "Proxy override"},
|
||||
"advanced_options": {"name": "advanced_options", "tooltip": "Advanced model options"},
|
||||
"skill_options": {"name": "skill_options", "tooltip": "Optional progressive Skill configuration from OpenAI Text Skill Options"}
|
||||
"api_name": {
|
||||
"name": "api_name"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"system_prompt": {
|
||||
"name": "system_prompt"
|
||||
},
|
||||
"user_prompt": {
|
||||
"name": "user_prompt"
|
||||
},
|
||||
"persist_context": {
|
||||
"name": "persist_context",
|
||||
"tooltip": "Persist chat context between calls"
|
||||
},
|
||||
"clear_history": {
|
||||
"name": "clear_history",
|
||||
"tooltip": "Clear the current conversation history"
|
||||
},
|
||||
"stream": {
|
||||
"name": "stream",
|
||||
"tooltip": "If true, the model response is streamed to the client as it is generated using server-sent events (SSE)."
|
||||
},
|
||||
"images": {
|
||||
"name": "images",
|
||||
"tooltip": "Optional image input"
|
||||
},
|
||||
"videos": {
|
||||
"name": "videos",
|
||||
"tooltip": "Optional video input; unsupported APIs return an error"
|
||||
},
|
||||
"config_options": {
|
||||
"name": "config_options",
|
||||
"tooltip": "Configuration override"
|
||||
},
|
||||
"proxy_options": {
|
||||
"name": "proxy_options",
|
||||
"tooltip": "Proxy override"
|
||||
},
|
||||
"advanced_options": {
|
||||
"name": "advanced_options",
|
||||
"tooltip": "Advanced model options"
|
||||
},
|
||||
"skill_options": {
|
||||
"name": "skill_options",
|
||||
"tooltip": "Optional progressive Skill configuration from OpenAI Text Skill Options"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {"name": "Result"},
|
||||
"1": {"name": "Conversation", "tooltip": "Full redacted Pi Skill Agent ledger for Skill calls"},
|
||||
"2": {"name": "Skill Trace"}
|
||||
"0": {
|
||||
"name": "Result"
|
||||
},
|
||||
"1": {
|
||||
"name": "Conversation",
|
||||
"tooltip": "Full redacted Pi Skill Agent ledger for Skill calls"
|
||||
},
|
||||
"2": {
|
||||
"name": "Skill Trace"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Preview_API_Result": {
|
||||
"display_name": "Preview API Result",
|
||||
"description": "Render text as a Markdown preview with copy support.",
|
||||
"inputs": {
|
||||
"source": {"name": "source", "tooltip": "Markdown or plain text to preview"}
|
||||
"source": {
|
||||
"name": "source",
|
||||
"tooltip": "Markdown or plain text to preview"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {"name": "text"}
|
||||
"0": {
|
||||
"name": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_OpenAI_Text_Skill_Options": {
|
||||
"display_name": "OpenAI Text Skill Options",
|
||||
"description": "Load a local SKILL.md package for progressive use by OpenAI Text API.",
|
||||
"inputs": {
|
||||
"skill_name": {"name": "skill_name", "tooltip": "Select a configured local Skill"},
|
||||
"description": {"name": "Skill description", "tooltip": "Read-only description of the selected Skill"}
|
||||
"skill_name": {
|
||||
"name": "skill_name",
|
||||
"tooltip": "Select a configured local Skill"
|
||||
},
|
||||
"description": {
|
||||
"name": "Skill description",
|
||||
"tooltip": "Read-only description of the selected Skill"
|
||||
}
|
||||
},
|
||||
"outputs": {"0": {"name": "skill_options"}}
|
||||
"outputs": {
|
||||
"0": {
|
||||
"name": "skill_options"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_OpenAI_Text_Advanced_Options": {
|
||||
"display_name": "OpenAI Text Advanced Options",
|
||||
@@ -51,7 +108,11 @@
|
||||
"tooltip": "A JSON object containing protocol/API-specific request parameters. Example:\n{\n \"temperature\": 0.7,\n \"reasoning\": {\n \"effort\": \"medium\"\n }\n}"
|
||||
}
|
||||
},
|
||||
"outputs": {"0": {"name": "advanced_options"}}
|
||||
"outputs": {
|
||||
"0": {
|
||||
"name": "advanced_options"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Gemini_Image_API": {
|
||||
"display_name": "Gemini Image API",
|
||||
@@ -100,6 +161,60 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Grok_Image_API": {
|
||||
"display_name": "Grok Image API",
|
||||
"description": "This node uses the xAI Grok Image API to generate or edit images.",
|
||||
"inputs": {
|
||||
"images": {
|
||||
"name": "images",
|
||||
"tooltip": "Optional reference image(s) for editing. Up to 3 images (1 for pro model)."
|
||||
},
|
||||
"config_options": {
|
||||
"name": "config_options",
|
||||
"tooltip": "Optional configuration override from YCYY API Config Options"
|
||||
},
|
||||
"proxy_options": {
|
||||
"name": "proxy_options",
|
||||
"tooltip": "Optional proxy configuration override from YCYY API Proxy Options"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "The prompt used to generate or edit the image"
|
||||
},
|
||||
"model": {
|
||||
"name": "model",
|
||||
"tooltip": "Grok image model"
|
||||
},
|
||||
"aspect_ratio": {
|
||||
"name": "aspect_ratio",
|
||||
"tooltip": "Aspect ratio of the generated image. 'auto' matches input image in edit mode or generates 1:1."
|
||||
},
|
||||
"resolution": {
|
||||
"name": "resolution",
|
||||
"tooltip": "Resolution of the output image (1K or 2K)."
|
||||
},
|
||||
"quality": {
|
||||
"name": "quality",
|
||||
"tooltip": "Quality level, supported only by the grok-imagine-image-2.0 model."
|
||||
},
|
||||
"number_of_images": {
|
||||
"name": "number_of_images",
|
||||
"tooltip": "Number of images to generate (1 to 10)."
|
||||
},
|
||||
"seed": {
|
||||
"name": "seed",
|
||||
"tooltip": "Seed to use for generation."
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"name": "Image"
|
||||
},
|
||||
"1": {
|
||||
"name": "Info"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Ollama_VLM_API": {
|
||||
"display_name": "Ollama VLM API",
|
||||
"description": "This node uses the Ollama VLM model for image reasoning and analysis.",
|
||||
@@ -475,20 +590,49 @@
|
||||
"display_name": "ModelScope Image Edit API",
|
||||
"description": "This node uses the ModelScope API to edit an input image.",
|
||||
"inputs": {
|
||||
"image": {"name": "image", "tooltip": "Input image to edit"},
|
||||
"config_options": {"name": "config_options", "tooltip": "Optional configuration override from YCYY API Config Options"},
|
||||
"proxy_options": {"name": "proxy_options", "tooltip": "Optional proxy configuration override from YCYY API Proxy Options"},
|
||||
"prompt": {"name": "prompt", "tooltip": "Image editing instruction"},
|
||||
"negative_prompt": {"name": "negative_prompt", "tooltip": "Negative prompt"},
|
||||
"model": {"name": "model"},
|
||||
"width": {"name": "width"},
|
||||
"height": {"name": "height"},
|
||||
"steps": {"name": "steps"},
|
||||
"guidance": {"name": "guidance"}
|
||||
"image": {
|
||||
"name": "image",
|
||||
"tooltip": "Input image to edit"
|
||||
},
|
||||
"config_options": {
|
||||
"name": "config_options",
|
||||
"tooltip": "Optional configuration override from YCYY API Config Options"
|
||||
},
|
||||
"proxy_options": {
|
||||
"name": "proxy_options",
|
||||
"tooltip": "Optional proxy configuration override from YCYY API Proxy Options"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "Image editing instruction"
|
||||
},
|
||||
"negative_prompt": {
|
||||
"name": "negative_prompt",
|
||||
"tooltip": "Negative prompt"
|
||||
},
|
||||
"model": {
|
||||
"name": "model"
|
||||
},
|
||||
"width": {
|
||||
"name": "width"
|
||||
},
|
||||
"height": {
|
||||
"name": "height"
|
||||
},
|
||||
"steps": {
|
||||
"name": "steps"
|
||||
},
|
||||
"guidance": {
|
||||
"name": "guidance"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {"name": "Image"},
|
||||
"1": {"name": "String"}
|
||||
"0": {
|
||||
"name": "Image"
|
||||
},
|
||||
"1": {
|
||||
"name": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Image_Compare": {
|
||||
@@ -505,4 +649,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+209
-65
@@ -3,44 +3,101 @@
|
||||
"display_name": "OpenAI 文本 API",
|
||||
"description": "支持 OpenAI 及兼容接口的文本、图像和视频请求。",
|
||||
"inputs": {
|
||||
"api_name": {"name": "API 名称"},
|
||||
"model": {"name": "模型"},
|
||||
"system_prompt": {"name": "系统提示词"},
|
||||
"user_prompt": {"name": "用户提示词"},
|
||||
"persist_context": {"name": "保持上下文", "tooltip": "在多次调用之间保持对话上下文"},
|
||||
"clear_history": {"name": "清除历史", "tooltip": "清除当前会话历史"},
|
||||
"stream": {"name": "流式输出", "tooltip": "设为 true 时,模型响应会在生成过程中通过服务器发送事件(SSE)流式传输到客户端。"},
|
||||
"images": {"name": "图像", "tooltip": "可选图像输入"},
|
||||
"videos": {"name": "视频", "tooltip": "可选视频输入;不支持视频的接口会返回错误"},
|
||||
"config_options": {"name": "配置选项", "tooltip": "配置覆盖"},
|
||||
"proxy_options": {"name": "代理选项", "tooltip": "代理覆盖"},
|
||||
"advanced_options": {"name": "高级选项", "tooltip": "模型高级参数"},
|
||||
"skill_options": {"name": "Skill 选项", "tooltip": "来自 OpenAI 文本 Skill 选项节点的可选渐进式 Skill 配置"}
|
||||
"api_name": {
|
||||
"name": "API 名称"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型"
|
||||
},
|
||||
"system_prompt": {
|
||||
"name": "系统提示词"
|
||||
},
|
||||
"user_prompt": {
|
||||
"name": "用户提示词"
|
||||
},
|
||||
"persist_context": {
|
||||
"name": "保持上下文",
|
||||
"tooltip": "在多次调用之间保持对话上下文"
|
||||
},
|
||||
"clear_history": {
|
||||
"name": "清除历史",
|
||||
"tooltip": "清除当前会话历史"
|
||||
},
|
||||
"stream": {
|
||||
"name": "流式输出",
|
||||
"tooltip": "设为 true 时,模型响应会在生成过程中通过服务器发送事件(SSE)流式传输到客户端。"
|
||||
},
|
||||
"images": {
|
||||
"name": "图像",
|
||||
"tooltip": "可选图像输入"
|
||||
},
|
||||
"videos": {
|
||||
"name": "视频",
|
||||
"tooltip": "可选视频输入;不支持视频的接口会返回错误"
|
||||
},
|
||||
"config_options": {
|
||||
"name": "配置选项",
|
||||
"tooltip": "配置覆盖"
|
||||
},
|
||||
"proxy_options": {
|
||||
"name": "代理选项",
|
||||
"tooltip": "代理覆盖"
|
||||
},
|
||||
"advanced_options": {
|
||||
"name": "高级选项",
|
||||
"tooltip": "模型高级参数"
|
||||
},
|
||||
"skill_options": {
|
||||
"name": "Skill 选项",
|
||||
"tooltip": "来自 OpenAI 文本 Skill 选项节点的可选渐进式 Skill 配置"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {"name": "结果"},
|
||||
"1": {"name": "对话", "tooltip": "Skill 调用时输出完整脱敏的 Pi Skill Agent ledger"},
|
||||
"2": {"name": "Skill 调用记录"}
|
||||
"0": {
|
||||
"name": "结果"
|
||||
},
|
||||
"1": {
|
||||
"name": "对话",
|
||||
"tooltip": "Skill 调用时输出完整脱敏的 Pi Skill Agent ledger"
|
||||
},
|
||||
"2": {
|
||||
"name": "Skill 调用记录"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Preview_API_Result": {
|
||||
"display_name": "Preview API Result",
|
||||
"description": "将文本渲染为 Markdown 网页预览,并支持复制。",
|
||||
"inputs": {
|
||||
"source": {"name": "文本", "tooltip": "要预览的 Markdown 或纯文本"}
|
||||
"source": {
|
||||
"name": "文本",
|
||||
"tooltip": "要预览的 Markdown 或纯文本"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {"name": "文本"}
|
||||
"0": {
|
||||
"name": "文本"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_OpenAI_Text_Skill_Options": {
|
||||
"display_name": "OpenAI 文本 Skill 选项",
|
||||
"description": "加载本地 SKILL.md,并供 OpenAI 文本 API 渐进式读取引用资料。",
|
||||
"inputs": {
|
||||
"skill_name": {"name": "Skill 名称", "tooltip": "选择配置中发现的本地 Skill"},
|
||||
"description": {"name": "Skill 描述", "tooltip": "当前所选 Skill 的只读描述"}
|
||||
"skill_name": {
|
||||
"name": "Skill 名称",
|
||||
"tooltip": "选择配置中发现的本地 Skill"
|
||||
},
|
||||
"description": {
|
||||
"name": "Skill 描述",
|
||||
"tooltip": "当前所选 Skill 的只读描述"
|
||||
}
|
||||
},
|
||||
"outputs": {"0": {"name": "Skill 选项"}}
|
||||
"outputs": {
|
||||
"0": {
|
||||
"name": "Skill 选项"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_OpenAI_Text_Advanced_Options": {
|
||||
"display_name": "OpenAI 文本高级选项(JSON)",
|
||||
@@ -51,7 +108,11 @@
|
||||
"tooltip": "填写协议或 API 特有请求参数的 JSON 对象。示例:\n{\n \"temperature\": 0.7,\n \"reasoning\": {\n \"effort\": \"medium\"\n }\n}"
|
||||
}
|
||||
},
|
||||
"outputs": {"0": {"name": "高级选项"}}
|
||||
"outputs": {
|
||||
"0": {
|
||||
"name": "高级选项"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Gemini_Image_API": {
|
||||
"display_name": "Gemini 图像 API",
|
||||
@@ -61,11 +122,11 @@
|
||||
"name": "图像",
|
||||
"tooltip": "可选的图像,用作模型的上下文"
|
||||
},
|
||||
"config_options":{
|
||||
"config_options": {
|
||||
"name": "配置选项",
|
||||
"tooltip": "可选配置覆盖选项,来自 YCYY API 配置选项"
|
||||
},
|
||||
"proxy_options":{
|
||||
"proxy_options": {
|
||||
"name": "代理选项",
|
||||
"tooltip": "可选代理覆盖选项,来自 YCYY API 代理选项"
|
||||
},
|
||||
@@ -101,19 +162,73 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Ollama_VLM_API":{
|
||||
"display_name": "Ollama 视觉 API",
|
||||
"description": "这个节点使用Ollama VLM 模型进行图片推理分析",
|
||||
"YCYY_Grok_Image_API": {
|
||||
"display_name": "Grok 图像 API",
|
||||
"description": "该节点使用 xAI Grok 图像 API 生成或编辑图像",
|
||||
"inputs": {
|
||||
"images":{
|
||||
"images": {
|
||||
"name": "图像",
|
||||
"tooltip": "用于分析的图像(支持多个)"
|
||||
"tooltip": "可选的参考图像,用于图生图编辑。Grok 支持最多 3 张参考图片(pro 模型支持 1 张)。"
|
||||
},
|
||||
"config_options":{
|
||||
"config_options": {
|
||||
"name": "配置选项",
|
||||
"tooltip": "可选配置覆盖选项,来自 YCYY API 配置选项"
|
||||
},
|
||||
"proxy_options":{
|
||||
"proxy_options": {
|
||||
"name": "代理选项",
|
||||
"tooltip": "可选代理覆盖选项,来自 YCYY API 代理选项"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "提示词",
|
||||
"tooltip": "用于生成或编辑图像的提示词"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型",
|
||||
"tooltip": "Grok 图像模型"
|
||||
},
|
||||
"aspect_ratio": {
|
||||
"name": "图像宽高比",
|
||||
"tooltip": "输出图像的宽高比。'auto' 在编辑模式下匹配输入图像,或生成 1:1 正方形。"
|
||||
},
|
||||
"resolution": {
|
||||
"name": "图像分辨率",
|
||||
"tooltip": "控制输出图像的分辨率(1K 或 2K)。"
|
||||
},
|
||||
"quality": {
|
||||
"name": "质量",
|
||||
"tooltip": "质量等级,仅 grok-imagine-image-2.0 模型支持。"
|
||||
},
|
||||
"number_of_images": {
|
||||
"name": "生成数量",
|
||||
"tooltip": "要生成的图像数量(1 到 10)。"
|
||||
},
|
||||
"seed": {
|
||||
"name": "种子",
|
||||
"tooltip": "用于生成噪声的随机种子。"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {
|
||||
"name": "图像"
|
||||
},
|
||||
"1": {
|
||||
"name": "信息"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Ollama_VLM_API": {
|
||||
"display_name": "Ollama 视觉 API",
|
||||
"description": "这个节点使用Ollama VLM 模型进行图片推理分析",
|
||||
"inputs": {
|
||||
"images": {
|
||||
"name": "图像",
|
||||
"tooltip": "用于分析的图像(支持多个)"
|
||||
},
|
||||
"config_options": {
|
||||
"name": "配置选项",
|
||||
"tooltip": "可选配置覆盖选项,来自 YCYY API 配置选项"
|
||||
},
|
||||
"proxy_options": {
|
||||
"name": "代理选项",
|
||||
"tooltip": "可选代理覆盖选项,来自 YCYY API 代理选项"
|
||||
},
|
||||
@@ -127,26 +242,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Ollama_LLM_API":{
|
||||
"YCYY_Ollama_LLM_API": {
|
||||
"display_name": "Ollama 文本 API",
|
||||
"description": "该节点使用 Ollama 大语言模型进行对话",
|
||||
"inputs": {
|
||||
"config_options":{
|
||||
"config_options": {
|
||||
"name": "配置选项",
|
||||
"tooltip": "可选配置覆盖选项,来自 YCYY API 配置选项"
|
||||
},
|
||||
"proxy_options":{
|
||||
"proxy_options": {
|
||||
"name": "代理选项",
|
||||
"tooltip": "可选代理覆盖选项,来自 YCYY API 代理选项"
|
||||
},
|
||||
"advanced_options":{
|
||||
"advanced_options": {
|
||||
"name": "高级选项",
|
||||
"tooltip": "模型的高级选项(可选),接受来自 Ollama 文本高级选项节点的输入。"
|
||||
},
|
||||
"system_prompt":{
|
||||
"system_prompt": {
|
||||
"name": "system_prompt"
|
||||
},
|
||||
"user_prompt":{
|
||||
"user_prompt": {
|
||||
"name": "user_prompt"
|
||||
},
|
||||
"model": {
|
||||
@@ -172,17 +287,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Ollama_LLM_Advanced_Options":{
|
||||
"YCYY_Ollama_LLM_Advanced_Options": {
|
||||
"display_name": "Ollama 文本高级选项",
|
||||
"description": "该节点为 ollama 大语言模型提供了高级选项。",
|
||||
"inputs": {
|
||||
"max_tokens":{
|
||||
"inputs": {
|
||||
"max_tokens": {
|
||||
"name": "max_tokens"
|
||||
},
|
||||
"temperature":{
|
||||
"temperature": {
|
||||
"name": "temperature"
|
||||
},
|
||||
"top_p":{
|
||||
"top_p": {
|
||||
"name": "top_p"
|
||||
},
|
||||
"enable_max_tokens": {
|
||||
@@ -261,19 +376,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Gemini_Image_Preset":{
|
||||
"YCYY_Gemini_Image_Preset": {
|
||||
"display_name": "Gemini 图像预设",
|
||||
"description": "该节点为 Gemini 图像 API 提供预设值",
|
||||
"inputs": {
|
||||
"preset":{
|
||||
"preset": {
|
||||
"name": "预设名称",
|
||||
"tooltip": "预设名称"
|
||||
},
|
||||
"description":{
|
||||
"description": {
|
||||
"name": "预设描述",
|
||||
"tooltip": "预设描述"
|
||||
},
|
||||
"prompt":{
|
||||
"prompt": {
|
||||
"name": "预设提示词",
|
||||
"tooltip": "预设提示词"
|
||||
}
|
||||
@@ -332,11 +447,11 @@
|
||||
"name": "text",
|
||||
"tooltip": "需要转换为语音的文本"
|
||||
},
|
||||
"config_options":{
|
||||
"config_options": {
|
||||
"name": "配置选项",
|
||||
"tooltip": "可选配置覆盖选项,来自 YCYY API 配置选项"
|
||||
},
|
||||
"proxy_options":{
|
||||
"proxy_options": {
|
||||
"name": "代理选项",
|
||||
"tooltip": "可选代理覆盖选项,来自 YCYY API 代理选项"
|
||||
},
|
||||
@@ -406,11 +521,11 @@
|
||||
"name": "prompt",
|
||||
"tooltip": "用于指导转录的提示词。您可以要求特定的格式或指令。"
|
||||
},
|
||||
"config_options":{
|
||||
"config_options": {
|
||||
"name": "配置选项",
|
||||
"tooltip": "可选配置覆盖选项,来自 YCYY API 配置选项"
|
||||
},
|
||||
"proxy_options":{
|
||||
"proxy_options": {
|
||||
"name": "代理选项",
|
||||
"tooltip": "可选代理覆盖选项,来自 YCYY API 代理选项"
|
||||
},
|
||||
@@ -431,11 +546,11 @@
|
||||
"display_name": "魔搭图像API",
|
||||
"description": "该节点使用 ModelScope API 生成图像",
|
||||
"inputs": {
|
||||
"config_options":{
|
||||
"config_options": {
|
||||
"name": "配置选项",
|
||||
"tooltip": "可选配置覆盖选项,来自 YCYY API 配置选项"
|
||||
},
|
||||
"proxy_options":{
|
||||
"proxy_options": {
|
||||
"name": "代理选项",
|
||||
"tooltip": "可选代理覆盖选项,来自 YCYY API 代理选项"
|
||||
},
|
||||
@@ -476,20 +591,49 @@
|
||||
"display_name": "魔搭图像编辑API",
|
||||
"description": "该节点使用 ModelScope API 编辑输入图像",
|
||||
"inputs": {
|
||||
"image": {"name": "输入图像", "tooltip": "要编辑的输入图像"},
|
||||
"config_options": {"name": "配置选项", "tooltip": "可选配置覆盖选项,来自 YCYY API 配置选项"},
|
||||
"proxy_options": {"name": "代理选项", "tooltip": "可选代理覆盖选项,来自 YCYY API 代理选项"},
|
||||
"prompt": {"name": "prompt", "tooltip": "图像编辑指令"},
|
||||
"negative_prompt": {"name": "negative_prompt", "tooltip": "负向提示"},
|
||||
"model": {"name": "模型"},
|
||||
"width": {"name": "宽度"},
|
||||
"height": {"name": "高度"},
|
||||
"steps": {"name": "采样步数"},
|
||||
"guidance": {"name": "提示词引导系数"}
|
||||
"image": {
|
||||
"name": "输入图像",
|
||||
"tooltip": "要编辑的输入图像"
|
||||
},
|
||||
"config_options": {
|
||||
"name": "配置选项",
|
||||
"tooltip": "可选配置覆盖选项,来自 YCYY API 配置选项"
|
||||
},
|
||||
"proxy_options": {
|
||||
"name": "代理选项",
|
||||
"tooltip": "可选代理覆盖选项,来自 YCYY API 代理选项"
|
||||
},
|
||||
"prompt": {
|
||||
"name": "prompt",
|
||||
"tooltip": "图像编辑指令"
|
||||
},
|
||||
"negative_prompt": {
|
||||
"name": "negative_prompt",
|
||||
"tooltip": "负向提示"
|
||||
},
|
||||
"model": {
|
||||
"name": "模型"
|
||||
},
|
||||
"width": {
|
||||
"name": "宽度"
|
||||
},
|
||||
"height": {
|
||||
"name": "高度"
|
||||
},
|
||||
"steps": {
|
||||
"name": "采样步数"
|
||||
},
|
||||
"guidance": {
|
||||
"name": "提示词引导系数"
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
"0": {"name": "图像"},
|
||||
"1": {"name": "字符串"}
|
||||
"0": {
|
||||
"name": "图像"
|
||||
},
|
||||
"1": {
|
||||
"name": "字符串"
|
||||
}
|
||||
}
|
||||
},
|
||||
"YCYY_Image_Compare": {
|
||||
@@ -506,4 +650,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
Reference in New Issue
Block a user