Use native node help documentation

This commit is contained in:
Jedrzej Kosinski
2026-07-17 17:49:55 -07:00
parent 2dc014a33e
commit d0db79787d
12 changed files with 235 additions and 176 deletions
+3 -3
View File
@@ -4,14 +4,14 @@ from .animatediff.utils_model import get_available_motion_models, Folders
from .animatediff.model_injection import prepare_dinklink_register_definitions
from .animatediff.motion_module_ad import prepare_dinklink_motion_module_ad
from .animatediff.nodes import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
from .animatediff import documentation
from .animatediff.dinklink import init_dinklink
if len(get_available_motion_models()) == 0:
logger.error(f"No motion models found. Please download one and place in: {folder_paths.get_folder_paths(Folders.ANIMATEDIFF_MODELS)}")
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
documentation.format_descriptions(NODE_CLASS_MAPPINGS)
WEB_DIRECTORY = "./web"
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
init_dinklink()
prepare_dinklink_register_definitions()
-51
View File
@@ -1,51 +0,0 @@
from typing import Union
def short_desc(desc):
return str(desc)
def coll(text: str):
return text
descriptions = {}
def as_markdown(entry, depth=0):
if isinstance(entry, dict):
sections = []
for name, value in entry.items():
if name == "collapsed":
continue
heading = "#" * min(depth + 2, 6)
rendered = as_markdown(value, depth=depth + 1)
sections.append(f"{heading} {name}\n\n{rendered}" if rendered else f"{heading} {name}")
return "\n\n".join(sections)
if isinstance(entry, list):
return "\n\n".join(as_markdown(item, depth=depth) for item in entry)
return str(entry)
def register_description(node_id: str, desc: Union[list, dict]):
descriptions[node_id] = desc
def format_descriptions(nodes):
for node_id, description in descriptions.items():
nodes[node_id].DESCRIPTION = as_markdown(description)
class DocHelper:
def __init__(self):
self.actual_dict = {}
def add(self, add_dict):
self.actual_dict.update(add_dict)
return self
def get(self):
return self.actual_dict
@staticmethod
def combine(*args):
docs = DocHelper()
for doc in args:
docs.add(doc)
return docs.get()
+2 -23
View File
@@ -1,7 +1,6 @@
from typing import Union
from torch import Tensor
from .documentation import short_desc, register_description, coll, DocHelper
from .motion_module_ad import BlockType
from .utils_model import ModelTypeSD
from .utils_motion import AllPerBlocks, PerBlock, PerBlockId, extend_list_to_batch_size
@@ -281,17 +280,7 @@ class PerBlock_SD15_FromFloatsNode:
RETURN_TYPES = ("PER_BLOCK",)
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
FUNCTION = "create_per_block"
Desc = [
short_desc('Use Floats from Value Schedules to select SD1.5 effect/scale values for blocks.'),
'SD1.5 Motion Modules contain 21 blocks:',
'idx 0 - start of down blocks (down_0__0)',
'idx 7 - end of down blocks (down_3__1)',
'idx 8 - mid block (mid)',
'idx 9 - start of up blocks (up_0__0)',
'idx 20 - end of up blocks (up_3__2)',
]
register_description(NodeID, Desc)
DESCRIPTION = 'Use Floats from Value Schedules to select SD1.5 effect/scale values for blocks.'
def create_per_block(self,
effect_21_floats: Union[list[float], None]=None,
@@ -454,17 +443,7 @@ class PerBlock_SDXL_FromFloatsNode:
RETURN_TYPES = ("PER_BLOCK",)
CATEGORY = "Animate Diff 🎭🅐🅓/per block"
FUNCTION = "create_per_block"
Desc = [
short_desc('Use Floats from Value Schedules to select SDXL effect/scale values for blocks.'),
'SDXL Motion Modules contain 16 blocks:',
'idx 0 - start of down blocks (down_0__0)',
'idx 5 - end of down blocks (down_2__1)',
'idx 6 - mid block (mid)',
'idx 7 - start of up blocks (up_0__0)',
'idx 15 - end of up blocks (up_2__2)',
]
register_description(NodeID, Desc)
DESCRIPTION = 'Use Floats from Value Schedules to select SDXL effect/scale values for blocks.'
def create_per_block(self,
effect_16_floats: Union[list[float], None]=None,
+6 -99
View File
@@ -1,66 +1,10 @@
from typing import Union
from .documentation import register_description, short_desc, coll, DocHelper
from .scheduling import (evaluate_prompt_schedule, evaluate_value_schedule, extract_cond_from_schedule, TensorInterp, PromptOptions,
verify_key_value)
from .utils_model import BIGMAX
from .logger import logger
desc_values = {coll('values'): 'Write your values here.'}
desc_prompts = {coll('prompts'): 'Write your prompts here.'}
desc_clip = {'clip': 'CLIP to use for encoding prompts.'}
desc_latent = {'latent': 'Used to get the amount of frames (max_length) to use for scheduling.'}
desc_prepend_text = {'prepend_text': 'OPTIONAL, adds text before all prompts.'}
desc_append_text = {'append_text': 'OPTIONAL, adds text after all prompts.'}
desc_values_replace = {'values_replace': 'OPTIONAL, replaces keys from value_replace keys with provided value schedules. Keys in the prompt are written as `some_key`, surrounded by the ` characters.'}
desc_tensor_interp = {'tensor_interp': 'Selects method of interpolating prompt conds - defaults to lerp.'}
desc_print_schedule = {'print_schedule': 'When True, prints output values for each frame.'}
desc_max_length = {'max_length': 'Used to select the intended length of schedule. If set to 0, will use the largest index in the schedule as max_length, but will disable relative indexes (negative and decimal).'}
desc_floats = {'floats': 'List of floats, likely outputted by a Value Scheduling node.'}
desc_FLOAT = {'FLOAT': 'Float (or list of floats) to convert to FLOATS type.'}
desc_value_key = {'value_key': 'Key to use for value schedule in Prompt Scheduling node. Can only contain a-z, A-Z, 0-9, and _ characters. In Prompt Scheduling, keys can be referred to as `some_key`, where the key is surrounded by ` characters.'}
desc_prev_replace = {'prev_replace': 'OPTIONAL, other values_replace can be chained.'}
desc_input_conditioning = {'conditioning': 'Encoded prompts. The output of a Prompt Scheduling node.'}
desc_index = {'index': 'The index to extract. Must be within the range [0,N] where N is the length of scheduled prompts.'}
desc_output_conditioning_single = {'CONDITIONING': 'The single step conditioning from the schedule.'}
desc_output_conditioning = {'CONDITIONING': 'Encoded prompts.'}
desc_output_latent = {'LATENT': 'Unmodified input latents; can be used as pipe, or can be ignored.'}
desc_format_allowed_idxs = {'allowed idxs':
{'single': 'A positive integer (e.g. 0, 2) schedules value for frame. A negative integer (e.g. -1, -5) schedules value for frame from the end (-1 would be the last frame). ' +
'A decimal (e.g. 0.5, 1.0) selects frame based relative location in whole schedule (0.5 would be halfway, 1.0 would be last frame).',
'range': 'Using rules above, single:single chooses uninterpolated prompts from start idx (included) to end idx (excluded). Examples -> 0:12, 0:-5, 2:0.5',
'hold': 'Putting a colon after a single idx stops interpolation until the next provided index. Examples -> 0:, 0.5:, 16: '}
}
desc_format_prompt = [
'Scheduling supports two formats: JSON and pythonic.',
{'JSON': ['"idx": "your prompt here", ...'],
'pythonic': ['idx = "your prompt here", ...']},
'The idx is the index of the frame - first frame is 0, last frame is max_frames-1. An idx may be the following:',
desc_format_allowed_idxs,
'The prompts themselves should be surrounded by double quotes ("your prompt here"). Portions of prompts can use value schedules provided values_replace.',
{'JSON': ['"0": "blue rock on mountain",', '"16": "green rock in lake"'],
'pythonic': ['0 = "blue rock on mountain",', '16 = "green rock in lake"']}
]
desc_format_values = [
'Scheduling supports two formats: JSON and pythonic.',
{'JSON': ['"idx": float/int_value, ...'],
'pythonic': ['idx = float/int_value, ...']},
'The idx is the index of the frame - first frame is 0, last frame is max_frames-1. An idx may be the following:',
desc_format_allowed_idxs,
'The values can be written without any special formatting.',
{'JSON': ['"0": 1.0,', '"16": 1.3'],
'pythonic': ['0 = 1.0,', '16 = 1.3']}
]
class PromptSchedulingLatentsNode:
NodeID = 'ADE_PromptSchedulingLatents'
NodeName = 'Prompt Scheduling [Latents] 🎭🅐🅓'
@@ -84,14 +28,7 @@ class PromptSchedulingLatentsNode:
RETURN_TYPES = ("CONDITIONING", "LATENT",)
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
FUNCTION = "create_schedule"
Desc = [
short_desc('Encode a schedule of prompts with automatic interpolation, its length matching passed-in latent count.'),
{'Format': desc_format_prompt},
{coll('Inputs'): DocHelper.combine(desc_prompts, desc_clip, desc_latent, desc_values_replace, desc_prepend_text, desc_append_text, desc_tensor_interp, desc_print_schedule)},
{coll('Outputs'): DocHelper.combine(desc_output_conditioning, desc_output_latent)}
]
register_description(NodeID, Desc)
DESCRIPTION = 'Encode a schedule of prompts with automatic interpolation, its length matching passed-in latent count.'
def create_schedule(self, prompts: str, clip, latent: dict, print_schedule=False, tensor_interp=TensorInterp.LERP,
prepend_text='', append_text='', values_replace=None):
@@ -124,14 +61,7 @@ class PromptSchedulingNode:
RETURN_TYPES = ("CONDITIONING",)
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
FUNCTION = "create_schedule"
Desc = [
short_desc('Encode a schedule of prompts with automatic interpolation.'),
{'Format': desc_format_prompt},
{coll('Inputs'): DocHelper.combine(desc_prompts, desc_clip, desc_values_replace, desc_prepend_text, desc_append_text, desc_max_length, desc_tensor_interp, desc_print_schedule)},
{coll('Outputs'): DocHelper.combine(desc_output_conditioning)}
]
register_description(NodeID, Desc)
DESCRIPTION = 'Encode a schedule of prompts with automatic interpolation.'
def create_schedule(self, prompts: str, clip, print_schedule=False, max_length: int=0, tensor_interp=TensorInterp.LERP,
prepend_text='', append_text='', values_replace=None):
@@ -159,13 +89,7 @@ class ValueSchedulingLatentsNode:
RETURN_TYPES = ("FLOAT", "FLOATS", "INT", "INTS")
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
FUNCTION = "create_schedule"
Desc = [
short_desc('Create a list of values with automatic interpolation, its length matching passed-in latent count.'),
{'Format': desc_format_values},
{coll('Inputs'): DocHelper.combine(desc_values, desc_latent, desc_print_schedule)},
]
register_description(NodeID, Desc)
DESCRIPTION = 'Create a list of values with automatic interpolation, its length matching passed-in latent count.'
def create_schedule(self, values: str, latent: dict, print_schedule=False):
float_vals = evaluate_value_schedule(values, latent["samples"].size(0))
@@ -195,13 +119,7 @@ class ValueSchedulingNode:
RETURN_TYPES = ("FLOAT", "FLOATS", "INT", "INTS")
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
FUNCTION = "create_schedule"
Desc = [
short_desc('Create a list of values with automatic interpolation.'),
{'Format': desc_format_values},
{coll('Inputs'): DocHelper.combine(desc_values, desc_max_length, desc_print_schedule)},
]
register_description(NodeID, Desc)
DESCRIPTION = 'Create a list of values with automatic interpolation.'
def create_schedule(self, values: str, max_length: int, print_schedule=False):
float_vals = evaluate_value_schedule(values, max_length)
@@ -231,12 +149,7 @@ class AddValuesReplaceNode:
RETURN_TYPES = ("VALUES_REPLACE",)
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
FUNCTION = "add_values_replace"
Desc = [
short_desc('Add a values schedule bound to a key to be used in Prompt Scheduling node.'),
{'Inputs': DocHelper.combine(desc_value_key, desc_floats, desc_prev_replace)},
]
register_description(NodeID, Desc)
DESCRIPTION = 'Add a values schedule bound to a key to be used in Prompt Scheduling node.'
def add_values_replace(self, value_key: str, floats: Union[list[float]], prev_replace: dict=None):
# key can only have a-z, A-Z, 0-9, and _ characters
@@ -289,13 +202,7 @@ class ConditionExtractionNode:
RETURN_TYPES = ("CONDITIONING",)
CATEGORY = "Animate Diff 🎭🅐🅓/scheduling"
FUNCTION = "extract_conditioning"
Desc = [
short_desc('Extract a single conditioning step from a schedule of prompts.'),
{coll('Inputs'): DocHelper.combine(desc_input_conditioning, desc_index)},
{coll('Outputs'): DocHelper.combine(desc_output_conditioning)}
]
register_description(NodeID, Desc)
DESCRIPTION = 'Extract a single conditioning step from a schedule of prompts.'
def extract_conditioning(self, conditioning, index: int=0):
conditioning_step = extract_cond_from_schedule(conditioning, index)
+12
View File
@@ -0,0 +1,12 @@
# Condition Step Extraction
Extract a single conditioning step from a schedule of prompts.
## Inputs
- `conditioning`: Encoded prompts from a Prompt Scheduling node.
- `index`: The step to extract. It must be within the scheduled prompt range.
## Outputs
- `CONDITIONING`: The single conditioning step from the schedule.
+24
View File
@@ -0,0 +1,24 @@
# AD Per Block Floats (SD1.5)
Use Floats from Value Schedules to select SD1.5 effect and scale values for blocks.
## Inputs
- `effect_21_floats`: Optional effect values. The list is extended to the required 21 values when needed.
- `scale_21_floats`: Optional scale values. The list is extended to the required 21 values when needed.
## Block index map
SD1.5 motion modules contain 21 blocks.
| Index | Block |
| ---: | --- |
| 0 | Start of down blocks (`down_0__0`) |
| 7 | End of down blocks (`down_3__1`) |
| 8 | Mid block (`mid`) |
| 9 | Start of up blocks (`up_0__0`) |
| 20 | End of up blocks (`up_3__2`) |
## Outputs
- `PER_BLOCK`: Per-block effect and scale configuration for an SD1.5 motion module.
+24
View File
@@ -0,0 +1,24 @@
# AD Per Block Floats (SDXL)
Use Floats from Value Schedules to select SDXL effect and scale values for blocks.
## Inputs
- `effect_16_floats`: Optional effect values. The list is extended to the required 16 values when needed.
- `scale_16_floats`: Optional scale values. The list is extended to the required 16 values when needed.
## Block index map
SDXL motion modules contain 16 blocks.
| Index | Block |
| ---: | --- |
| 0 | Start of down blocks (`down_0__0`) |
| 5 | End of down blocks (`down_2__1`) |
| 6 | Mid block (`mid`) |
| 7 | Start of up blocks (`up_0__0`) |
| 15 | End of up blocks (`up_2__2`) |
## Outputs
- `PER_BLOCK`: Per-block effect and scale configuration for an SDXL motion module.
+42
View File
@@ -0,0 +1,42 @@
# Prompt Scheduling
Encode a schedule of prompts with automatic interpolation.
## Schedule format
Schedules support JSON and Python-like formats. Frame 0 is the first frame and `max_frames - 1` is the last.
```text
"0": "blue rock on mountain",
"16": "green rock in lake"
```
```text
0 = "blue rock on mountain",
16 = "green rock in lake"
```
Prompts must be enclosed in double quotes. Prompt portions may use keys supplied through `values_replace`.
### Allowed indices
- **Single:** A positive integer such as `0` or `2` selects that frame. A negative integer such as `-1` or `-5` selects from the end (`-1` is the last frame). A decimal such as `0.5` or `1.0` selects a relative position (`0.5` is halfway and `1.0` is the last frame).
- **Range:** `start:end` uses an uninterpolated prompt from the included start index to the excluded end index. Examples: `0:12`, `0:-5`, `2:0.5`.
- **Hold:** A colon after one index stops interpolation until the next supplied index. Examples: `0:`, `0.5:`, `16:`.
## Inputs
| Input | Description |
| --- | --- |
| `prompts` | The prompt schedule. |
| `clip` | CLIP used to encode prompts. |
| `prepend_text` | Optional text added before every prompt. |
| `append_text` | Optional text added after every prompt. |
| `values_replace` | Optional value schedules substituted for keys written as `` `some_key` `` in prompts. |
| `print_schedule` | Print the resulting schedule when enabled. |
| `max_length` | Intended schedule length. At 0, the largest schedule index determines the length, but negative and decimal relative indices are disabled. |
| `tensor_interp` | Prompt-conditioning interpolation method; defaults to linear interpolation. |
## Outputs
- `CONDITIONING`: Encoded prompts.
+43
View File
@@ -0,0 +1,43 @@
# Prompt Scheduling [Latents]
Encode a schedule of prompts with automatic interpolation, its length matching the passed-in latent count.
## Schedule format
Schedules support JSON and Python-like formats. Frame 0 is the first frame and `max_frames - 1` is the last.
```text
"0": "blue rock on mountain",
"16": "green rock in lake"
```
```text
0 = "blue rock on mountain",
16 = "green rock in lake"
```
Prompts must be enclosed in double quotes. Prompt portions may use keys supplied through `values_replace`.
### Allowed indices
- **Single:** A positive integer such as `0` or `2` selects that frame. A negative integer such as `-1` or `-5` selects from the end (`-1` is the last frame). A decimal such as `0.5` or `1.0` selects a relative position (`0.5` is halfway and `1.0` is the last frame).
- **Range:** `start:end` uses an uninterpolated prompt from the included start index to the excluded end index. Examples: `0:12`, `0:-5`, `2:0.5`.
- **Hold:** A colon after one index stops interpolation until the next supplied index. Examples: `0:`, `0.5:`, `16:`.
## Inputs
| Input | Description |
| --- | --- |
| `prompts` | The prompt schedule. |
| `clip` | CLIP used to encode prompts. |
| `latent` | Supplies the frame count used as the schedule length. |
| `prepend_text` | Optional text added before every prompt. |
| `append_text` | Optional text added after every prompt. |
| `values_replace` | Optional value schedules substituted for keys written as `` `some_key` `` in prompts. |
| `tensor_interp` | Prompt-conditioning interpolation method; defaults to linear interpolation. |
| `print_schedule` | Print the resulting schedule when enabled. |
## Outputs
- `CONDITIONING`: Encoded prompts.
- `LATENT`: The unmodified input latents, usable as a pipe or safely ignored.
+33
View File
@@ -0,0 +1,33 @@
# Value Scheduling
Create a list of values with automatic interpolation.
## Schedule format
Schedules support JSON and Python-like formats. Values need no special formatting.
```text
"0": 1.0,
"16": 1.3
```
```text
0 = 1.0,
16 = 1.3
```
Frame 0 is the first frame and `max_frames - 1` is the last.
- **Single:** Positive integers select a frame, negative integers select from the end (`-1` is last), and decimals select a relative position (`0.5` is halfway and `1.0` is last).
- **Range:** `start:end` holds the start value without interpolation through the excluded end. Examples: `0:12`, `0:-5`, `2:0.5`.
- **Hold:** A trailing colon stops interpolation until the next index. Examples: `0:`, `0.5:`, `16:`.
## Inputs
- `values`: The value schedule.
- `max_length`: Intended schedule length. At 0, the largest schedule index determines the length, but negative and decimal relative indices are disabled.
- `print_schedule`: Print each output value when enabled.
## Outputs
The schedule is returned as `FLOAT`, `FLOATS`, rounded `INT`, and rounded `INTS` outputs.
+33
View File
@@ -0,0 +1,33 @@
# Value Scheduling [Latents]
Create a list of values with automatic interpolation, its length matching the passed-in latent count.
## Schedule format
Schedules support JSON and Python-like formats. Values need no special formatting.
```text
"0": 1.0,
"16": 1.3
```
```text
0 = 1.0,
16 = 1.3
```
Frame 0 is the first frame and `max_frames - 1` is the last.
- **Single:** Positive integers select a frame, negative integers select from the end (`-1` is last), and decimals select a relative position (`0.5` is halfway and `1.0` is last).
- **Range:** `start:end` holds the start value without interpolation through the excluded end. Examples: `0:12`, `0:-5`, `2:0.5`.
- **Hold:** A trailing colon stops interpolation until the next index. Examples: `0:`, `0.5:`, `16:`.
## Inputs
- `values`: The value schedule.
- `latent`: Supplies the frame count used as the schedule length.
- `print_schedule`: Print each output value when enabled.
## Outputs
The schedule is returned as `FLOAT`, `FLOATS`, rounded `INT`, and rounded `INTS` outputs.
+13
View File
@@ -0,0 +1,13 @@
# Add Values Replace
Add a value schedule bound to a key for use in a Prompt Scheduling node.
## Inputs
- `value_key`: The key for the value schedule. It may contain only `a-z`, `A-Z`, `0-9`, and `_`. Refer to it in a prompt by surrounding it with backticks, for example `` `some_key` ``.
- `floats`: A list of floats, typically produced by a Value Scheduling node.
- `prev_replace`: Optional existing replacements, allowing multiple Values Replace nodes to be chained.
## Outputs
- `VALUES_REPLACE`: The replacement mapping for a Prompt Scheduling node.