Files
Van/攻城狮鹿鸣君 4cfe6c4e40 prepare a verifiable first Registry release
Establish the immutable mediahub-cloud identity, public documentation, branding, contribution contract, CI, guarded publishing workflow, and a live-smoke regression fix before the first public release.

Constraint: Registry versions and node IDs are immutable after publication

Rejected: Automatic publish on pyproject.toml changes | too easy to publish an unverified immutable version

Confidence: high

Scope-risk: moderate

Directive: Run paid provider-family live verification before triggering the manual Registry workflow

Tested: 221 pytest tests; JavaScript syntax; Python compilation; workflow JSON validation; restarted ComfyUI smoke; clean editable install; comfy node validate; comfy node pack inspection

Not-tested: Paid live API calls for every advertised provider family
2026-06-13 22:34:55 +08:00

554 lines
23 KiB
Python

import json
import torch
if __package__:
from .mediahub.core.contracts import MediaRequest
from .mediahub.core.registry import registry
from .mediahub.core.services import generate_image, resolve_video, submit_video
from .mediahub.images import image_sources_to_tensor_batch, image_tensor_to_base64_data_url
from .mediahub import providers as _providers
else:
from mediahub.core.contracts import MediaRequest
from mediahub.core.registry import registry
from mediahub.core.services import generate_image, resolve_video, submit_video
from mediahub.images import image_sources_to_tensor_batch, image_tensor_to_base64_data_url
from mediahub import providers as _providers
KEY_INPUT = ("STRING", {"forceInput": True})
PROMPT_INPUT = ("STRING", {"forceInput": True})
IMAGE_INPUT = ("IMAGE", {"forceInput": True})
SEED_INPUT = ("INT", {"default": 0, "min": 0, "max": 9223372036854775807, "control_after_generate": False})
RATIOS = ["1:1", "16:9", "4:3", "3:2", "2:3", "3:4", "9:16", "21:9"]
def _request(provider, operation, payload):
return (MediaRequest(provider, operation, payload),)
def _minimax_image_inputs(i2i=False):
required = {
"prompt": PROMPT_INPUT,
"model": (["image-01", "image-01-live"],),
"aspect_ratio": (RATIOS,),
"use_seed": ("BOOLEAN", {"default": False}),
"seed": SEED_INPUT,
"n": ("INT", {"default": 1, "min": 1, "max": 9}),
"response_format": (["url", "base64"],),
"prompt_optimizer": ("BOOLEAN", {"default": False}),
"aigc_watermark": ("BOOLEAN", {"default": False}),
"use_style": ("BOOLEAN", {"default": False}),
"style_type": (["漫画", "元气", "中世纪", "水彩"],),
"style_weight": ("FLOAT", {"default": 0.8, "min": 0.01, "max": 1.0, "step": 0.01}),
}
if i2i:
required["subject_image"] = IMAGE_INPUT
else:
required = {
**required,
"size_mode": (["aspect_ratio", "custom"],),
"width": ("INT", {"default": 1024, "min": 512, "max": 2048, "step": 8}),
"height": ("INT", {"default": 1024, "min": 512, "max": 2048, "step": 8}),
}
return {"required": required}
class MiniMaxCNT2IConfig:
@classmethod
def INPUT_TYPES(cls): return _minimax_image_inputs()
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/MiniMax CN/Image"
def build(self, **kwargs):
payload = registry.call("MiniMax CN", "image.t2i.build", **kwargs)
return _request("MiniMax CN", "image.generate", payload)
class MiniMaxCNI2IConfig:
@classmethod
def INPUT_TYPES(cls): return _minimax_image_inputs(True)
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/MiniMax CN/Image"
def build(self, subject_image: torch.Tensor, **kwargs):
refs = [{"type": "character", "image_file": value} for value in image_tensor_to_base64_data_url(subject_image)]
payload = registry.call("MiniMax CN", "image.i2i.build", subject_reference=refs, **kwargs)
return _request("MiniMax CN", "image.generate", payload)
def _agnes_image_inputs(i2i=False):
required = {
"prompt": PROMPT_INPUT,
"width": ("INT", {"default": 1024, "min": 64, "max": 4096, "step": 8}),
"height": ("INT", {"default": 768, "min": 64, "max": 4096, "step": 8}),
"response_format": (["url", "base64"],),
}
if i2i:
required["image"] = IMAGE_INPUT
return {"required": required}
class AgnesImage21T2IConfig:
@classmethod
def INPUT_TYPES(cls): return _agnes_image_inputs()
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Agnes/Image"
def build(self, prompt, width, height, response_format):
payload = registry.call("Agnes", "image.t2i.build", prompt=prompt, width=width, height=height, response_format=response_format)
return _request("Agnes", "image.generate", payload)
class AgnesImage21I2IConfig:
@classmethod
def INPUT_TYPES(cls): return _agnes_image_inputs(True)
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Agnes/Image"
def build(self, prompt, width, height, response_format, image):
images = image_tensor_to_base64_data_url(image)
payload = registry.call("Agnes", "image.i2i.build", prompt=prompt, width=width, height=height, images=images, response_format=response_format)
return _request("Agnes", "image.generate", payload)
def _seed_image_inputs(i2i=False):
required = {
"prompt": PROMPT_INPUT,
"model": (["doubao-seedream-5-0-260128", "doubao-seedream-4-5-251128", "doubao-seedream-4-0-250828"],),
"size": (["1K", "2K", "3K", "4K"],),
"response_format": (["url", "base64"],),
"watermark": ("BOOLEAN", {"default": False}),
"seed": ("INT", {"default": -1, "min": -1, "max": 4294967295}),
}
if i2i:
required["image"] = IMAGE_INPUT
return {"required": required}
class SeedVolcengineT2IConfig:
@classmethod
def INPUT_TYPES(cls): return _seed_image_inputs()
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Seed Volcengine/Image"
def build(self, **kwargs):
payload = registry.call("Seed Volcengine", "image.t2i.build", **kwargs)
return _request("Seed Volcengine", "image.generate", payload)
class SeedVolcengineI2IConfig:
@classmethod
def INPUT_TYPES(cls): return _seed_image_inputs(True)
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Seed Volcengine/Image"
def build(self, image, **kwargs):
images = image_tensor_to_base64_data_url(image)
payload = registry.call("Seed Volcengine", "image.i2i.build", images=images, **kwargs)
return _request("Seed Volcengine", "image.generate", payload)
def _seed_video_inputs(with_image=False):
models = ["doubao-seedance-2-0-260128", "doubao-seedance-2-0-fast-260128", "doubao-seedance-1-5-pro-251215", "doubao-seedance-1-0-pro-250528", "doubao-seedance-1-0-pro-fast-251015"]
if with_image:
required = {
"mode": (["first_frame", "first_last_frame"],),
"prompt": PROMPT_INPUT,
"first_frame_image": IMAGE_INPUT,
"model": (models,),
"resolution": (["480p", "720p", "1080p"],),
"ratio": (["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "adaptive"],),
"duration": ("INT", {"default": 5, "min": -1, "max": 15}),
"seed": ("INT", {"default": -1, "min": -1, "max": 4294967295}),
"watermark": ("BOOLEAN", {"default": False}),
"generate_audio": ("BOOLEAN", {"default": True}),
}
return {"required": required, "optional": {"last_frame_image": IMAGE_INPUT}}
required = {
"prompt": PROMPT_INPUT,
"model": (models,),
"resolution": (["480p", "720p", "1080p"],),
"ratio": (["16:9", "4:3", "1:1", "3:4", "9:16", "21:9", "adaptive"],),
"duration": ("INT", {"default": 5, "min": -1, "max": 15}),
"seed": ("INT", {"default": -1, "min": -1, "max": 4294967295}),
"watermark": ("BOOLEAN", {"default": False}),
"generate_audio": ("BOOLEAN", {"default": True}),
}
return {"required": required}
class SeedVolcengineT2VConfig:
@classmethod
def INPUT_TYPES(cls): return _seed_video_inputs()
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Seed Volcengine/Video"
def build(self, **kwargs):
payload = registry.call("Seed Volcengine", "video.t2v.build", **kwargs)
return _request("Seed Volcengine", "video.submit", payload)
class SeedVolcengineI2VConfig:
@classmethod
def INPUT_TYPES(cls): return _seed_video_inputs(True)
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Seed Volcengine/Video"
def build(self, mode, first_frame_image, last_frame_image=None, **kwargs):
images = image_tensor_to_base64_data_url(first_frame_image)
if mode == "first_last_frame":
if last_frame_image is None:
raise ValueError("Last frame image is required for first_last_frame mode")
images.extend(image_tensor_to_base64_data_url(last_frame_image))
payload = registry.call("Seed Volcengine", "video.i2v.build", images=images, mode=mode, **kwargs)
return _request("Seed Volcengine", "video.submit", payload)
def _wan_image_inputs(i2i=False):
required = {
"prompt": PROMPT_INPUT,
"model": (["wan2.7-image-pro", "wan2.7-image"],),
"size": (["1K", "2K", "4K"],),
"n": ("INT", {"default": 1, "min": 1, "max": 4}),
"watermark": ("BOOLEAN", {"default": False}),
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
}
if i2i:
required["image"] = IMAGE_INPUT
return {"required": required}
class WanBailianCNT2IConfig:
@classmethod
def INPUT_TYPES(cls): return _wan_image_inputs()
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Wan Bailian CN/Image"
def build(self, **kwargs):
payload = registry.call("Wan Bailian CN", "image.t2i.build", **kwargs)
return _request("Wan Bailian CN", "image.generate", payload)
class WanBailianCNI2IConfig:
@classmethod
def INPUT_TYPES(cls): return _wan_image_inputs(True)
RETURN_TYPES = ("MEDIAHUB_IMAGE_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Wan Bailian CN/Image"
def build(self, image, **kwargs):
images = image_tensor_to_base64_data_url(image)
payload = registry.call("Wan Bailian CN", "image.i2i.build", images=images, **kwargs)
return _request("Wan Bailian CN", "image.generate", payload)
def _wan_t2v_inputs():
return {"required": {
"prompt": PROMPT_INPUT,
"model": (["wan2.7-t2v"],),
"resolution": (["720P", "1080P"],),
"ratio": (["16:9", "9:16", "1:1", "4:3", "3:4"],),
"duration": ("INT", {"default": 5, "min": -1, "max": 15}),
"watermark": ("BOOLEAN", {"default": False}),
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
"prompt_extend": ("BOOLEAN", {"default": True}),
"negative_prompt": ("STRING", {"default": "", "multiline": True}),
"audio_url": ("STRING", {"default": ""}),
}}
class WanBailianCNT2VConfig:
@classmethod
def INPUT_TYPES(cls): return _wan_t2v_inputs()
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Wan Bailian CN/Video"
def build(self, **kwargs):
payload = registry.call("Wan Bailian CN", "video.t2v.build", **kwargs)
return _request("Wan Bailian CN", "video.submit", payload)
def _wan_i2v_inputs():
return {"required": {
"prompt": PROMPT_INPUT,
"model": (["wan2.7-i2v-2026-04-25"],),
"resolution": (["720P", "1080P"],),
"duration": ("INT", {"default": 5, "min": 2, "max": 15}),
"watermark": ("BOOLEAN", {"default": False}),
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
"prompt_extend": ("BOOLEAN", {"default": True}),
"mode": (["first_frame", "first_last_frame"],),
"first_frame_image": IMAGE_INPUT,
}, "optional": {"last_frame_image": IMAGE_INPUT, "audio_url": ("STRING", {"default": ""})}}
class WanBailianCNI2VConfig:
@classmethod
def INPUT_TYPES(cls): return _wan_i2v_inputs()
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Wan Bailian CN/Video"
def build(self, mode, first_frame_image, last_frame_image=None, audio_url="", **kwargs):
images = image_tensor_to_base64_data_url(first_frame_image)
if mode == "first_last_frame":
if last_frame_image is None:
raise ValueError("Last frame image is required for first_last_frame mode")
images.extend(image_tensor_to_base64_data_url(last_frame_image))
payload = registry.call("Wan Bailian CN", "video.i2v.build", images=images, mode=mode, audio_url=audio_url, **kwargs)
return _request("Wan Bailian CN", "video.submit", payload)
def _hh_t2v_inputs():
return {"required": {
"prompt": PROMPT_INPUT,
"model": (["happyhorse-1.0-t2v"],),
"resolution": (["720P", "1080P"],),
"ratio": (["16:9", "9:16", "1:1", "4:3", "3:4", "4:5", "5:4", "9:21", "21:9"],),
"duration": ("INT", {"default": 5, "min": 3, "max": 15}),
"watermark": ("BOOLEAN", {"default": True}),
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
}}
class HappyHorseBailianCNT2VConfig:
@classmethod
def INPUT_TYPES(cls): return _hh_t2v_inputs()
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/HappyHorse Bailian CN/Video"
def build(self, **kwargs):
payload = registry.call("HappyHorse Bailian CN", "video.t2v.build", **kwargs)
return _request("HappyHorse Bailian CN", "video.submit", payload)
def _hh_i2v_inputs():
return {"required": {
"prompt": PROMPT_INPUT,
"model": (["happyhorse-1.0-i2v"],),
"resolution": (["720P", "1080P"],),
"duration": ("INT", {"default": 5, "min": 3, "max": 15}),
"watermark": ("BOOLEAN", {"default": True}),
"seed": ("INT", {"default": -1, "min": -1, "max": 2147483647}),
"first_frame_image": IMAGE_INPUT,
}}
class HappyHorseBailianCNI2VConfig:
@classmethod
def INPUT_TYPES(cls): return _hh_i2v_inputs()
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/HappyHorse Bailian CN/Video"
def build(self, first_frame_image, **kwargs):
images = image_tensor_to_base64_data_url(first_frame_image)
payload = registry.call("HappyHorse Bailian CN", "video.i2v.build", images=images, **kwargs)
return _request("HappyHorse Bailian CN", "video.submit", payload)
class MediaHubGenerateImage:
@classmethod
def INPUT_TYPES(cls): return {"required": {"api_key": KEY_INPUT, "request": ("MEDIAHUB_IMAGE_REQUEST", {"forceInput": True})}}
RETURN_TYPES = ("IMAGE", "STRING", "STRING")
RETURN_NAMES = ("image", "image_urls", "raw_json")
FUNCTION = "generate"
CATEGORY = "MediaHub/Image"
@classmethod
def IS_CHANGED(cls, **kwargs): return float("NaN")
def generate(self, api_key, request):
result = generate_image(api_key, request)
return image_sources_to_tensor_batch(result.sources), json.dumps(result.urls, ensure_ascii=False), json.dumps(result.raw, ensure_ascii=False, indent=2)
def _minimax_t2v_inputs():
return {"required": {
"prompt": PROMPT_INPUT,
"model": (["MiniMax-Hailuo-2.3", "MiniMax-Hailuo-02", "T2V-01-Director", "T2V-01"],),
"resolution": (["768P", "1080P"],),
"duration": ([6, 10],),
"prompt_optimizer": ("BOOLEAN", {"default": True}),
"fast_pretreatment": ("BOOLEAN", {"default": False}),
"aigc_watermark": ("BOOLEAN", {"default": False}),
}}
class MiniMaxCNT2VConfig:
@classmethod
def INPUT_TYPES(cls): return _minimax_t2v_inputs()
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/MiniMax CN/Video"
def build(self, **kwargs):
return _request("MiniMax CN", "video.submit", registry.call("MiniMax CN", "video.t2v.build", **kwargs))
class MiniMaxCNI2VConfig:
@classmethod
def INPUT_TYPES(cls):
return {"required": {
"mode": (["i2v", "fl2v", "s2v"],), "prompt": PROMPT_INPUT,
"model": (["MiniMax-Hailuo-2.3", "MiniMax-Hailuo-2.3-Fast", "MiniMax-Hailuo-02", "I2V-01-Director", "I2V-01-live", "I2V-01", "S2V-01"],),
"resolution": (["768P", "1080P"],), "duration": ([6, 10],),
"prompt_optimizer": ("BOOLEAN", {"default": True}), "fast_pretreatment": ("BOOLEAN", {"default": False}), "aigc_watermark": ("BOOLEAN", {"default": False}),
}, "optional": {"first_frame_image": IMAGE_INPUT, "last_frame_image": IMAGE_INPUT, "subject_image": IMAGE_INPUT}}
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/MiniMax CN/Video"
def build(self, mode, first_frame_image=None, last_frame_image=None, subject_image=None, **kwargs):
first = image_tensor_to_base64_data_url(first_frame_image)[0] if first_frame_image is not None else ""
last = image_tensor_to_base64_data_url(last_frame_image)[0] if last_frame_image is not None else ""
subjects = image_tensor_to_base64_data_url(subject_image) if subject_image is not None else []
payload = registry.call("MiniMax CN", "video.i2v.build", mode=mode, first_frame_data_url=first, last_frame_data_url=last, subject_image_data_urls=subjects, **kwargs)
return _request("MiniMax CN", "video.submit", payload)
def _agnes_video_inputs(with_image=False):
required = {
"prompt": PROMPT_INPUT,
"width": ("INT", {"default": 1152, "min": 64, "max": 4096, "step": 8}),
"height": ("INT", {"default": 768, "min": 64, "max": 4096, "step": 8}),
"num_frames": ("INT", {"default": 121, "min": 1, "max": 441, "step": 8}),
"frame_rate": ("FLOAT", {"default": 24, "min": 1, "max": 60, "step": 1}),
"num_inference_steps": ("INT", {"default": 30, "min": 1, "max": 100}),
"use_seed": ("BOOLEAN", {"default": False}), "seed": SEED_INPUT,
"negative_prompt": ("STRING", {"default": "", "multiline": True}),
}
if with_image:
required["mode"] = (["i2v", "multi_image", "keyframes"],)
required["image"] = IMAGE_INPUT
return {"required": required}
class AgnesVideo20T2VConfig:
@classmethod
def INPUT_TYPES(cls): return _agnes_video_inputs()
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Agnes/Video"
def build(self, **kwargs):
payload = registry.call("Agnes", "video.build", images=[], mode="t2v", **kwargs)
return _request("Agnes", "video.submit", payload)
class AgnesVideo20I2VConfig:
@classmethod
def INPUT_TYPES(cls): return _agnes_video_inputs(True)
RETURN_TYPES = ("MEDIAHUB_VIDEO_REQUEST",)
RETURN_NAMES = ("request",)
FUNCTION = "build"
CATEGORY = "MediaHub/Provider/Agnes/Video"
def build(self, image, mode, **kwargs):
payload = registry.call("Agnes", "video.build", images=image_tensor_to_base64_data_url(image), mode=mode, **kwargs)
return _request("Agnes", "video.submit", payload)
class MediaHubSubmitVideo:
@classmethod
def INPUT_TYPES(cls): return {"required": {"api_key": KEY_INPUT, "request": ("MEDIAHUB_VIDEO_REQUEST", {"forceInput": True})}}
RETURN_TYPES = ("MEDIAHUB_JOB", "STRING")
RETURN_NAMES = ("job", "raw_json")
FUNCTION = "submit"
CATEGORY = "MediaHub/Video"
@classmethod
def IS_CHANGED(cls, **kwargs): return float("NaN")
def submit(self, api_key, request):
job = submit_video(api_key, request)
return job, json.dumps(job.to_dict(), ensure_ascii=False, indent=2)
class MediaHubResolveVideo:
@classmethod
def INPUT_TYPES(cls): return {"required": {"api_key": KEY_INPUT, "job": ("MEDIAHUB_JOB", {"forceInput": True})}}
RETURN_TYPES = ("VIDEO", "STRING", "STRING")
RETURN_NAMES = ("video", "video_url", "raw_json")
FUNCTION = "resolve"
CATEGORY = "MediaHub/Video"
@classmethod
def IS_CHANGED(cls, **kwargs): return float("NaN")
def resolve(self, api_key, job):
result = resolve_video(api_key, job)
from comfy_api.latest import InputImpl
return InputImpl.VideoFromFile(str(result.path)), result.url, json.dumps(result.raw, ensure_ascii=False, indent=2)
class MediaHubAPIKey:
@classmethod
def INPUT_TYPES(cls): return {"required": {"api_key": ("STRING", {"default": "", "password": True, "placeholder": "API Key"})}}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("api_key",)
FUNCTION = "get_api_key"
CATEGORY = "MediaHub/Inputs"
def get_api_key(self, api_key): return (api_key,)
NODE_CLASS_MAPPINGS = {
"MiniMaxCNT2IConfig": MiniMaxCNT2IConfig, "MiniMaxCNI2IConfig": MiniMaxCNI2IConfig,
"AgnesImage21T2IConfig": AgnesImage21T2IConfig, "AgnesImage21I2IConfig": AgnesImage21I2IConfig,
"SeedVolcengineT2IConfig": SeedVolcengineT2IConfig, "SeedVolcengineI2IConfig": SeedVolcengineI2IConfig,
"WanBailianCNT2IConfig": WanBailianCNT2IConfig, "WanBailianCNI2IConfig": WanBailianCNI2IConfig,
"MediaHubGenerateImage": MediaHubGenerateImage,
"MiniMaxCNT2VConfig": MiniMaxCNT2VConfig, "MiniMaxCNI2VConfig": MiniMaxCNI2VConfig,
"AgnesVideo20T2VConfig": AgnesVideo20T2VConfig, "AgnesVideo20I2VConfig": AgnesVideo20I2VConfig,
"SeedVolcengineT2VConfig": SeedVolcengineT2VConfig, "SeedVolcengineI2VConfig": SeedVolcengineI2VConfig,
"WanBailianCNT2VConfig": WanBailianCNT2VConfig, "WanBailianCNI2VConfig": WanBailianCNI2VConfig,
"HappyHorseBailianCNT2VConfig": HappyHorseBailianCNT2VConfig, "HappyHorseBailianCNI2VConfig": HappyHorseBailianCNI2VConfig,
"MediaHubSubmitVideo": MediaHubSubmitVideo, "MediaHubResolveVideo": MediaHubResolveVideo,
"MediaHubAPIKey": MediaHubAPIKey,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"MiniMaxCNT2IConfig": "MiniMax CN T2I Config", "MiniMaxCNI2IConfig": "MiniMax CN I2I Config",
"AgnesImage21T2IConfig": "Agnes Image 2.1 T2I Config", "AgnesImage21I2IConfig": "Agnes Image 2.1 I2I Config",
"SeedVolcengineT2IConfig": "Seed Volcengine T2I Config", "SeedVolcengineI2IConfig": "Seed Volcengine I2I Config",
"WanBailianCNT2IConfig": "Wan Bailian CN T2I Config", "WanBailianCNI2IConfig": "Wan Bailian CN I2I Config",
"MediaHubGenerateImage": "MediaHub Generate Image",
"MiniMaxCNT2VConfig": "MiniMax CN T2V Config", "MiniMaxCNI2VConfig": "MiniMax CN I2V Config",
"AgnesVideo20T2VConfig": "Agnes Video 2.0 T2V Config", "AgnesVideo20I2VConfig": "Agnes Video 2.0 I2V Config",
"SeedVolcengineT2VConfig": "Seed Volcengine T2V Config", "SeedVolcengineI2VConfig": "Seed Volcengine I2V Config",
"WanBailianCNT2VConfig": "Wan Bailian CN T2V Config", "WanBailianCNI2VConfig": "Wan Bailian CN I2V Config",
"HappyHorseBailianCNT2VConfig": "HappyHorse T2V Config", "HappyHorseBailianCNI2VConfig": "HappyHorse I2V Config",
"MediaHubSubmitVideo": "MediaHub Submit Video", "MediaHubResolveVideo": "MediaHub Resolve Video",
"MediaHubAPIKey": "MediaHub API Key",
}