Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ This node pack focuses on **image / video / edit** — see the full **[node cata
| AtlasCloud VEO3.1 Lite Text-to-Video | google/veo3.1-lite/text-to-video |
| AtlasCloud VEO3.1 Fast Text-to-Video | google/veo3.1-fast/text-to-video |
| AtlasCloud Gemini Omni Flash Text-to-Video Developer | google/gemini-omni-flash/text-to-video-developer |
| AtlasCloud Gemini Omni Flash Text-to-Video | google/gemini-omni-flash/text-to-video |
| AtlasCloud Gemini Omni Flash Image-to-Video | google/gemini-omni-flash/image-to-video |
| AtlasCloud Gemini Omni Flash Reference-to-Video | google/gemini-omni-flash/reference-to-video |
| AtlasCloud Gemini Omni Flash Video Edit | google/gemini-omni-flash/video-edit |
| AtlasCloud Grok Imagine Video Text-to-Video | xai/grok-imagine-video/text-to-video |
| AtlasCloud VEO2 Text-to-Video | google/veo2 |
| AtlasCloud WAN2.6 Text-to-Video | alibaba/wan-2.6/text-to-video |
Expand Down
76 changes: 76 additions & 0 deletions src/atlascloud_comfyui/nodes/video/google_gemini_omni_flash_i2v.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from __future__ import annotations

from typing import Any, Dict, Tuple

from ..auth.atlas_client_node import AtlasClientHandle


class AtlasGeminiOmniFlashImageToVideo:
CATEGORY = "AtlasCloud/Video"
FUNCTION = "run"
RETURN_TYPES = ("STRING", "STRING")
RETURN_NAMES = ("video_url", "prediction_id")

@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"atlas_client": ("ATLAS_CLIENT",),
"prompt": ("STRING", {"multiline": True, "tooltip": "Text prompt (max 20,000 chars)"}),
"image": ("STRING", {"default": "", "tooltip": "Starting frame image URL/base64 (<=20MB)"}),
},
"optional": {
"duration": ("INT", {"default": 10, "min": 3, "max": 10, "tooltip": "Duration (seconds)"}),
"aspect_ratio": (["16:9", "9:16"], {"default": "16:9", "tooltip": "Aspect ratio"}),
"resolution": (["720p"], {"default": "720p", "tooltip": "Resolution"}),
"thinking_level": (["default", "high", "low"], {"default": "default", "tooltip": "Internal reasoning level"}),
"seed": ("INT", {"default": -1, "min": -1, "max": 2**31 - 1, "tooltip": "Random if -1"}),
"poll_interval_sec": ("FLOAT", {"default": 2.0, "min": 0.5, "max": 10.0, "tooltip": "Polling interval (seconds)"}),
"timeout_sec": ("INT", {"default": 900, "min": 30, "max": 7200, "tooltip": "Timeout (seconds)"}),
},
}

def run(
self,
atlas_client: AtlasClientHandle,
prompt: str,
image: str,
duration: int = 10,
aspect_ratio: str = "16:9",
resolution: str = "720p",
thinking_level: str = "default",
seed: int = -1,
poll_interval_sec: float = 2.0,
timeout_sec: int = 900,
) -> Tuple[str, str]:
prompt = (prompt or "").strip()
if not prompt:
raise RuntimeError("prompt is required")

image = (image or "").strip()
if not image:
raise RuntimeError("image is required")

client = atlas_client.client

payload: Dict[str, Any] = {
"model": "google/gemini-omni-flash/image-to-video",
"prompt": prompt,
"image": image,
"duration": int(duration),
"aspect_ratio": aspect_ratio,
"resolution": resolution,
"thinking_level": thinking_level,
}

if int(seed) >= 0:
payload["seed"] = int(seed)

prediction_id = client.generate_video(payload)
result = client.poll_prediction(prediction_id, poll_interval_sec=float(poll_interval_sec), timeout_sec=float(timeout_sec))

outputs = (result.get("data") or {}).get("outputs") or []
if not outputs:
raise RuntimeError(f"No outputs returned for prediction {prediction_id}: {result}")

return (outputs[0], prediction_id)
78 changes: 78 additions & 0 deletions src/atlascloud_comfyui/nodes/video/google_gemini_omni_flash_r2v.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from __future__ import annotations

from typing import Any, Dict, List, Tuple

from ..auth.atlas_client_node import AtlasClientHandle


class AtlasGeminiOmniFlashReferenceToVideo:
CATEGORY = "AtlasCloud/Video"
FUNCTION = "run"
RETURN_TYPES = ("STRING", "STRING")
RETURN_NAMES = ("video_url", "prediction_id")

@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"atlas_client": ("ATLAS_CLIENT",),
"prompt": ("STRING", {"multiline": True, "tooltip": "Text prompt (max 20,000 chars)"}),
"images": ("STRING", {"multiline": True, "default": "", "tooltip": "1-5 reference image URLs/base64, one per line"}),
},
"optional": {
"duration": ("INT", {"default": 10, "min": 3, "max": 10, "tooltip": "Duration (seconds)"}),
"aspect_ratio": (["16:9", "9:16"], {"default": "16:9", "tooltip": "Aspect ratio"}),
"resolution": (["720p"], {"default": "720p", "tooltip": "Resolution"}),
"thinking_level": (["default", "high", "low"], {"default": "default", "tooltip": "Internal reasoning level"}),
"seed": ("INT", {"default": -1, "min": -1, "max": 2**31 - 1, "tooltip": "Random if -1"}),
"poll_interval_sec": ("FLOAT", {"default": 2.0, "min": 0.5, "max": 10.0, "tooltip": "Polling interval (seconds)"}),
"timeout_sec": ("INT", {"default": 900, "min": 30, "max": 7200, "tooltip": "Timeout (seconds)"}),
},
}

def run(
self,
atlas_client: AtlasClientHandle,
prompt: str,
images: str,
duration: int = 10,
aspect_ratio: str = "16:9",
resolution: str = "720p",
thinking_level: str = "default",
seed: int = -1,
poll_interval_sec: float = 2.0,
timeout_sec: int = 900,
) -> Tuple[str, str]:
prompt = (prompt or "").strip()
if not prompt:
raise RuntimeError("prompt is required")

image_list: List[str] = [v.strip() for v in (images or "").splitlines() if v.strip()]
if not image_list:
raise RuntimeError("images is required (1-5 lines)")
if len(image_list) > 5:
raise RuntimeError("images maxItems is 5")

client = atlas_client.client

payload: Dict[str, Any] = {
"model": "google/gemini-omni-flash/reference-to-video",
"prompt": prompt,
"images": image_list,
"duration": int(duration),
"aspect_ratio": aspect_ratio,
"resolution": resolution,
"thinking_level": thinking_level,
}

if int(seed) >= 0:
payload["seed"] = int(seed)

prediction_id = client.generate_video(payload)
result = client.poll_prediction(prediction_id, poll_interval_sec=float(poll_interval_sec), timeout_sec=float(timeout_sec))

outputs = (result.get("data") or {}).get("outputs") or []
if not outputs:
raise RuntimeError(f"No outputs returned for prediction {prediction_id}: {result}")

return (outputs[0], prediction_id)
69 changes: 69 additions & 0 deletions src/atlascloud_comfyui/nodes/video/google_gemini_omni_flash_t2v.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from __future__ import annotations

from typing import Any, Dict, Tuple

from ..auth.atlas_client_node import AtlasClientHandle


class AtlasGeminiOmniFlashTextToVideo:
CATEGORY = "AtlasCloud/Video"
FUNCTION = "run"
RETURN_TYPES = ("STRING", "STRING")
RETURN_NAMES = ("video_url", "prediction_id")

@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"atlas_client": ("ATLAS_CLIENT",),
"prompt": ("STRING", {"multiline": True, "tooltip": "Text prompt (max 20,000 chars)"}),
},
"optional": {
"duration": ("INT", {"default": 10, "min": 3, "max": 10, "tooltip": "Duration (seconds)"}),
"aspect_ratio": (["16:9", "9:16"], {"default": "16:9", "tooltip": "Aspect ratio"}),
"resolution": (["720p"], {"default": "720p", "tooltip": "Resolution"}),
"thinking_level": (["default", "high", "low"], {"default": "default", "tooltip": "Internal reasoning level"}),
"seed": ("INT", {"default": -1, "min": -1, "max": 2**31 - 1, "tooltip": "Random if -1"}),
"poll_interval_sec": ("FLOAT", {"default": 2.0, "min": 0.5, "max": 10.0, "tooltip": "Polling interval (seconds)"}),
"timeout_sec": ("INT", {"default": 900, "min": 30, "max": 7200, "tooltip": "Timeout (seconds)"}),
},
}

def run(
self,
atlas_client: AtlasClientHandle,
prompt: str,
duration: int = 10,
aspect_ratio: str = "16:9",
resolution: str = "720p",
thinking_level: str = "default",
seed: int = -1,
poll_interval_sec: float = 2.0,
timeout_sec: int = 900,
) -> Tuple[str, str]:
prompt = (prompt or "").strip()
if not prompt:
raise RuntimeError("prompt is required")

client = atlas_client.client

payload: Dict[str, Any] = {
"model": "google/gemini-omni-flash/text-to-video",
"prompt": prompt,
"duration": int(duration),
"aspect_ratio": aspect_ratio,
"resolution": resolution,
"thinking_level": thinking_level,
}

if int(seed) >= 0:
payload["seed"] = int(seed)

prediction_id = client.generate_video(payload)
result = client.poll_prediction(prediction_id, poll_interval_sec=float(poll_interval_sec), timeout_sec=float(timeout_sec))

outputs = (result.get("data") or {}).get("outputs") or []
if not outputs:
raise RuntimeError(f"No outputs returned for prediction {prediction_id}: {result}")

return (outputs[0], prediction_id)
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from __future__ import annotations

from typing import Any, Dict, List, Tuple

from ..auth.atlas_client_node import AtlasClientHandle


class AtlasGeminiOmniFlashVideoEdit:
CATEGORY = "AtlasCloud/Video"
FUNCTION = "run"
RETURN_TYPES = ("STRING", "STRING")
RETURN_NAMES = ("video_url", "prediction_id")

@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"atlas_client": ("ATLAS_CLIENT",),
"video": ("STRING", {"default": "", "tooltip": "Source video URL (<=100MB, <=30s)"}),
"prompt": ("STRING", {"multiline": True, "tooltip": "Edit prompt (max 20,000 chars)"}),
},
"optional": {
"images": ("STRING", {"multiline": True, "default": "", "tooltip": "Optional 1-5 reference image URLs/base64, one per line"}),
"resolution": (["720p"], {"default": "720p", "tooltip": "Resolution"}),
"thinking_level": (["default", "high", "low"], {"default": "default", "tooltip": "Internal reasoning level"}),
"seed": ("INT", {"default": -1, "min": -1, "max": 2**31 - 1, "tooltip": "Random if -1"}),
"poll_interval_sec": ("FLOAT", {"default": 2.0, "min": 0.5, "max": 10.0, "tooltip": "Polling interval (seconds)"}),
"timeout_sec": ("INT", {"default": 900, "min": 30, "max": 7200, "tooltip": "Timeout (seconds)"}),
},
}

def run(
self,
atlas_client: AtlasClientHandle,
video: str,
prompt: str,
images: str = "",
resolution: str = "720p",
thinking_level: str = "default",
seed: int = -1,
poll_interval_sec: float = 2.0,
timeout_sec: int = 900,
) -> Tuple[str, str]:
prompt = (prompt or "").strip()
if not prompt:
raise RuntimeError("prompt is required")

video = (video or "").strip()
if not video:
raise RuntimeError("video is required")

client = atlas_client.client

payload: Dict[str, Any] = {
"model": "google/gemini-omni-flash/video-edit",
"video": video,
"prompt": prompt,
"resolution": resolution,
"thinking_level": thinking_level,
}

image_list: List[str] = [v.strip() for v in (images or "").splitlines() if v.strip()]
if image_list:
if len(image_list) > 5:
raise RuntimeError("images maxItems is 5")
payload["images"] = image_list

if int(seed) >= 0:
payload["seed"] = int(seed)

prediction_id = client.generate_video(payload)
result = client.poll_prediction(prediction_id, poll_interval_sec=float(poll_interval_sec), timeout_sec=float(timeout_sec))

outputs = (result.get("data") or {}).get("outputs") or []
if not outputs:
raise RuntimeError(f"No outputs returned for prediction {prediction_id}: {result}")

return (outputs[0], prediction_id)
12 changes: 12 additions & 0 deletions src/atlascloud_comfyui/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@
from atlascloud_comfyui.nodes.video.google_gemini_omni_flash_t2v_dev import AtlasGeminiOmniFlashTextToVideoDev
from atlascloud_comfyui.nodes.video.google_gemini_omni_flash_i2v_dev import AtlasGeminiOmniFlashImageToVideoDev
from atlascloud_comfyui.nodes.video.google_gemini_omni_flash_r2v_dev import AtlasGeminiOmniFlashReferenceToVideoDev
from atlascloud_comfyui.nodes.video.google_gemini_omni_flash_t2v import AtlasGeminiOmniFlashTextToVideo
from atlascloud_comfyui.nodes.video.google_gemini_omni_flash_i2v import AtlasGeminiOmniFlashImageToVideo
from atlascloud_comfyui.nodes.video.google_gemini_omni_flash_r2v import AtlasGeminiOmniFlashReferenceToVideo
from atlascloud_comfyui.nodes.video.google_gemini_omni_flash_video_edit import AtlasGeminiOmniFlashVideoEdit
from atlascloud_comfyui.nodes.video.xai_grok_imagine_video_t2v import AtlasGrokImagineVideoTextToVideo
from atlascloud_comfyui.nodes.video.xai_grok_imagine_video_i2v import AtlasGrokImagineVideoImageToVideo
from atlascloud_comfyui.nodes.video.xai_grok_imagine_video_v15_i2v import AtlasGrokImagineVideoV15ImageToVideo
Expand Down Expand Up @@ -565,6 +569,10 @@
"AtlasCloud Gemini Omni Flash Text-to-Video Developer": AtlasGeminiOmniFlashTextToVideoDev,
"AtlasCloud Gemini Omni Flash Image-to-Video Developer": AtlasGeminiOmniFlashImageToVideoDev,
"AtlasCloud Gemini Omni Flash Reference-to-Video Developer": AtlasGeminiOmniFlashReferenceToVideoDev,
"AtlasCloud Gemini Omni Flash Text-to-Video": AtlasGeminiOmniFlashTextToVideo,
"AtlasCloud Gemini Omni Flash Image-to-Video": AtlasGeminiOmniFlashImageToVideo,
"AtlasCloud Gemini Omni Flash Reference-to-Video": AtlasGeminiOmniFlashReferenceToVideo,
"AtlasCloud Gemini Omni Flash Video Edit": AtlasGeminiOmniFlashVideoEdit,
"AtlasCloud VEO3.1 Reference-to-Video": AtlasVeo31ReferenceToVideo,
"AtlasCloud VEO3.1 Image-to-Video": AtlasVeo31ImageToVideo,
"AtlasCloud VEO3 Image-to-Video": AtlasVeo3ImageToVideo,
Expand Down Expand Up @@ -893,6 +901,10 @@
"AtlasCloud Gemini Omni Flash Text-to-Video Developer": "AtlasCloud Gemini Omni Flash Text-to-Video Developer",
"AtlasCloud Gemini Omni Flash Image-to-Video Developer": "AtlasCloud Gemini Omni Flash Image-to-Video Developer",
"AtlasCloud Gemini Omni Flash Reference-to-Video Developer": "AtlasCloud Gemini Omni Flash Reference-to-Video Developer",
"AtlasCloud Gemini Omni Flash Text-to-Video": "AtlasCloud Gemini Omni Flash Text-to-Video",
"AtlasCloud Gemini Omni Flash Image-to-Video": "AtlasCloud Gemini Omni Flash Image-to-Video",
"AtlasCloud Gemini Omni Flash Reference-to-Video": "AtlasCloud Gemini Omni Flash Reference-to-Video",
"AtlasCloud Gemini Omni Flash Video Edit": "AtlasCloud Gemini Omni Flash Video Edit",
"AtlasCloud VEO3.1 Reference-to-Video": "AtlasCloud VEO3.1 Reference-to-Video",
"AtlasCloud VEO3.1 Image-to-Video": "AtlasCloud VEO3.1 Image-to-Video",
"AtlasCloud VEO3 Image-to-Video": "AtlasCloud VEO3 Image-to-Video",
Expand Down
Loading
Loading