Fix: Prompt text can't be validated in Kling nodes when using primitive nodes (#90)

This commit is contained in:
Christian Byrne 2025-04-30 21:48:07 -07:00 committed by Jedrzej Kosinski
parent 90025b4dfe
commit fbb1d16bda

View File

@ -1,15 +1,4 @@
""" from typing import Optional
`camera_control` supported:
- pro | 5s duration | kling-v1-5
`camera_control` not supported:
- std | 10s duration | kling-v1-6
"""
from typing import Union, Optional
import math import math
import logging import logging
import torch import torch
@ -39,9 +28,9 @@ from comfy_api_nodes.apinode_utils import (
tensor_to_base64_string, tensor_to_base64_string,
download_url_to_video_output, download_url_to_video_output,
) )
from comfy_api_nodes.mapper_utils import model_field_to_node_input
from comfy.comfy_types.node_typing import IO, InputTypeOptions, ComfyNodeABC from comfy.comfy_types.node_typing import IO, InputTypeOptions, ComfyNodeABC
from comfy_api.input_impl import VideoFromFile from comfy_api.input_impl import VideoFromFile
from comfy_api_nodes.mapper_utils import model_field_to_node_input
KLING_API_VERSION = "v1" KLING_API_VERSION = "v1"
PATH_TEXT_TO_VIDEO = f"/proxy/kling/{KLING_API_VERSION}/videos/text2video" PATH_TEXT_TO_VIDEO = f"/proxy/kling/{KLING_API_VERSION}/videos/text2video"
@ -52,6 +41,9 @@ PATH_VIDEO_EFFECTS = f"/proxy/kling/{KLING_API_VERSION}/videos/effects"
PATH_CHARACTER_IMAGE = f"/proxy/kling/{KLING_API_VERSION}/images/generations" PATH_CHARACTER_IMAGE = f"/proxy/kling/{KLING_API_VERSION}/images/generations"
PATH_VIRTUAL_TRY_ON = f"/proxy/kling/{KLING_API_VERSION}/images/kolors-virtual-try-on" PATH_VIRTUAL_TRY_ON = f"/proxy/kling/{KLING_API_VERSION}/images/kolors-virtual-try-on"
MAX_PROMPT_LENGTH_T2V = 2500
MAX_PROMPT_LENGTH_I2V = 500
class KlingApiError(Exception): class KlingApiError(Exception):
"""Base exception for Kling API errors.""" """Base exception for Kling API errors."""
@ -83,6 +75,19 @@ def is_valid_video_response(response: KlingText2VideoResponse) -> bool:
) )
def validate_prompts(prompt: str, negative_prompt: str, max_length: int) -> bool:
"""Verifies that the positive prompt is not empty and that neither promt is too long."""
if not prompt:
raise ValueError("Positive prompt is empty")
if len(prompt) > max_length:
raise ValueError(f"Positive prompt is too long: {len(prompt)} characters")
if negative_prompt and len(negative_prompt) > max_length:
raise ValueError(
f"Negative prompt is too long: {len(negative_prompt)} characters"
)
return True
def get_camera_control_input_config( def get_camera_control_input_config(
tooltip: str, default: float = 0.0 tooltip: str, default: float = 0.0
) -> tuple[IO, InputTypeOptions]: ) -> tuple[IO, InputTypeOptions]:
@ -183,20 +188,6 @@ class KlingCameraControls(ComfyNodeABC):
class KlingNodeBase(ComfyNodeABC): class KlingNodeBase(ComfyNodeABC):
"""Base class for Kling nodes.""" """Base class for Kling nodes."""
@classmethod
def VALIDATE_INPUTS(
cls,
prompt,
negative_prompt,
) -> Union[str, bool]:
if not is_valid_prompt(prompt):
return "Prompt is required"
if len(prompt) >= 2500:
return "Prompt must be less than 2500 characters"
if negative_prompt and len(negative_prompt) >= 2500:
return "Negative prompt must be less than 2500 characters"
return True
FUNCTION = "api_call" FUNCTION = "api_call"
CATEGORY = "api node/video/Kling" CATEGORY = "api node/video/Kling"
API_NODE = True API_NODE = True
@ -284,6 +275,7 @@ class KlingTextToVideoNode(KlingNodeBase):
camera_control: Optional[CameraControl] = None, camera_control: Optional[CameraControl] = None,
auth_token: Optional[str] = None, auth_token: Optional[str] = None,
) -> tuple[VideoFromFile]: ) -> tuple[VideoFromFile]:
validate_prompts(prompt, negative_prompt, MAX_PROMPT_LENGTH_T2V)
initial_operation = SynchronousOperation( initial_operation = SynchronousOperation(
endpoint=ApiEndpoint( endpoint=ApiEndpoint(
path=PATH_TEXT_TO_VIDEO, path=PATH_TEXT_TO_VIDEO,
@ -416,6 +408,7 @@ class KlingImage2VideoNode(KlingNodeBase):
end_frame: Optional[torch.Tensor] = None, end_frame: Optional[torch.Tensor] = None,
auth_token: Optional[str] = None, auth_token: Optional[str] = None,
) -> tuple[VideoFromFile]: ) -> tuple[VideoFromFile]:
validate_prompts(prompt, negative_prompt, MAX_PROMPT_LENGTH_I2V)
initial_operation = SynchronousOperation( initial_operation = SynchronousOperation(
endpoint=ApiEndpoint( endpoint=ApiEndpoint(
path=PATH_IMAGE_TO_VIDEO, path=PATH_IMAGE_TO_VIDEO,